AstTyped *captured_value;
u32 offset;
+ b32 by_reference: 1;
};
struct AstPolyQuery {
YIELD(expr->token->pos, "Waiting to resolve #this_package.");
break;
- case Ast_Kind_Capture_Local:
- expr->type = ((AstCaptureLocal *) expr)->captured_value->type;
+ case Ast_Kind_Capture_Local: {
+ AstCaptureLocal *cl = (AstCaptureLocal *) expr;
+ if (cl->by_reference) {
+ if (!is_lval((AstNode *) cl->captured_value)) {
+ ERROR_(cl->token->pos, "Cannot pass '%b' by pointer because it is not an l-value.", cl->token->text, cl->token->length);
+ }
+
+ expr->type = type_make_pointer(context.ast_alloc, cl->captured_value->type);
+
+ } else {
+ expr->type = cl->captured_value->type;
+ }
break;
+ }
case Ast_Kind_File_Contents: break;
case Ast_Kind_Overloaded_Function: break;
if (parser->hit_unexpected_token) break;
AstCaptureLocal *capture = make_node(AstCaptureLocal, Ast_Kind_Capture_Local);
+
+ if (consume_token_if_next(parser, '&')) capture->by_reference = 1;
+
capture->token = expect_token(parser, Token_Type_Symbol);
bh_arr_push(captures->captures, capture);
// Populate the block
bh_arr_each(AstCaptureLocal *, capture, func->captures->captures) {
WIL(NULL, WI_LOCAL_GET, capture_block_ptr);
- emit_expression(mod, &code, (*capture)->captured_value);
- emit_store_instruction(mod, &code, (*capture)->captured_value->type, (*capture)->offset);
+
+ if ((*capture)->by_reference) {
+ emit_location(mod, &code, (*capture)->captured_value);
+ } else {
+ emit_expression(mod, &code, (*capture)->captured_value);
+ }
+
+ emit_store_instruction(mod, &code, (*capture)->type, (*capture)->offset);
}
local_raw_free(mod->local_alloc, WASM_TYPE_PTR);