restore(lang): full lang tree from ff3ef452 (306 files) — compiler, vm, shared, runner, c-abi, etc.\n\n- Restores lang/ directory (files≈306, dirs≈64) as per historical branch with selfhost sources\n- Keeps our recent parser index changes in compiler/* (merged clean by checkout)\n- Unblocks selfhost development and documentation references

This commit is contained in:
nyash-codex
2025-10-31 20:45:46 +09:00
parent dbc285f2b1
commit e5f697eb22
244 changed files with 16915 additions and 47 deletions

View File

@ -168,16 +168,6 @@ static box ParserExprBox {
k = ctx.skip_ws(src, k)
if src.substring(k, k+1) == ")" { k = k + 1 }
node = "{\"type\":\"Method\",\"recv\":" + node + ",\"method\":\"" + mname + "\",\"args\":" + args_json2 + "}"
} else if tch == "[" {
// Index access: node[ index ] → Method(recv=node, method="get", args=[index])
k = k + 1
k = ctx.skip_ws(src, k)
local idx_json = ctx.parse_expr2(src, k)
k = ctx.gpos_get()
k = ctx.skip_ws(src, k)
if src.substring(k, k+1) == "]" { k = k + 1 }
local args_idx = "[" + idx_json + "]"
node = "{\\\"type\\\":\\\"Method\\\",\\\"recv\\\":" + node + ",\\\"method\\\":\\\"get\\\",\\\"args\\\":" + args_idx + "}"
} else {
cont2 = 0
}
@ -362,3 +352,4 @@ static box ParserExprBox {
return out + "@" + ctx.i2s(j)
}
}

View File

@ -14,11 +14,13 @@ using lang.compiler.parser.stmt.parser_control_box
box ParserBox {
gpos
usings_json
externs_json
stage3
birth() {
me.gpos = 0
me.usings_json = "[]"
me.externs_json = "[]"
me.stage3 = 0
return 0
}
@ -152,6 +154,36 @@ box ParserBox {
return me.usings_json
}
// === extern_c annotations ===
add_extern_c(symbol, func) {
// Entry shape: {"symbol":"hako_add","func":"Name/Arity"}
local sym = match symbol { null => "", _ => symbol }
local fn = match func { null => "", _ => func }
local entry = "{\"symbol\":\"" + me.esc_json(sym) + "\",\"func\":\"" + me.esc_json(fn) + "\"}"
local cur = me.externs_json
if cur == null || cur.size() == 0 { cur = "[]" }
if cur == "[]" {
me.externs_json = "[" + entry + "]"
return 0
}
local pos = cur.lastIndexOf("]")
if pos < 0 {
me.externs_json = "[" + entry + "]"
return 0
}
me.externs_json = cur.substring(0, pos) + "," + entry + "]"
return 0
}
extract_externs(_src) {
// MVP: rely on ParserStmtBox to call add_extern_c during parse; here no-op for now.
return 0
}
get_externs_json() {
return me.externs_json
}
// === Delegation to ParserExprBox ===
parse_expr2(src, i) {
local expr = new ParserExprBox()
@ -236,4 +268,3 @@ static box ParserStub {
return 0
}
}

View File

@ -11,45 +11,51 @@ static box ParserStmtBox {
local j = ctx.skip_ws(src, i)
local stmt_start = j
// annotation: @extern_c("c_symbol","Func/Arity");
if ctx.starts_with(src, j, "@extern_c") == 1 {
j = j + 9 // len("@extern_c")
j = ctx.skip_ws(src, j)
if j < src.size() && src.substring(j, j+1) == "(" { j = j + 1 }
j = ctx.skip_ws(src, j)
// First string literal: symbol
local sym = ""
if j < src.size() && src.substring(j, j+1) == "\"" {
sym = ctx.read_string_lit(src, j)
j = ctx.gpos_get()
}
j = ctx.skip_ws(src, j)
if j < src.size() && src.substring(j, j+1) == "," { j = j + 1 }
j = ctx.skip_ws(src, j)
// Second string literal: func
local fn = ""
if j < src.size() && src.substring(j, j+1) == "\"" {
fn = ctx.read_string_lit(src, j)
j = ctx.gpos_get()
}
// Skip to ')' if present
j = ctx.skip_ws(src, j)
if j < src.size() && src.substring(j, j+1) == ")" { j = j + 1 }
// Optional semicolon is consumed by caller; still advance if present
j = ctx.skip_ws(src, j)
if j < src.size() && src.substring(j, j+1) == ";" { j = j + 1 }
ctx.gpos_set(j)
// Record annotation in parser context and emit no statement
ctx.add_extern_c(sym, fn)
return ""
}
// using statement
if ctx.starts_with_kw(src, j, "using") == 1 {
return me.parse_using(src, j, stmt_start, ctx)
}
// assignment: IDENT '[' expr ']' '=' expr or IDENT '=' expr
// assignment: IDENT '=' expr
if j < src.size() && ctx.is_alpha(src.substring(j, j+1)) {
local idp0 = ctx.read_ident2(src, j)
local at0 = idp0.lastIndexOf("@")
if at0 > 0 {
local name0 = idp0.substring(0, at0)
local k0 = ctx.to_int(idp0.substring(at0+1, idp0.size()))
// Case A: index assignment arr[expr] = value
{
local kA = ctx.skip_ws(src, k0)
if kA < src.size() && src.substring(kA, kA+1) == "[" {
kA = kA + 1
kA = ctx.skip_ws(src, kA)
// parse index expression
local idx_json = ctx.parse_expr2(src, kA)
kA = ctx.gpos_get()
kA = ctx.skip_ws(src, kA)
if kA < src.size() && src.substring(kA, kA+1) == "]" { kA = kA + 1 }
kA = ctx.skip_ws(src, kA)
if kA < src.size() && src.substring(kA, kA+1) == "=" {
// parse RHS
kA = kA + 1
kA = ctx.skip_ws(src, kA)
local rhs_json = ctx.parse_expr2(src, kA)
kA = ctx.gpos_get()
// Build Method set(name[idx], rhs) as Expr statement
local recv = "{\\\"type\\\":\\\"Var\\\",\\\"name\\\":\"" + name0 + "\"}"
local args = "[" + idx_json + "," + rhs_json + "]"
local method = "{\\\"type\\\":\\\"Method\\\",\\\"recv\\\":" + recv + ",\\\"method\\\":\\\"set\\\",\\\"args\\\":" + args + "}"
ctx.gpos_set(kA)
return "{\"type\":\"Expr\",\"expr\":" + method + "}"
}
}
}
k0 = ctx.skip_ws(src, k0)
if k0 < src.size() && src.substring(k0, k0+1) == "=" {
local eq_two = "="