#include "compiler.h" #include "lib/commons.h" void compiler_init(compiler_t* compiler, mod_t* mod, tysy_t* tysy, err_t* err) { assert(compiler); assert(err); compiler->mod = mod; compiler->tysy = tysy; compiler->err = err; } void compiler_free(compiler_t* compiler) { assert(compiler); } void compiler_run(compiler_t* compiler, node_t* node) { assert(compiler); assert(node); switch (node->type) { case NODE_MOD: { for (size_t i=0; ichildren.size; i++) { compiler_run(compiler, (node_t*) node->children.data[i]); } } break; case NODE_NUM: { double value = atof(node->value.data); value_t* val = tysy_new_num(compiler->tysy, value, node->line); Opcode op = OP_PUSH; param_t param = (param_t) mod_push_new_value(compiler->mod, val); mod_push_instr(compiler->mod, op, param); } break; case NODE_BOOL: { int value = strcmp(node->value.data, "true") == 0; value_t* val = tysy_new_bool(compiler->tysy, value, node->line); Opcode op = OP_PUSH; param_t param = (param_t) mod_push_new_value(compiler->mod, val); mod_push_instr(compiler->mod, op, param); } break; case NODE_STR: { char* value = node->value.data; value_t* val = tysy_new_str(compiler->tysy, value, node->line); Opcode op = OP_PUSH; param_t param = (param_t) mod_push_new_value(compiler->mod, val); mod_push_instr(compiler->mod, op, param); } break; case NODE_ASSERT: { assert(node->children.size == 1); compiler_run(compiler, node_child(node, 0)); mod_push_instr(compiler->mod, OP_ASSERT, RZ_NO_PARAM); } break; case NODE_NE: case NODE_EQ: { assert(node->children.size == 2); for (size_t i=0; ichildren.size; i++) { compiler_run(compiler, node_child(node, i)); } mod_push_instr(compiler->mod, node->type == NODE_EQ ? OP_EQ : OP_NE, RZ_NO_PARAM); } break; case NODE_LT: case NODE_LE: case NODE_GT: case NODE_GE: { assert(node->children.size == 2); for (size_t i=0; ichildren.size; i++) { compiler_run(compiler, node_child(node, i)); } Opcode op; switch (node->type) { case NODE_LT: op = OP_LT; break; case NODE_LE: op = OP_LE; break; case NODE_GT: op = OP_GT; break; case NODE_GE: op = OP_GE; break; default: assert(0); } mod_push_instr(compiler->mod, op, RZ_NO_PARAM); } break; case NODE_ADD: case NODE_SUB: case NODE_MUL: case NODE_DIV: case NODE_MODULO: case NODE_POW: { for (size_t i=0; ichildren.size; i++) { compiler_run(compiler, node_child(node, i)); } Opcode op; if (node->type == NODE_SUB && node->children.size == 1) { op = OP_USUB; } else { switch (node->type) { case NODE_ADD: op = OP_ADD; break; case NODE_SUB: op = OP_SUB; break; case NODE_MUL: op = OP_MUL; break; case NODE_DIV: op = OP_DIV; break; case NODE_MODULO: op = OP_MODULO; break; case NODE_POW: op = OP_POW; break; default: assert(0); } } mod_push_instr(compiler->mod, op, RZ_NO_PARAM); } break; default: { fprintf(stderr, "Cannot compile unknown node '%s'", NodeTypeStr[node->type]); abort(); } break; } }