resolve: apply stashed using/module + deps bridge; remove conflict markers in runner/mod.rs

This commit is contained in:
Selfhosting Dev
2025-09-08 04:35:50 +09:00
parent da5fa600d2
commit f22082f67c
18 changed files with 685 additions and 67 deletions

View 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
}
}

View File

@ -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"))