From a14bf1188c4cee23db44a590ada52aa8778a2a3f Mon Sep 17 00:00:00 2001 From: ubq323 Date: Tue, 25 Jun 2024 16:24:29 +0100 Subject: add setting locals --- com.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'com.c') diff --git a/com.c b/com.c index a3cc5a8..66d3941 100644 --- a/com.c +++ b/com.c @@ -43,6 +43,7 @@ static int stack_effect_of(Op opcode) { case OP_SKIP: case OP_REDO: case OP_SETGLOBAL: + case OP_SETLOCAL: case OP_RET: case OP_HALT: return 0; @@ -141,13 +142,25 @@ void single_form(Compiler *C, AstVec l, Op op) { compile_opcode(C, op); } +static Local *locate_local(Compiler *C, char *name); + void set_form(Compiler *C, AstVec l, Op _) { AstNode ident = l.vals[1]; CHECK(ident.ty == AST_IDENT, "set's first argument must be identifier"); - ObjString *o = objstring_copy_cstr(C->S, ident.as.str); - compile_node(C, l.vals[2]); - compile_opcode(C, OP_SETGLOBAL); - compile_byte(C, compile_constant(C, VAL_OBJ(o))); + char *name = ident.as.str; + + Local *loc = locate_local(C, name); + if (loc != NULL) { + compile_node(C, l.vals[2]); + compile_opcode(C, OP_SETLOCAL); + compile_byte(C, loc->slot); + } else { + // write global + ObjString *o = objstring_copy_cstr(C->S, name); + compile_node(C, l.vals[2]); + compile_opcode(C, OP_SETGLOBAL); + compile_byte(C, compile_constant(C, VAL_OBJ(o))); + } } void do_form(Compiler *C, AstVec l, Op _) { -- cgit v1.2.3