#include #include #include #include "vm.h" #include "ast.h" #include "read.h" static void compile_node(Chunk *ch, AstNode a) { switch (a.ty) { case AST_IDENT: printf("can't compile ident\n"); exit(1); break; case AST_NUM: chunk_wbc(ch, OP_LOADK); chunk_wbc(ch, chunk_wconst(ch, VAL_NUM(a.as.num))); break; case AST_STRING: { size_t len = strlen(a.as.str); ObjString *o = objstring_new(a.as.str, len); chunk_wbc(ch, OP_LOADK); chunk_wbc(ch, chunk_wconst(ch, VAL_OBJ(o))); break; } case AST_LIST: { AstVec l = a.as.list; #define CK(cond, msg) if (!(cond)) { puts(msg); exit(1); } CK(l.len == 3, "can only compile binary ops"); CK(l.vals[0].ty == AST_IDENT, "can only call ops"); #undef CK 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(ch, l.vals[1]); compile_node(ch, l.vals[2]); chunk_wbc(ch, op); } } } int main() { Chunk ch = chunk_new(); AstNode an = read(); compile_node(&ch, an); chunk_wbc(&ch, OP_PRINT); chunk_wbc(&ch, OP_RET); runvm(&ch); }