runner: add NyVM wrapper core_bridge (canonicalize/dump) + opt-in wrapper canary; export module in common_util
This commit is contained in:
@ -27,6 +27,7 @@ static box Main {
|
||||
}
|
||||
|
||||
_collect_flags(args) {
|
||||
// Stage-A flags: emit/source/return only
|
||||
local flags = { emit: 0, ret: null, source: null }
|
||||
if args == null { return flags }
|
||||
|
||||
@ -210,17 +211,17 @@ static box Main {
|
||||
// expr like: {"a":1,"b":2} - Stage‑A: minimal implementation for basic key/value pairs
|
||||
local inner = me._trim(expr.substring(1, expr.length()-1))
|
||||
if inner == "" { return me._emit_call("map.of", "") }
|
||||
|
||||
|
||||
local out = ""
|
||||
local i = 0
|
||||
local n = inner.length()
|
||||
loop(i <= n) {
|
||||
// find next comma or end
|
||||
local j = i
|
||||
loop(j < n) {
|
||||
local ch = inner.substring(j,j+1)
|
||||
if ch == "," { break }
|
||||
j = j + 1
|
||||
loop(j < n) {
|
||||
local ch = inner.substring(j,j+1)
|
||||
if ch == "," { break }
|
||||
j = j + 1
|
||||
}
|
||||
local jj = j
|
||||
if jj >= n { jj = n }
|
||||
@ -466,7 +467,7 @@ static box Main {
|
||||
if flags.emit == 1 {
|
||||
local json = me._compile_source_to_json_v0(flags.source)
|
||||
print(json)
|
||||
return
|
||||
return 0
|
||||
}
|
||||
// Stage-A は --min-json 指定時のみ JSON を出力
|
||||
if flags.source != null && flags.source != "" {
|
||||
|
||||
74
lang/src/compiler/entry/compiler_stageb.hako
Normal file
74
lang/src/compiler/entry/compiler_stageb.hako
Normal file
@ -0,0 +1,74 @@
|
||||
// Stage-B compiler entry — ParserBox → FlowEntry emit-only
|
||||
|
||||
using "lang/src/compiler/parser/parser_box.hako" as ParserBox
|
||||
using "lang/src/compiler/pipeline_v2/flow_entry.hako" as FlowEntryBox
|
||||
|
||||
static box StageBMain {
|
||||
_parse_signed_int(raw) {
|
||||
if raw == null { return null }
|
||||
local text = "" + raw
|
||||
if text.length() == 0 { return null }
|
||||
local sign = 1
|
||||
local idx = 0
|
||||
if text.length() > 0 && text.substring(0, 1) == "-" {
|
||||
sign = -1
|
||||
idx = 1
|
||||
}
|
||||
if idx >= text.length() { return null }
|
||||
local acc = 0
|
||||
loop(idx < text.length()) {
|
||||
local ch = text.substring(idx, idx + 1)
|
||||
if ch < "0" || ch > "9" { return null }
|
||||
local digit = "0123456789".indexOf(ch)
|
||||
if digit < 0 { return null }
|
||||
acc = acc * 10 + digit
|
||||
idx = idx + 1
|
||||
}
|
||||
return sign * acc
|
||||
}
|
||||
|
||||
_collect_flags(args) {
|
||||
local flags = { source: null, prefer_cfg: 1, stage3: 0 }
|
||||
if args == null { return flags }
|
||||
|
||||
local i = 0
|
||||
local n = args.length()
|
||||
loop(i < n) {
|
||||
local token = "" + args.get(i)
|
||||
if token == "--source" && i + 1 < n {
|
||||
flags.source = "" + args.get(i + 1)
|
||||
i = i + 1
|
||||
} else if token == "--prefer-cfg" && i + 1 < n {
|
||||
local parsed = me._parse_signed_int(args.get(i + 1))
|
||||
if parsed != null { flags.prefer_cfg = parsed }
|
||||
i = i + 1
|
||||
} else if token == "--stage3" {
|
||||
flags.stage3 = 1
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
main(args) {
|
||||
local flags = me._collect_flags(args)
|
||||
local src = flags.source
|
||||
if src == null || src == "" {
|
||||
print("{\"version\":0,\"kind\":\"Program\",\"body\":[{\"type\":\"Return\",\"expr\":{\"type\":\"Int\",\"value\":0}}]}")
|
||||
return 0
|
||||
}
|
||||
local p = new ParserBox()
|
||||
if flags.stage3 == 1 { p.stage3_enable(1) }
|
||||
p.extract_usings(src)
|
||||
local usings_json = p.get_usings_json()
|
||||
p.extract_externs(src)
|
||||
local externs_json = p.get_externs_json()
|
||||
local ast_json = p.parse_program2(src)
|
||||
local prefer = flags.prefer_cfg
|
||||
local jv0 = FlowEntryBox.emit_v0_from_ast(ast_json, prefer)
|
||||
// Attach usings metadata when available(Stage-B pipeline consumes via resolver)
|
||||
if jv0 == null || jv0 == "" { jv0 = "{\"version\":0,\"kind\":\"Program\",\"body\":[{\"type\":\"Return\",\"expr\":{\"type\":\"Int\",\"value\":0}}]}" }
|
||||
print(jv0)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@ -157,9 +157,11 @@ box ParserBox {
|
||||
// === 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 sym = symbol
|
||||
if sym == null { sym = "" }
|
||||
local func_name = func
|
||||
if func_name == null { func_name = "" }
|
||||
local entry = "{\"symbol\":\"" + me.esc_json(sym) + "\",\"func\":\"" + me.esc_json(func_name) + "\"}"
|
||||
local cur = me.externs_json
|
||||
if cur == null || cur.size() == 0 { cur = "[]" }
|
||||
if cur == "[]" {
|
||||
|
||||
@ -37,8 +37,8 @@ static box EmitCallBox {
|
||||
return "\"" + out + "\""
|
||||
}
|
||||
emit_call_int_args(name, args) {
|
||||
name = match name { null => "", _ => name }
|
||||
args = match args { null => [], _ => args }
|
||||
if name == null { name = "" }
|
||||
if args == null { args = [] }
|
||||
// JSON v0 shape (HeaderEmitBox contract): {functions:[{name,params,blocks:[{id,instructions}]}]}
|
||||
// Materialize immediate int args: r1..rN; mir_call Extern(name)(r1..rN)->rK; ret rK
|
||||
local s = "" + args
|
||||
|
||||
@ -54,8 +54,9 @@ static box EmitCompareBox {
|
||||
|
||||
emit_compare_cfg3(lhs, rhs, cmp, materialize, trace) {
|
||||
if trace == 1 { print("[emit] compare lhs=" + lhs + " rhs=" + rhs + " cmp=" + cmp + " mat=" + materialize) }
|
||||
// normalize cmp via match
|
||||
cmp = match cmp { null => "Gt", "" => "Gt", _ => cmp }
|
||||
// normalize cmp (null/empty → Gt)
|
||||
if cmp == null { cmp = "Gt" }
|
||||
if cmp == "" { cmp = "Gt" }
|
||||
// string直組み
|
||||
local lhs_s = EmitCompareBox._to_str(lhs)
|
||||
local rhs_s = EmitCompareBox._to_str(rhs)
|
||||
|
||||
@ -32,8 +32,8 @@ static box EmitMethodBox {
|
||||
return "\"" + out + "\""
|
||||
}
|
||||
emit_method_int_args(method, recv_val, args) {
|
||||
method = match method { null => "", _ => method }
|
||||
args = match args { null => [], _ => args }
|
||||
if method == null { method = "" }
|
||||
if args == null { args = [] }
|
||||
// Shape: const recv->r1; const args r2..rN; mir_call Method(method, r1, r2..)->rK; ret rK
|
||||
local s = "" + args
|
||||
local pos = 0
|
||||
|
||||
@ -10,8 +10,8 @@ using "lang/src/compiler/pipeline_v2/local_ssa_box.hako" as LocalSSABox
|
||||
|
||||
static box EmitNewBoxBox {
|
||||
emit_newbox_int_args(class_name, args) {
|
||||
class_name = match class_name { null => "", _ => class_name }
|
||||
args = match args { null => [], _ => args }
|
||||
if class_name == null { class_name = "" }
|
||||
if args == null { args = [] }
|
||||
// ArgsParserBox 正規化 → BlockBuilder 直結
|
||||
local vals = Stage1ArgsParserBox.parse_ints(args)
|
||||
if vals == null { return null }
|
||||
@ -22,8 +22,8 @@ static box EmitNewBoxBox {
|
||||
|
||||
// JSON v1 (MirCall) emission — experimental, shape-only
|
||||
emit_newbox_int_args_v1(class_name, args) {
|
||||
class_name = match class_name { null => "", _ => class_name }
|
||||
args = match args { null => [], _ => args }
|
||||
if class_name == null { class_name = "" }
|
||||
if args == null { args = [] }
|
||||
// 同形出力(shared builder に一本化)
|
||||
local vals = Stage1ArgsParserBox.parse_ints(args)
|
||||
if vals == null { return null }
|
||||
|
||||
@ -11,8 +11,8 @@ using "lang/src/shared/mir/json_emit_box.hako" as JsonEmitBox
|
||||
static box MirCallBox {
|
||||
// Global(name, args:int[])
|
||||
emit_call_v1(name, args) {
|
||||
name = match name { null => "", _ => name }
|
||||
args = match args { null => [], _ => args }
|
||||
if name == null { name = "" }
|
||||
if args == null { args = [] }
|
||||
local s = "" + args
|
||||
local pos = 0
|
||||
local n = 0
|
||||
@ -36,8 +36,8 @@ static box MirCallBox {
|
||||
|
||||
// Method(method, recv:int, args:int[])
|
||||
emit_method_v1(method, recv_val, args) {
|
||||
method = match method { null => "", _ => method }
|
||||
args = match args { null => [], _ => args }
|
||||
if method == null { method = "" }
|
||||
if args == null { args = [] }
|
||||
local s = "" + args
|
||||
local pos = 0
|
||||
local n = 0
|
||||
@ -63,8 +63,8 @@ static box MirCallBox {
|
||||
|
||||
// Constructor(class, args:int[])
|
||||
emit_newbox_v1(class_name, args) {
|
||||
class_name = match class_name { null => "", _ => class_name }
|
||||
args = match args { null => [], _ => args }
|
||||
if class_name == null { class_name = "" }
|
||||
if args == null { args = [] }
|
||||
local s = "" + args
|
||||
local pos = 0
|
||||
local n = 0
|
||||
|
||||
Reference in New Issue
Block a user