fix(stage-b): Add sh_core using + Stage-1 JSON support
## Fixed Issues
1. compiler_stageb.hako: Added 'using sh_core as StringHelpers'
- Resolved: call unresolved ParserStringUtilsBox.skip_ws/2
- Root cause: using chain resolution not implemented
- Workaround: explicit using in parent file
2. stageb_helpers.sh: Accept Stage-1 JSON format
- Modified awk pattern to accept both formats:
- MIR JSON v0: "version":0, "kind":"Program"
- Stage-1 JSON: "type":"Program"
## Remaining Issues
ParserBox VM crash: Invalid value: use of undefined value ValueId(5839)
- Cause: Complex nested loops in parse_program2()
- Workaround: Minimal Stage-B (without ParserBox) works
- Fallback: Rust compiler path available
## Verification
✅ Minimal Stage-B outputs JSON correctly
❌ ParserBox execution crashes VM (SSA bug)
Co-Authored-By: Task先生 (AI Agent)
This commit is contained in:
@ -254,7 +254,7 @@ pub fn try_parse_v1_to_module(json: &str) -> Result<Option<MirModule>, String> {
|
||||
}
|
||||
}
|
||||
"mir_call" => {
|
||||
// Minimal v1 mir_call support (Global only; print-family)
|
||||
// Minimal v1 mir_call support (Global/Method/Constructor/Extern/Value + Closure creation)
|
||||
// dst: optional
|
||||
let dst_opt = inst.get("dst").and_then(|d| d.as_u64()).map(|v| ValueId::new(v as u32));
|
||||
// args: array of value ids
|
||||
@ -310,6 +310,153 @@ pub fn try_parse_v1_to_module(json: &str) -> Result<Option<MirModule>, String> {
|
||||
});
|
||||
if let Some(d) = dst_opt { max_value_id = max_value_id.max(d.as_u32() + 1); }
|
||||
}
|
||||
"Method" => {
|
||||
// receiver: required u64, method: string, box_name: optional
|
||||
let method = callee_obj
|
||||
.get("method")
|
||||
.and_then(Value::as_str)
|
||||
.ok_or_else(|| format!(
|
||||
"mir_call callee Method missing method in function '{}'",
|
||||
func_name
|
||||
))?
|
||||
.to_string();
|
||||
let recv_id = callee_obj
|
||||
.get("receiver")
|
||||
.and_then(Value::as_u64)
|
||||
.ok_or_else(|| format!(
|
||||
"mir_call callee Method missing receiver in function '{}'",
|
||||
func_name
|
||||
))? as u32;
|
||||
let box_name = callee_obj
|
||||
.get("box_name")
|
||||
.and_then(Value::as_str)
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
block_ref.add_instruction(MirInstruction::Call {
|
||||
dst: dst_opt,
|
||||
func: ValueId::new(0),
|
||||
callee: Some(crate::mir::definitions::Callee::Method {
|
||||
box_name,
|
||||
method,
|
||||
receiver: Some(ValueId::new(recv_id)),
|
||||
certainty: crate::mir::definitions::call_unified::TypeCertainty::Known,
|
||||
}),
|
||||
args: argv,
|
||||
effects: EffectMask::PURE,
|
||||
});
|
||||
if let Some(d) = dst_opt { max_value_id = max_value_id.max(d.as_u32() + 1); }
|
||||
}
|
||||
"Closure" => {
|
||||
// Closure creation (NewClosure equivalent)
|
||||
// Requires dst; accepts optional params[], captures[[name, id]...], me_capture
|
||||
let dst = dst_opt.ok_or_else(|| format!(
|
||||
"mir_call Closure requires dst in function '{}'",
|
||||
func_name
|
||||
))?;
|
||||
// params: array of strings (optional)
|
||||
let mut params: Vec<String> = Vec::new();
|
||||
if let Some(arr) = callee_obj.get("params").and_then(Value::as_array) {
|
||||
for p in arr {
|
||||
let s = p.as_str().ok_or_else(|| format!(
|
||||
"mir_call Closure params must be strings in function '{}'",
|
||||
func_name
|
||||
))?;
|
||||
params.push(s.to_string());
|
||||
}
|
||||
}
|
||||
// captures: array of [name, id]
|
||||
let mut captures: Vec<(String, ValueId)> = Vec::new();
|
||||
if let Some(arr) = callee_obj.get("captures").and_then(Value::as_array) {
|
||||
for e in arr {
|
||||
let pair = e.as_array().ok_or_else(|| format!(
|
||||
"mir_call Closure capture entry must be array in function '{}'",
|
||||
func_name
|
||||
))?;
|
||||
if pair.len() != 2 {
|
||||
return Err("mir_call Closure capture entry must have 2 elements".into());
|
||||
}
|
||||
let name = pair[0].as_str().ok_or_else(|| {
|
||||
"mir_call Closure capture[0] must be string".to_string()
|
||||
})?;
|
||||
let id = pair[1].as_u64().ok_or_else(|| {
|
||||
"mir_call Closure capture[1] must be integer".to_string()
|
||||
})? as u32;
|
||||
captures.push((name.to_string(), ValueId::new(id)));
|
||||
}
|
||||
}
|
||||
// me_capture: optional u64
|
||||
let me_capture = callee_obj
|
||||
.get("me_capture")
|
||||
.and_then(Value::as_u64)
|
||||
.map(|v| ValueId::new(v as u32));
|
||||
|
||||
// Body is not carried in v1; create empty body vector as placeholder
|
||||
block_ref.add_instruction(MirInstruction::NewClosure {
|
||||
dst,
|
||||
params,
|
||||
body: Vec::new(),
|
||||
captures,
|
||||
me: me_capture,
|
||||
});
|
||||
max_value_id = max_value_id.max(dst.as_u32() + 1);
|
||||
}
|
||||
"Constructor" => {
|
||||
// box_type: string, dst: required
|
||||
let dst = dst_opt.ok_or_else(|| format!(
|
||||
"mir_call Constructor requires dst in function '{}'",
|
||||
func_name
|
||||
))?;
|
||||
let bt = callee_obj
|
||||
.get("box_type")
|
||||
.and_then(Value::as_str)
|
||||
.ok_or_else(|| format!(
|
||||
"mir_call Constructor missing box_type in function '{}'",
|
||||
func_name
|
||||
))?
|
||||
.to_string();
|
||||
block_ref.add_instruction(MirInstruction::NewBox {
|
||||
dst,
|
||||
box_type: bt,
|
||||
args: argv.clone(),
|
||||
});
|
||||
max_value_id = max_value_id.max(dst.as_u32() + 1);
|
||||
}
|
||||
"Extern" => {
|
||||
let name = callee_obj
|
||||
.get("name")
|
||||
.and_then(Value::as_str)
|
||||
.ok_or_else(|| format!(
|
||||
"mir_call callee Extern missing name in function '{}'",
|
||||
func_name
|
||||
))?
|
||||
.to_string();
|
||||
block_ref.add_instruction(MirInstruction::Call {
|
||||
dst: dst_opt,
|
||||
func: ValueId::new(0),
|
||||
callee: Some(crate::mir::definitions::Callee::Extern(name)),
|
||||
args: argv,
|
||||
effects: EffectMask::IO,
|
||||
});
|
||||
if let Some(d) = dst_opt { max_value_id = max_value_id.max(d.as_u32() + 1); }
|
||||
}
|
||||
"Value" => {
|
||||
// dynamic function value id: field 'func' (u64)
|
||||
let fid = callee_obj
|
||||
.get("func")
|
||||
.and_then(Value::as_u64)
|
||||
.ok_or_else(|| format!(
|
||||
"mir_call callee Value missing func in function '{}'",
|
||||
func_name
|
||||
))? as u32;
|
||||
block_ref.add_instruction(MirInstruction::Call {
|
||||
dst: dst_opt,
|
||||
func: ValueId::new(0),
|
||||
callee: Some(crate::mir::definitions::Callee::Value(ValueId::new(fid))),
|
||||
args: argv,
|
||||
effects: EffectMask::PURE,
|
||||
});
|
||||
if let Some(d) = dst_opt { max_value_id = max_value_id.max(d.as_u32() + 1); }
|
||||
}
|
||||
other => {
|
||||
return Err(format!(
|
||||
"unsupported callee type '{}' in mir_call (Gate-C v1 bridge)",
|
||||
|
||||
Reference in New Issue
Block a user