c83f6d5994
Implement MVP closures — anonymous functions without captures.
Syntax:
|a: int, b: int| -> int { return a + b; }
Changes:
- ast.bux + ast.nim: add ekClosure AST node
- parser.bux + parser.nim: parse |params| -> Ret { body }
- sema.bux + sema.nim: type-check closure params/body, return tyFunc
- hir_lower.bux + hir_lower.nim: generate __closure_N function + hAddrOf
- lir_c_backend.nim: fix function-pointer variable declaration (cParamDecl)
- C backend: closures compile to global functions with unique names
Test: _test_closure/src/Main.bux
- Closure as variable
- Closure passed to higher-order function
- Address of named function as function pointer
Both bootstrap and selfhost compilers build and pass the test.
35 lines
694 B
Plaintext
35 lines
694 B
Plaintext
module Main {
|
|
|
|
extern func PrintInt(x: int);
|
|
extern func PrintLine(msg: String);
|
|
|
|
func Apply(x: int, op: func(int) -> int) -> int {
|
|
return op(x);
|
|
}
|
|
|
|
func Double(x: int) -> int {
|
|
return x * 2;
|
|
}
|
|
|
|
func main() -> int {
|
|
// Closure as variable
|
|
let add: func(int, int) -> int = |a: int, b: int| -> int { return a + b; };
|
|
let sum: int = add(3, 4);
|
|
PrintInt(sum);
|
|
PrintLine("");
|
|
|
|
// Closure passed to function
|
|
let result: int = Apply(5, |x: int| -> int { return x * 3; });
|
|
PrintInt(result);
|
|
PrintLine("");
|
|
|
|
// Address of named function as function pointer
|
|
let d: func(int) -> int = &Double;
|
|
PrintInt(d(7));
|
|
PrintLine("");
|
|
|
|
return 0;
|
|
}
|
|
|
|
}
|