diff options
author | ubq323 <ubq323@ubq323.website> | 2024-06-25 00:51:37 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2024-06-25 00:51:37 +0100 |
commit | f76f5a8c244ac6d04e4d89778a6d8c2c2040cdc9 (patch) | |
tree | 484b9fea3fa5a136972384239f0890a3886bb5ba /com.c | |
parent | e9b99a90510309ac4f5d91d4a5138e7a84904057 (diff) |
get functions and arguments and returning to work fully
Diffstat (limited to 'com.c')
-rw-r--r-- | com.c | 65 |
1 files changed, 40 insertions, 25 deletions
@@ -21,6 +21,7 @@ Compiler compiler_new(Compiler *outer, Chunk *ch) { .S = outer->S, .ch = ch, .stack_cur = 0, + .scope = NULL, }; } @@ -211,26 +212,6 @@ void arith_form(Compiler *C, AstVec l, Op op) { compile_opcode(C, op); } -void fn_form(Compiler *C, AstVec l, Op _) { - // (fn (arg arg arg) body ...) - CHECK(l.vals[1].ty == AST_LIST, "fn's first argument must be list"); - AstVec arglist = l.vals[1].as.list; - CHECK(arglist.len <= 255, "maximum 255 args for function"); - uint8_t arity = arglist.len; - - ObjFunc *func = objfunc_new(C->S, arity); - Compiler subcompiler = compiler_new(C, &func->ch); - - for (int i = 2; i < l.len - 1; i++) { - compile_node(&subcompiler, l.vals[i]); - compile_opcode(&subcompiler, OP_DROP); - } - compile_node(&subcompiler, l.vals[l.len-1]); - compile_opcode(&subcompiler, OP_RET); - - compile_opcode(C, OP_LOADK); - compile_byte(C, compile_constant(C, VAL_OBJ(func))); -} static void begin_scope(Compiler *C) { Scope *sc = malloc(sizeof(Scope)); @@ -261,6 +242,7 @@ static void declare_local(Compiler *C, char *name) { // -1 because local is expected to be already on the stack // ie sitting just below where stack_cur points l->slot = C->stack_cur - 1; + // printf("declaring local %s at %d, stack_cur is %d\n",l->name, l->slot, C->stack_cur); } void let_form(Compiler *C, AstVec l, Op _) { @@ -286,7 +268,41 @@ void let_form(Compiler *C, AstVec l, Op _) { end_scope(C); } +void fn_form(Compiler *C, AstVec l, Op _) { + // (fn (arg arg arg) body ...) + CHECK(l.vals[1].ty == AST_LIST, "fn's first argument must be list"); + AstVec arglist = l.vals[1].as.list; + CHECK(arglist.len <= 255, "maximum 255 args for function"); + uint8_t arity = arglist.len; + + ObjFunc *func = objfunc_new(C->S, arity); + Compiler subcompiler = compiler_new(C, &func->ch); + Compiler *SC = &subcompiler; + begin_scope(SC); + // when called, stack slot 0 contains the function itself, + // stack slots 1..n contain passed arguments + SC->stack_cur ++; + declare_local(SC, "__func__"); + for (int i = 0; i < arity; i++) { + AstNode argname = arglist.vals[i]; + CHECK(argname.ty == AST_IDENT, "argument name must be identifier"); + SC->stack_cur ++; + declare_local(SC, argname.as.str); + } + + for (int i = 2; i < l.len - 1; i++) { + compile_node(SC, l.vals[i]); + compile_opcode(SC, OP_DROP); + } + compile_node(&subcompiler, l.vals[l.len-1]); + + end_scope(SC); + compile_opcode(SC, OP_RET); + + compile_opcode(C, OP_LOADK); + compile_byte(C, compile_constant(C, VAL_OBJ(func))); +} typedef struct { char *name; @@ -444,14 +460,13 @@ int main(int argc, char **argv) { AstNode an = read(); - Compiler com = (Compiler){ - .S = S, - .ch = &ch, - }; + Compiler com = (Compiler){ 0 }; + com.S = S; + com.ch = &ch; + Compiler *C = &com; compile_node(C, an); - compile_opcode(C, OP_PUTS); compile_opcode(C, OP_HALT); |