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:
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 = "="
|
||||
|
||||
@ -37,9 +37,12 @@ box ExecutionPipelineBox {
|
||||
if stage3_flag == 1 { p.stage3_enable(1) }
|
||||
p.extract_usings(src)
|
||||
local usings = p.get_usings_json()
|
||||
// Extract extern_c annotations (syntax: @extern_c("c_symbol","Func/Arity");)
|
||||
p.extract_externs(src)
|
||||
local externs = p.get_externs_json()
|
||||
local ast = p.parse_program2(src)
|
||||
// Emit Stage‑1 JSON with meta.usings
|
||||
local json = EmitterBox.emit_program(ast, usings)
|
||||
local json = EmitterBox.emit_program(ast, usings, externs)
|
||||
if json == null || json.size() == 0 { return 1 }
|
||||
print(json)
|
||||
return 0
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// Guard: This box performs no execution. Returns MIR(JSON) as text.
|
||||
|
||||
using "lang/src/compiler/pipeline_v2/pipeline.hako" as PipelineV2
|
||||
using "lang/src/shared/json/mir_v1_adapter.hako" as MirJsonV1Adapter
|
||||
|
||||
static box FlowEntryBox {
|
||||
// Emit legacy v0 JSON(call/boxcall/newbox)。最小入力: Stage‑1 JSON 文字列
|
||||
@ -21,6 +22,18 @@ static box FlowEntryBox {
|
||||
return PipelineV2.lower_stage1_to_mir_v1_compat(ast_json, prefer_cfg)
|
||||
}
|
||||
|
||||
// Emit v1 JSON with metadata.extern_c(externs を v1 の metadata に反映)
|
||||
// externs_json: JSON array text, e.g. [{"func":"Name/Arity","symbol":"c_symbol"}]
|
||||
emit_v1_from_ast_with_meta(ast_json, prefer_cfg, externs_json) {
|
||||
return PipelineV2.lower_stage1_to_mir_v1_with_meta(ast_json, prefer_cfg, externs_json)
|
||||
}
|
||||
|
||||
// Emit v1 JSON + metadata.extern_c を注入し、v0互換に変換
|
||||
emit_v1_compat_from_ast_with_meta(ast_json, prefer_cfg, externs_json) {
|
||||
local j1 = PipelineV2.lower_stage1_to_mir_v1_with_meta(ast_json, prefer_cfg, externs_json)
|
||||
return MirJsonV1Adapter.to_v0(j1)
|
||||
}
|
||||
|
||||
// No-op entry(箱ガード用)
|
||||
main(args) { return 0 }
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ using "lang/src/compiler/pipeline_v2/stage1_name_args_normalizer_box.hako" as Na
|
||||
using "lang/src/compiler/pipeline_v2/alias_preflight_box.hako" as AliasPreflightBox
|
||||
using "lang/src/compiler/pipeline_v2/stage1_args_parser_box.hako" as Stage1ArgsParserBox
|
||||
using "lang/src/compiler/pipeline_v2/pipeline_helpers_box.hako" as PipelineHelpersBox
|
||||
using "lang/src/shared/json/mir_v1_meta_inject_box.hako" as MirV1MetaInjectBox
|
||||
|
||||
flow PipelineV2 {
|
||||
lower_stage1_to_mir(ast_json, prefer_cfg) {
|
||||
@ -150,6 +151,14 @@ flow PipelineV2 {
|
||||
return PipelineV2.lower_stage1_to_mir(ast_json, prefer_cfg)
|
||||
}
|
||||
|
||||
// Experimental (with metadata): emit JSON v1 and inject metadata.extern_c.
|
||||
// externs_json: JSON array text like
|
||||
// [{"func":"Name/Arity","symbol":"c_symbol"}, ...]
|
||||
lower_stage1_to_mir_v1_with_meta(ast_json, prefer_cfg, externs_json) {
|
||||
local j1 = PipelineV2.lower_stage1_to_mir_v1(ast_json, prefer_cfg)
|
||||
return MirV1MetaInjectBox.inject_meta_externs(j1, externs_json)
|
||||
}
|
||||
|
||||
// Experimental helper: emit v1 then downgrade to v0 for Mini‑VM exec
|
||||
lower_stage1_to_mir_v1_compat(ast_json, prefer_cfg) {
|
||||
local j1 = PipelineV2.lower_stage1_to_mir_v1(ast_json, prefer_cfg)
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
using "lang/src/compiler/pipeline_v2/emit_call_box.hako" as EmitCallBox
|
||||
using "lang/src/compiler/pipeline_v2/local_ssa_box.hako" as LocalSSABox
|
||||
using "lang/src/shared/json/mir_v1_meta_inject_box.hako" as MirV1MetaInjectBox
|
||||
|
||||
static box PipelineEmitBox {
|
||||
// Emit Call(name, int-args) → JSON v0, wrapped with LocalSSA ensures
|
||||
@ -10,6 +11,14 @@ static box PipelineEmitBox {
|
||||
local j = EmitCallBox.emit_call_int_args(name, args)
|
||||
return LocalSSABox.ensure_calls(LocalSSABox.ensure_cond(j))
|
||||
}
|
||||
|
||||
// Emit Call(name, int-args) → JSON v1 with metadata.extern_c (if provided)
|
||||
// externs_json: JSON array text like
|
||||
// [{"func":"Name/Arity","symbol":"c_symbol"}, ...]
|
||||
emit_call_int_args_v1_with_meta(name, args, externs_json) {
|
||||
local jv0 = me.emit_call_int_args_v0(name, args)
|
||||
return MirV1MetaInjectBox.inject_meta_externs(jv0, externs_json)
|
||||
}
|
||||
}
|
||||
|
||||
static box PipelineEmitMain { main(args) { return 0 } }
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
using "lang/src/compiler/stage1/json_program_box.hako" as JsonProg
|
||||
|
||||
static box EmitterBox {
|
||||
emit_program(json, usings_json) {
|
||||
emit_program(json, usings_json, externs_json) {
|
||||
if json == null { return json }
|
||||
return JsonProg.normalize(json, usings_json)
|
||||
return JsonProg.normalize(json, usings_json, externs_json)
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,21 +5,24 @@ using "lang/src/shared/common/string_helpers.hako" as StringHelpers
|
||||
using "lang/src/shared/json/json_utils.hako" as JsonUtilsBox
|
||||
|
||||
static box JsonProgramBox {
|
||||
normalize(json, usings_json) {
|
||||
normalize(json, usings_json, externs_json) {
|
||||
local normalized = me.normalize_program(json)
|
||||
// 一括正規化: 配列フィールドの null を [] に丸める(Loop.body / If.then/else / Call.args)
|
||||
normalized = me.fix_null_arrays(normalized)
|
||||
normalized = me.compact_array_ws(normalized)
|
||||
return me.ensure_meta(normalized, usings_json)
|
||||
return me.ensure_meta(normalized, usings_json, externs_json)
|
||||
}
|
||||
|
||||
ensure_meta(json, usings_json) {
|
||||
ensure_meta(json, usings_json, externs_json) {
|
||||
local payload = usings_json
|
||||
if payload == null { payload = "[]" }
|
||||
if payload.size() == 0 { payload = "[]" }
|
||||
local ext = externs_json
|
||||
if ext == null { ext = "[]" }
|
||||
if ext.size() == 0 { ext = "[]" }
|
||||
|
||||
if json == null {
|
||||
return "{\"version\":0,\"kind\":\"Program\",\"body\":[],\"meta\":{\"usings\":" + payload + "}}"
|
||||
return "{\"version\":0,\"kind\":\"Program\",\"body\":[],\"meta\":{\"usings\":" + payload + ",\"extern_c\":" + ext + "}}"
|
||||
}
|
||||
|
||||
local n = json.lastIndexOf("}")
|
||||
@ -33,7 +36,7 @@ static box JsonProgramBox {
|
||||
if last == "{" || last == "," { needs_comma = 0 }
|
||||
}
|
||||
if needs_comma == 1 { head = head + "," }
|
||||
return head + "\"meta\":{\"usings\":" + payload + "}" + tail
|
||||
return head + "\"meta\":{\"usings\":" + payload + ",\"extern_c\":" + ext + "}" + tail
|
||||
}
|
||||
|
||||
normalize_program(json) {
|
||||
|
||||
Reference in New Issue
Block a user