resolve: apply stashed using/module + deps bridge; remove conflict markers in runner/mod.rs
This commit is contained in:
154
apps/selfhost/tools/dep_tree_min_string.nyash
Normal file
154
apps/selfhost/tools/dep_tree_min_string.nyash
Normal file
@ -0,0 +1,154 @@
|
||||
// dep_tree_min_string.nyash — minimal include-only dependency tree (no Array/Map plugins)
|
||||
|
||||
static box Main {
|
||||
has_in_stack(stack, p) {
|
||||
// check if stack contains "\n" + p + "\n"
|
||||
local t = "\n" + p + "\n"
|
||||
local n = stack.length()
|
||||
local m = t.length()
|
||||
if m == 0 { return 0 }
|
||||
local i = 0
|
||||
loop(i + m <= n) {
|
||||
if stack.substring(i, i+m) == t { return 1 }
|
||||
i = i + 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
read_all(path) {
|
||||
local fb = new FileBox()
|
||||
local ok = fb.open(path, "r")
|
||||
if ok == false { return null }
|
||||
local s = fb.read()
|
||||
fb.close()
|
||||
return s
|
||||
}
|
||||
|
||||
dirname(path) {
|
||||
local pb = new PathBox()
|
||||
local d = pb.dirname(path)
|
||||
if d != null { return d }
|
||||
local i = path.lastIndexOf("/")
|
||||
if i < 0 { return "." }
|
||||
return path.substring(0, i)
|
||||
}
|
||||
|
||||
join(base, rel) {
|
||||
local pb = new PathBox()
|
||||
local j = pb.join(base, rel)
|
||||
if j != null { return j }
|
||||
return base + "/" + rel
|
||||
}
|
||||
|
||||
esc_json(s) {
|
||||
// very small escaper: replace \ and "
|
||||
local out = ""
|
||||
local i = 0
|
||||
local n = s.length()
|
||||
loop(i < n) {
|
||||
local ch = s.substring(i, i+1)
|
||||
if ch == "\\" { out = out + "\\\\" } else {
|
||||
if ch == "\"" { out = out + "\\\"" } else { out = out + ch }
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
node_json(path, stack, depth) {
|
||||
// safety valve: max depth
|
||||
if depth >= 64 {
|
||||
return "{\\\"path\\\":\\\"" + me.esc_json(path) + "\\\",\\\"includes\\\":[],\\\"children\\\":[]}"
|
||||
}
|
||||
local src = me.read_all(path)
|
||||
if src == null {
|
||||
return "{\\\"path\\\":\\\"" + me.esc_json(path) + "\\\",\\\"includes\\\":[],\\\"children\\\":[]}"
|
||||
}
|
||||
local base = me.dirname(path)
|
||||
local incs = ""
|
||||
local inc_first = 1
|
||||
local children = ""
|
||||
local child_first = 1
|
||||
local i = 0
|
||||
local n = src.length()
|
||||
local in_str = 0
|
||||
local in_cmt = 0
|
||||
loop(i < n) {
|
||||
local ch = src.substring(i, i+1)
|
||||
// handle line comments (// or #)
|
||||
if in_cmt == 1 {
|
||||
if ch == "\n" { in_cmt = 0 }
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
if in_str == 1 {
|
||||
if ch == "\"" {
|
||||
// if previous is not backslash, close
|
||||
if i == 0 { in_str = 0 } else {
|
||||
local prev = src.substring(i-1, i)
|
||||
if prev != "\\" { in_str = 0 }
|
||||
}
|
||||
}
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
// not in string/comment
|
||||
if ch == "/" && i + 1 < n && src.substring(i+1, i+2) == "/" { in_cmt = 1; i = i + 2; continue }
|
||||
if ch == "#" { in_cmt = 1; i = i + 1; continue }
|
||||
if ch == "\"" { in_str = 1; i = i + 1; continue }
|
||||
// look for include "
|
||||
if i + 9 <= n && src.substring(i, i+9) == "include \"" {
|
||||
local j = i + 9
|
||||
// find closing quote (respect escapes)
|
||||
loop(j < n) {
|
||||
if src.substring(j, j+1) == "\"" {
|
||||
local prev = src.substring(j-1, j)
|
||||
if prev != "\\" { break }
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
if j < n {
|
||||
local p = src.substring(i+9, j)
|
||||
if inc_first == 1 {
|
||||
incs = incs + "\"" + me.esc_json(p) + "\""
|
||||
inc_first = 0
|
||||
} else {
|
||||
incs = incs + ",\"" + me.esc_json(p) + "\""
|
||||
}
|
||||
local child_path = me.join(base, p)
|
||||
// cycle detection: if child_path already in stack, do not recurse
|
||||
local cj = null
|
||||
if me.has_in_stack(stack, child_path) == 1 {
|
||||
cj = "{\\\"path\\\":\\\"" + me.esc_json(child_path) + "\\\",\\\"includes\\\":[],\\\"children\\\":[]}"
|
||||
} else {
|
||||
cj = me.node_json(child_path, stack + child_path + "\n", depth + 1)
|
||||
}
|
||||
if child_first == 1 {
|
||||
children = children + cj
|
||||
child_first = 0
|
||||
} else {
|
||||
children = children + "," + cj
|
||||
}
|
||||
i = j + 1
|
||||
continue
|
||||
}
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return "{\\\"path\\\":\\\"" + me.esc_json(path) + "\\\",\\\"includes\\\":[" + incs + "],\\\"children\\\":[" + children + "]}"
|
||||
}
|
||||
|
||||
main(args) {
|
||||
local console = new ConsoleBox()
|
||||
local entry = null
|
||||
if args != null && args.length() >= 1 { entry = args.get(0) }
|
||||
if entry == null || entry == "" {
|
||||
// try stdin first line
|
||||
local line = console.readLine()
|
||||
if line != null && line != "" { entry = line } else { entry = "apps/selfhost/ny-parser-nyash/main.nyash" }
|
||||
}
|
||||
local tree = me.node_json(entry, "\n" + entry + "\n", 0)
|
||||
local out = "{\\\"version\\\":1,\\\"root_path\\\":\\\"" + me.esc_json(entry) + "\\\",\\\"tree\\\":" + tree + "}"
|
||||
console.println(out)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@ -37,26 +37,35 @@ static box Main {
|
||||
|
||||
// ---- text utils ----
|
||||
split_lines(src) {
|
||||
// return { arr, len }
|
||||
local pair = new MapBox()
|
||||
local out = new ArrayBox()
|
||||
local len = 0
|
||||
local i = 0
|
||||
local n = src.length()
|
||||
local start = 0
|
||||
loop(true) {
|
||||
if i == n { out.push(src.substring(start, i)) return out }
|
||||
if i == n { out.push(src.substring(start, i)) len = len + 1 pair.set("arr", out) pair.set("len", len) return pair }
|
||||
local ch = src.substring(i, i+1)
|
||||
if ch == "\n" { out.push(src.substring(start, i)) start = i + 1 }
|
||||
if ch == "\n" { out.push(src.substring(start, i)) len = len + 1 start = i + 1 }
|
||||
i = i + 1
|
||||
}
|
||||
return out
|
||||
pair.set("arr", out)
|
||||
pair.set("len", len)
|
||||
return pair
|
||||
}
|
||||
|
||||
// ---- scanners ----
|
||||
scan_includes(src) {
|
||||
local pair = new MapBox()
|
||||
local out = new ArrayBox()
|
||||
if src == null { return out }
|
||||
local lines = me.split_lines(src)
|
||||
local out_len = 0
|
||||
if src == null { pair.set("arr", out) pair.set("len", out_len) return pair }
|
||||
local lp = me.split_lines(src)
|
||||
local lines = lp.get("arr")
|
||||
local lines_len = lp.get("len")
|
||||
local i = 0
|
||||
loop(i < lines.length()) {
|
||||
loop(i < lines_len) {
|
||||
local t = lines.get(i).trim()
|
||||
if t.startsWith("include \"") {
|
||||
local rest = t.substring(9, t.length())
|
||||
@ -66,19 +75,26 @@ static box Main {
|
||||
if rest.substring(j, j+1) == "\"" { q = j j = rest.length() }
|
||||
j = j + 1
|
||||
}
|
||||
if q >= 0 { out.push(rest.substring(0, q)) }
|
||||
if q >= 0 { out.push(rest.substring(0, q)) out_len = out_len + 1 }
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return out
|
||||
pair.set("arr", out)
|
||||
pair.set("len", out_len)
|
||||
return pair
|
||||
}
|
||||
|
||||
scan_usings(src) {
|
||||
// return { arr, len }
|
||||
local pair = new MapBox()
|
||||
local out = new ArrayBox()
|
||||
if src == null { return out }
|
||||
local lines = me.split_lines(src)
|
||||
local out_len = 0
|
||||
if src == null { pair.set("arr", out) pair.set("len", out_len) return pair }
|
||||
local lp = me.split_lines(src)
|
||||
local lines = lp.get("arr")
|
||||
local lines_len = lp.get("len")
|
||||
local i = 0
|
||||
loop(i < lines.length()) {
|
||||
loop(i < lines_len) {
|
||||
local t0 = lines.get(i).trim()
|
||||
local matched = false
|
||||
local t = t0
|
||||
@ -95,18 +111,26 @@ static box Main {
|
||||
if alias != null { rec.set("alias", alias) }
|
||||
if target.startsWith("./") || target.startsWith("/") || target.endsWith(".nyash") { rec.set("kind", "path") } else { rec.set("kind", "namespace") }
|
||||
out.push(rec)
|
||||
out_len = out_len + 1
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return out
|
||||
pair.set("arr", out)
|
||||
pair.set("len", out_len)
|
||||
return pair
|
||||
}
|
||||
|
||||
scan_modules(src) {
|
||||
// return { arr, len }
|
||||
local pair = new MapBox()
|
||||
local out = new ArrayBox()
|
||||
if src == null { return out }
|
||||
local lines = me.split_lines(src)
|
||||
local out_len = 0
|
||||
if src == null { pair.set("arr", out) pair.set("len", out_len) return pair }
|
||||
local lp = me.split_lines(src)
|
||||
local lines = lp.get("arr")
|
||||
local lines_len = lp.get("len")
|
||||
local i = 0
|
||||
loop(i < lines.length()) {
|
||||
loop(i < lines_len) {
|
||||
local t = lines.get(i).trim()
|
||||
if t.startsWith("// @module ") {
|
||||
local rest = t.substring(11, t.length())
|
||||
@ -118,11 +142,14 @@ static box Main {
|
||||
m.set("namespace", ns)
|
||||
m.set("path", path)
|
||||
out.push(m)
|
||||
out_len = out_len + 1
|
||||
}
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return out
|
||||
pair.set("arr", out)
|
||||
pair.set("len", out_len)
|
||||
return pair
|
||||
}
|
||||
|
||||
default_using_paths() {
|
||||
@ -139,8 +166,9 @@ static box Main {
|
||||
local cand0 = me.join(base_dir, rel)
|
||||
if me.file_exists(cand0) { return cand0 }
|
||||
local paths = me.default_using_paths()
|
||||
local paths_len = 4
|
||||
local i = 0
|
||||
loop(i < paths.length()) {
|
||||
loop(i < paths_len) {
|
||||
local cand = me.join(paths.get(i), rel)
|
||||
if me.file_exists(cand) { return cand }
|
||||
i = i + 1
|
||||
@ -172,28 +200,34 @@ static box Main {
|
||||
return out
|
||||
}
|
||||
local base = me.dirname(path)
|
||||
local incs = me.scan_includes(src)
|
||||
local uses = me.scan_usings(src)
|
||||
local mods = me.scan_modules(src)
|
||||
local incp = me.scan_includes(src)
|
||||
local incs = incp.get("arr")
|
||||
local incs_len = incp.get("len")
|
||||
local usp = me.scan_usings(src)
|
||||
local uses = usp.get("arr")
|
||||
local uses_len = usp.get("len")
|
||||
local modp = me.scan_modules(src)
|
||||
local mods = modp.get("arr")
|
||||
local mods_len = modp.get("len")
|
||||
out.set("includes", incs)
|
||||
out.set("uses", uses)
|
||||
out.set("modules", mods)
|
||||
local mod_map = new MapBox()
|
||||
local mi = 0
|
||||
loop(mi < mods.length()) {
|
||||
loop(mi < mods_len) {
|
||||
local mm = mods.get(mi)
|
||||
mod_map.set(mm.get("namespace"), mm.get("path"))
|
||||
mi = mi + 1
|
||||
}
|
||||
local children = new ArrayBox()
|
||||
local i = 0
|
||||
loop(i < incs.length()) {
|
||||
loop(i < incs_len) {
|
||||
local child_path = me.join(base, incs.get(i))
|
||||
children.push(me.node_for(child_path, visited))
|
||||
i = i + 1
|
||||
}
|
||||
i = 0
|
||||
loop(i < uses.length()) {
|
||||
loop(i < uses_len) {
|
||||
local u = uses.get(i)
|
||||
if u.get("kind") == "path" {
|
||||
local p = me.join(base, u.get("target"))
|
||||
|
||||
Reference in New Issue
Block a user