Skip to main content

method_call/
method_call.rs

1//! Method call dispatch through receiver-style syntax.
2//!
3//! `n.double()` resolves at compile time to `Doubler::i64::double(n)`
4//! based on the receiver's inferred type. The compiler looks up the
5//! mangled function name in the function map and emits a regular
6//! call with the receiver passed as the first argument.
7//!
8//! Generic-receiver method calls require monomorphization (B2.4).
9//! Concrete receivers resolve directly through the narrow inference
10//! pass.
11//!
12//! Run with: `cargo run --example method_call`
13
14use keleusma::compiler::compile;
15use keleusma::lexer::tokenize;
16use keleusma::parser::parse;
17use keleusma::vm::{DEFAULT_ARENA_CAPACITY, Vm, VmState};
18use keleusma::{Arena, Value};
19
20fn main() {
21    let src = r#"
22        trait Doubler { fn double(x: i64) -> i64; }
23        impl Doubler for i64 { fn double(x: i64) -> i64 { x + x } }
24        fn main() -> i64 {
25            let n: i64 = 21;
26            n.double()
27        }
28    "#;
29    let tokens = tokenize(src).expect("lex");
30    let program = parse(&tokens).expect("parse");
31    let module = compile(&program).expect("compile");
32    let arena = Arena::with_capacity(DEFAULT_ARENA_CAPACITY);
33    let mut vm = Vm::new(module, &arena).expect("verify");
34    match vm.call(&[]) {
35        Ok(VmState::Finished(Value::Int(n))) => {
36            println!("21.double() = {}", n);
37            assert_eq!(n, 42);
38            println!("method call dispatch executed end to end");
39        }
40        other => panic!("unexpected: {:?}", other),
41    }
42}