feat(llvm): Complete function call system implementation by ChatGPT5

Major improvements to LLVM backend function call infrastructure:

## Key Changes

### Function Call System Complete
- All MIR functions now properly lowered to LLVM (not just entry)
- Function parameter binding to LLVM arguments implemented
- ny_main() wrapper added for proper entry point handling
- Callee resolution from ValueId to function symbols working

### Call Instruction Analysis
- MirInstruction::Call was implemented but system was incomplete
- Fixed "rhs missing" errors caused by undefined Call return values
- Function calls now properly return values through the system

### Code Modularization (Ongoing)
- BoxCall → instructions/boxcall.rs ✓
- ExternCall → instructions/externcall.rs ✓
- Call remains in mod.rs (to be refactored)

### Phase 21 Documentation
- Added comprehensive AI evaluation from Gemini and Codex
- Both AIs confirm academic paper potential for self-parsing AST DB approach
- "Code as Database" concept validated as novel contribution

Co-authored-by: ChatGPT5 <noreply@openai.com>

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Selfhosting Dev
2025-09-12 01:45:00 +09:00
parent 4f4c6397a9
commit 40d0cac0f1
17 changed files with 2219 additions and 608 deletions

View File

@ -146,6 +146,82 @@ pub(super) fn try_handle_string_method<'ctx>(
return Ok(true);
}
// substring(start, end) -> i8*
if method == "substring" {
if args.len() != 2 {
return Err("String.substring expects 2 args (start, end)".to_string());
}
let i64t = codegen.context.i64_type();
let i8p = codegen.context.ptr_type(AddressSpace::from(0));
// receiver must be i8* for this fast path
let recv_p = match recv_v {
BVE::PointerValue(p) => p,
_ => return Ok(false),
};
let a0 = *vmap.get(&args[0]).ok_or("substring start arg missing")?;
let a1 = *vmap.get(&args[1]).ok_or("substring end arg missing")?;
let s = match a0 {
BVE::IntValue(iv) => iv,
_ => return Err("substring start must be integer".to_string()),
};
let e = match a1 {
BVE::IntValue(iv) => iv,
_ => return Err("substring end must be integer".to_string()),
};
let fnty = i8p.fn_type(&[i8p.into(), i64t.into(), i64t.into()], false);
let callee = codegen
.module
.get_function("nyash.string.substring_sii")
.unwrap_or_else(|| codegen.module.add_function("nyash.string.substring_sii", fnty, None));
let call = codegen
.builder
.build_call(callee, &[recv_p.into(), s.into(), e.into()], "substring_call")
.map_err(|e| e.to_string())?;
if let Some(d) = dst {
let rv = call
.try_as_basic_value()
.left()
.ok_or("substring returned void".to_string())?;
vmap.insert(*d, rv);
}
return Ok(true);
}
// lastIndexOf(needle) -> i64
if method == "lastIndexOf" {
if args.len() != 1 {
return Err("String.lastIndexOf expects 1 arg".to_string());
}
let i64t = codegen.context.i64_type();
let i8p = codegen.context.ptr_type(AddressSpace::from(0));
// receiver must be i8* for this fast path
let recv_p = match recv_v {
BVE::PointerValue(p) => p,
_ => return Ok(false),
};
let a0 = *vmap.get(&args[0]).ok_or("lastIndexOf arg missing")?;
let needle_p = match a0 {
BVE::PointerValue(p) => p,
_ => return Err("lastIndexOf arg must be i8*".to_string()),
};
let fnty = i64t.fn_type(&[i8p.into(), i8p.into()], false);
let callee = codegen
.module
.get_function("nyash.string.lastIndexOf_ss")
.unwrap_or_else(|| codegen.module.add_function("nyash.string.lastIndexOf_ss", fnty, None));
let call = codegen
.builder
.build_call(callee, &[recv_p.into(), needle_p.into()], "lastindexof_call")
.map_err(|e| e.to_string())?;
if let Some(d) = dst {
let rv = call
.try_as_basic_value()
.left()
.ok_or("lastIndexOf returned void".to_string())?;
vmap.insert(*d, rv);
}
return Ok(true);
}
Ok(false)
}