diff --git a/bc/src/compiler.c b/bc/src/compiler.c index e846b81..1da7fcf 100644 --- a/bc/src/compiler.c +++ b/bc/src/compiler.c @@ -2,6 +2,7 @@ #include "commons.h" #include "node.h" #include "opcodes.h" +#include "program.h" #include "syms.h" #include "value.h" #include "vec.h" @@ -11,6 +12,7 @@ void compiler_init(struct compiler* self, struct syms* syms) assert(self); self->syms = syms; memset(self->error_msg, 0, GUX_STR_SIZE); + self->stack_size = 0; } void compiler_free(struct compiler* self) @@ -28,6 +30,26 @@ int compiler_compile(struct compiler* self, switch (node->type) { + case NODE_BLOCK: { + int stack_base = self->stack_size; + + for (size_t i=0; ichildren.size; i++) + { + if (compiler_compile(self, node->children.data[i], program) != 0) + { + return 1; + } + } + + int top = self->stack_size - stack_base; + + for (int i=0; ichildren.data[0]; struct node* expr = node->children.data[1]; @@ -40,7 +62,7 @@ int compiler_compile(struct compiler* self, return 1; } - program_push_instr(program, OP_STORE, entry->addr); + compiler_gen_instr(self, program, OP_STORE, entry->addr); } break; case NODE_IDENT: { @@ -56,7 +78,7 @@ int compiler_compile(struct compiler* self, return 1; } - program_push_instr(program, OP_LOAD, entry->addr); + compiler_gen_instr(self, program, OP_LOAD, entry->addr); } break; case NODE_CONSTDECL: @@ -76,7 +98,7 @@ int compiler_compile(struct compiler* self, node); assert(entry); - program_push_instr(program, OP_STORE, entry->addr); + compiler_gen_instr(self, program, OP_STORE, entry->addr); } break; case NODE_BOOL: { struct value* val = malloc(sizeof(struct value)); @@ -84,28 +106,28 @@ int compiler_compile(struct compiler* self, strcmp(node->value, "true") == 0 ? 1 : 0, node->line); size_t addr = program_push_constant(program, val); - program_push_instr(program, OP_PUSH, addr); + compiler_gen_instr(self, program, OP_PUSH, addr); } break; case NODE_INT: { struct value* val = malloc(sizeof(struct value)); value_init_int(val, atoi(node->value), node->line); size_t addr = program_push_constant(program, val); - program_push_instr(program, OP_PUSH, addr); + compiler_gen_instr(self, program, OP_PUSH, addr); } break; case NODE_FLOAT: { struct value* val = malloc(sizeof(struct value)); value_init_float(val, atof(node->value), node->line); size_t addr = program_push_constant(program, val); - program_push_instr(program, OP_PUSH, addr); + compiler_gen_instr(self, program, OP_PUSH, addr); } break; case NODE_STRING: { struct value* val = malloc(sizeof(struct value)); value_init_string(val, node->value, node->line); size_t addr = program_push_constant(program, val); - program_push_instr(program, OP_PUSH, addr); + compiler_gen_instr(self, program, OP_PUSH, addr); } break; case NODE_ASSERT: { @@ -114,21 +136,21 @@ int compiler_compile(struct compiler* self, return 1; } - size_t brt = program_push_instr(program, OP_BRT, NO_PARAM); - program_push_instr(program, OP_PUSH, GUX_RET_ASSERT); - size_t halt = program_push_instr(program, OP_HALT, node->line); + size_t brt = compiler_gen_instr(self, program, OP_BRT, NO_PARAM); + compiler_gen_instr(self, program, OP_PUSH, GUX_RET_ASSERT); + size_t halt = compiler_gen_instr(self, program, OP_HALT, node->line); struct instruction* instr = program->instructions.data[brt]; instr->param = halt + 1; if (halt + 1 >= program->instructions.size) { - program_push_instr(program, OP_NOP, NO_PARAM); + compiler_gen_instr(self, program, OP_NOP, NO_PARAM); } struct value* value = malloc(sizeof(struct value)); value_init_bool(value, VAL_TRUE, node->line); - program_push_instr(program, OP_PUSH, + compiler_gen_instr(self, program, OP_PUSH, program_push_constant(program, value)); } break; @@ -140,7 +162,7 @@ int compiler_compile(struct compiler* self, { return 1; } - program_push_instr(program, OP_EQ, NO_PARAM); + compiler_gen_instr(self, program, OP_EQ, NO_PARAM); } break; case NODE_NE: { @@ -152,8 +174,8 @@ int compiler_compile(struct compiler* self, return 1; } - program_push_instr(program, OP_EQ, NO_PARAM); - program_push_instr(program, OP_NOT, NO_PARAM); + compiler_gen_instr(self, program, OP_EQ, NO_PARAM); + compiler_gen_instr(self, program, OP_NOT, NO_PARAM); } break; case NODE_NOT: { @@ -162,7 +184,7 @@ int compiler_compile(struct compiler* self, return 1; } - program_push_instr(program, OP_NOT, NO_PARAM); + compiler_gen_instr(self, program, OP_NOT, NO_PARAM); } break; case NODE_AND: { @@ -177,17 +199,17 @@ int compiler_compile(struct compiler* self, } size_t* addr = malloc(sizeof(size_t)); - *addr = program_push_instr(program, OP_BRF, NO_PARAM); // to pivot + *addr = compiler_gen_instr(self, program, OP_BRF, NO_PARAM); // to pivot vec_push(&to_pivot, addr); } // true case struct value* true_val = malloc(sizeof(struct value)); value_init_bool(true_val, VAL_TRUE, node->line); - program_push_instr(program, OP_PUSH, + compiler_gen_instr(self, program, OP_PUSH, program_push_constant(program, true_val)); - size_t to_end = program_push_instr(program, OP_BR, NO_PARAM); // to end + size_t to_end = compiler_gen_instr(self, program, OP_BR, NO_PARAM); // to end // pivot size_t pivot_point = program->instructions.size; @@ -195,7 +217,7 @@ int compiler_compile(struct compiler* self, // false case struct value* false_val = malloc(sizeof(struct value)); value_init_bool(false_val, VAL_FALSE, node->line); - program_push_instr(program, OP_PUSH, + compiler_gen_instr(self, program, OP_PUSH, program_push_constant(program, false_val)); // end @@ -229,17 +251,17 @@ int compiler_compile(struct compiler* self, } size_t* addr = malloc(sizeof(size_t)); - *addr = program_push_instr(program, OP_BRT, NO_PARAM); // to pivot + *addr = compiler_gen_instr(self, program, OP_BRT, NO_PARAM); // to pivot vec_push(&to_pivot, addr); } // false case struct value* false_val = malloc(sizeof(struct value)); value_init_bool(false_val, VAL_FALSE, node->line); - program_push_instr(program, OP_PUSH, + compiler_gen_instr(self, program, OP_PUSH, program_push_constant(program, false_val)); - size_t to_end = program_push_instr(program, OP_BR, NO_PARAM); // to end + size_t to_end = compiler_gen_instr(self, program, OP_BR, NO_PARAM); // to end // pivot size_t pivot_point = program->instructions.size; @@ -247,7 +269,7 @@ int compiler_compile(struct compiler* self, // false case struct value* true_val = malloc(sizeof(struct value)); value_init_bool(true_val, VAL_TRUE, node->line); - program_push_instr(program, OP_PUSH, + compiler_gen_instr(self, program, OP_PUSH, program_push_constant(program, true_val)); // end @@ -291,16 +313,16 @@ int compiler_compile(struct compiler* self, switch (node->type) { - case NODE_ADD: program_push_instr(program, OP_ADD, NO_PARAM); break; - case NODE_SUB: program_push_instr(program, OP_SUB, NO_PARAM); break; - case NODE_MUL: program_push_instr(program, OP_MUL, NO_PARAM); break; - case NODE_DIV: program_push_instr(program, OP_DIV, NO_PARAM); break; - case NODE_MOD: program_push_instr(program, OP_MOD, NO_PARAM); break; - case NODE_POW: program_push_instr(program, OP_POW, NO_PARAM); break; - case NODE_LT: program_push_instr(program, OP_LT, NO_PARAM); break; - case NODE_LE: program_push_instr(program, OP_LE, NO_PARAM); break; - case NODE_GT: program_push_instr(program, OP_GT, NO_PARAM); break; - case NODE_GE: program_push_instr(program, OP_GE, NO_PARAM); break; + case NODE_ADD: compiler_gen_instr(self, program, OP_ADD, NO_PARAM); break; + case NODE_SUB: compiler_gen_instr(self, program, OP_SUB, NO_PARAM); break; + case NODE_MUL: compiler_gen_instr(self, program, OP_MUL, NO_PARAM); break; + case NODE_DIV: compiler_gen_instr(self, program, OP_DIV, NO_PARAM); break; + case NODE_MOD: compiler_gen_instr(self, program, OP_MOD, NO_PARAM); break; + case NODE_POW: compiler_gen_instr(self, program, OP_POW, NO_PARAM); break; + case NODE_LT: compiler_gen_instr(self, program, OP_LT, NO_PARAM); break; + case NODE_LE: compiler_gen_instr(self, program, OP_LE, NO_PARAM); break; + case NODE_GT: compiler_gen_instr(self, program, OP_GT, NO_PARAM); break; + case NODE_GE: compiler_gen_instr(self, program, OP_GE, NO_PARAM); break; default: break; } @@ -320,3 +342,45 @@ int compiler_compile(struct compiler* self, return 0; } + +size_t compiler_gen_instr(struct compiler* self, + struct program* program, + enum Opcodes op, + int param) +{ + assert(self); + assert(program); + + size_t addr = program_push_instr(program, op, param); + + switch (op) + { + case OP_LOAD: + case OP_PUSH: self->stack_size += 1; break; + + case OP_LT: + case OP_LE: + case OP_GT: + case OP_GE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_POW: + case OP_EQ: + case OP_POP: + case OP_HALT: + case OP_BRF: + case OP_BRT: + self->stack_size -= 1; break; + + case OP_SWAP: + case OP_BR: + case OP_NOT: + case OP_NOP: + case OP_STORE: break; + } + + return addr; +} diff --git a/bc/src/compiler.h b/bc/src/compiler.h index a530d38..4301be1 100644 --- a/bc/src/compiler.h +++ b/bc/src/compiler.h @@ -10,6 +10,7 @@ struct compiler { char error_msg[GUX_STR_SIZE]; struct syms* syms; int error_line; + int stack_size; }; void compiler_init(struct compiler* self, struct syms* syms); @@ -19,4 +20,9 @@ int compiler_compile(struct compiler* self, struct node* node, struct program* program); +size_t compiler_gen_instr(struct compiler* self, + struct program* program, + enum Opcodes op, + int param); + #endif diff --git a/bc/src/opcodes.h b/bc/src/opcodes.h index 8b6d3b5..2f90342 100644 --- a/bc/src/opcodes.h +++ b/bc/src/opcodes.h @@ -5,7 +5,8 @@ G(OP_PUSH), G(OP_POP), G(OP_BRF), G(OP_BR), G(OP_HALT), \ G(OP_BRT), G(OP_NOP), G(OP_NOT), G(OP_EQ), \ G(OP_ADD), G(OP_SUB), G(OP_MUL), G(OP_DIV), G(OP_MOD), G(OP_POW), \ - G(OP_LT), G(OP_LE), G(OP_GT),G(OP_GE), G(OP_LOAD), G(OP_STORE) + G(OP_LT), G(OP_LE), G(OP_GT),G(OP_GE), G(OP_LOAD), G(OP_STORE),\ + G(OP_SWAP) #include diff --git a/lang/src/type_resolver.c b/lang/src/type_resolver.c index f053354..6d712af 100644 --- a/lang/src/type_resolver.c +++ b/lang/src/type_resolver.c @@ -53,7 +53,7 @@ int type_resolver_resolve(struct type_resolver* self, case NODE_IDENT: { struct syms_entry* entry = syms_try_get(self->syms, node->value, - node_depth(node)); + node); if (!entry) { diff --git a/lib/src/commons.h b/lib/src/commons.h index 2e80f15..23503b1 100644 --- a/lib/src/commons.h +++ b/lib/src/commons.h @@ -9,7 +9,7 @@ #include #include -#define GUX_STR_SIZE 256 +#define GUX_STR_SIZE 512 #define GUX_ENUM_IDENT(X) X #define GUX_ENUM_STR(X) #X #define GUX_ENUM_H(Prefix, Types) \ diff --git a/vm/src/vm.c b/vm/src/vm.c index e9a3c6e..12b099a 100644 --- a/vm/src/vm.c +++ b/vm/src/vm.c @@ -124,6 +124,14 @@ int vm_exec(struct vm* self, struct program* program) switch (opcode) { + case OP_SWAP: { + assert(frame->sp > 1); + int tmp = frame->stack[frame->sp - 1]; + frame->stack[frame->sp - 1] = frame->stack[frame->sp - 2]; + frame->stack[frame->sp - 2] = tmp; + self->pc++; + } break; + case OP_LOAD: { int stack_addr = vm_load(self, param); struct frame* myframe = self->stack[self->fp - 1];