diff options
Diffstat (limited to 'com.c')
-rw-r--r-- | com.c | 56 |
1 files changed, 37 insertions, 19 deletions
@@ -35,26 +35,44 @@ static void compile_node(State *S, Chunk *ch, AstNode a) { CK(l.len == 2, "print requires exactly 1 argument"); compile_node(S, ch, l.vals[1]); chunk_wbc(S, ch, OP_PRINT); - break; - } - CK(l.len == 3, "can only compile binary ops"); - char opchar = l.vals[0].as.str[0]; - Op op; - switch (opchar) { - #define OP(char, code) case char: op = code; break; - OP('+', OP_ADD) - OP('-', OP_SUB) - OP('*', OP_MUL) - OP('/', OP_DIV) - #undef OP - default: - printf("unkown op %s\n",l.vals[0].as.str); - exit(1); - break; + } else if (0 == strcmp(l.vals[0].as.str, "set")) { + CK(l.len == 3, "set requires exactly 2 arguments"); + AstNode ident = l.vals[1]; + CK(ident.ty == AST_IDENT, "set's first argument must be identifier"); + + size_t len = strlen(ident.as.str); + ObjString *o = objstring_copy(S, ident.as.str, len); + + compile_node(S, ch, l.vals[2]); + chunk_wbc(S, ch, OP_SETGLOBAL); + chunk_wbc(S, ch, chunk_wconst(S, ch, VAL_OBJ(o))); + } else if (0 == strcmp(l.vals[0].as.str, "do")) { + for (int i = 1; i < l.len - 1; i++) { + compile_node(S, ch, l.vals[i]); + chunk_wbc(S, ch, OP_DROP); + } + compile_node(S, ch, l.vals[l.len - 1]); + } else { + + CK(l.len == 3, "can only compile binary ops"); + char opchar = l.vals[0].as.str[0]; + Op op; + switch (opchar) { + #define OP(char, code) case char: op = code; break; + OP('+', OP_ADD) + OP('-', OP_SUB) + OP('*', OP_MUL) + OP('/', OP_DIV) + #undef OP + default: + printf("unkown op %s\n",l.vals[0].as.str); + exit(1); + break; + } + compile_node(S, ch, l.vals[1]); + compile_node(S, ch, l.vals[2]); + chunk_wbc(S, ch, op); } - compile_node(S, ch, l.vals[1]); - compile_node(S, ch, l.vals[2]); - chunk_wbc(S, ch, op); #undef CK } } |