From 900b412b052a0f745f0853d6703e4bafbb0a3ce5 Mon Sep 17 00:00:00 2001 From: Mel Date: Tue, 26 May 2026 00:50:09 +0200 Subject: Lambda function emission, thin/fat calling conventions for (future) closed-over state Signed-off-by: Mel --- boot/ir.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'boot/ir.c') diff --git a/boot/ir.c b/boot/ir.c index 16811ed..164d9a4 100644 --- a/boot/ir.c +++ b/boot/ir.c @@ -249,6 +249,7 @@ enum Expression_Kind EXPRESSION_CAST, EXPRESSION_CONSTRUCT, EXPRESSION_INCREMENT_DECREMENT, + EXPRESSION_FUNCTION_REF, }; struct Expression_Integer_Literal @@ -310,6 +311,10 @@ struct Expression_Call struct Expression* subject; // arguments of call in written order, the inner slot decides final ordering. Array(struct Call_Argument) arguments; + // direct calls can emit a simple call without additional syntax, + // however indirect calls which have closed-over state have to call + // them taking into account the function pointer and the state first. + bool is_indirect; }; struct Expression_Member @@ -351,6 +356,14 @@ struct Expression_Increment_Decrement struct Expression* subject; }; +// reference to a known catskill function in a value context. +struct Expression_Function_Ref +{ + Function_Id function_id; + // matching synthetic closure type for the function's signature. + Type_Id closure_type_id; +}; + union Expression_Value { struct Expression_Integer_Literal integer_literal; @@ -367,6 +380,7 @@ union Expression_Value struct Expression_Cast cast; struct Expression_Construct construct; struct Expression_Increment_Decrement increment_decrement; + struct Expression_Function_Ref function_ref; }; struct Expression @@ -402,6 +416,14 @@ struct Function Array(struct Param) params; bool variadic; // is last parameter variadic? + // matching fat-closure struct type for this function's signature. + // synthesized lazily on first reference in value context, or 0. + Type_Id closure_type_id; + + // tree-side header which produced this function node. + // required for synthesizing the closure type after function is lowered. + struct Tree_Function_Header* ast_header; + // first lowering pass only fills out the ast body and not the lowered body, // to collect all top-declarations. struct Tree_Block* ast_body; @@ -647,11 +669,14 @@ ir_make_sizeof(struct Type_Ref target, struct Span span) } struct Expression* -ir_make_call(struct Expression* subject, Array(struct Call_Argument) arguments, struct Span span) +ir_make_call( + struct Expression* subject, Array(struct Call_Argument) arguments, bool is_indirect, + struct Span span) { union Expression_Value v = { 0 }; v.call.subject = subject; v.call.arguments = arguments; + v.call.is_indirect = is_indirect; return expression_new(EXPRESSION_CALL, v, span); } @@ -703,6 +728,15 @@ ir_make_increment_decrement( return expression_new(EXPRESSION_INCREMENT_DECREMENT, v, span); } +struct Expression* +ir_make_function_ref(Function_Id function_id, Type_Id closure_type_id, struct Span span) +{ + union Expression_Value v = { 0 }; + v.function_ref.function_id = function_id; + v.function_ref.closure_type_id = closure_type_id; + return expression_new(EXPRESSION_FUNCTION_REF, v, span); +} + struct Type_Ref type_ref_bare(Type_Id type_id) { -- cgit 1.4.1