#include "compiler.h" void compiler_init(struct compiler* self, struct status* status) { assert(self); self->status = status; } void compiler_free(struct compiler* self) { assert(self); } void compiler_compile(struct compiler* self, struct node* node, struct prog* prog, struct symtable* symtable) { assert(self); assert(node); assert(prog); switch (node->kind) { case NODE_ROOT: { for (size_t i=0; ichildren.size; i++) { struct node* child = node->children.data[i]; compiler_compile(self, child, prog, symtable); } } break; case NODE_CALL: { for (size_t i=0; ichildren.size - 1; i++) { // size_t k = node->children.size - 1 - i; // struct node* child = node->children.data[k]; // compiler_compile(self, child, prog, symtable); size_t k = node->children.size - 1 - i; struct node* child = node->children.data[k]; struct value* val = malloc(sizeof(struct value)); value_init_lazy(val, child, child->line); size_t addr = prog_add_new_value(prog, val); prog_add_instruction(prog, OP_PUSH, addr); } struct node* child = node->children.data[0]; compiler_compile(self, child, prog, symtable); prog_add_instruction(prog, OP_CALL, node->children.size - 1); } break; case NODE_INT: { struct value* value = malloc(sizeof(struct value)); int val = atoi(node->token->value); value_init_int(value, val, node->line); ssize_t addr = prog_add_new_value(prog, value); prog_add_instruction(prog, OP_PUSH, addr); } break; case NODE_FLOAT: { struct value* value = malloc(sizeof(struct value)); float val = atof(node->token->value); value_init_float(value, val, node->line); ssize_t addr = prog_add_new_value(prog, value); prog_add_instruction(prog, OP_PUSH, addr); } break; case NODE_BOOL: { struct value* value = malloc(sizeof(struct value)); bool val = strcmp("true", node->token->value) == 0; value_init_bool(value, val, node->line); ssize_t addr = prog_add_new_value(prog, value); prog_add_instruction(prog, OP_PUSH, addr); } break; case NODE_STRING: { struct value* value = malloc(sizeof(struct value)); value_init_string(value, node->token->value, node->line); ssize_t addr = prog_add_new_value(prog, value); prog_add_instruction(prog, OP_PUSH, addr); } break; case NODE_SYMBOL: { struct value* value = malloc(sizeof(struct value)); value_init_symbol(value, node->token->value, node->line); ssize_t addr = prog_add_new_value(prog, value); prog_add_instruction(prog, OP_PUSH, addr); } break; case NODE_IDENT: { struct entry const* entry = symtable_try_get(symtable, node->token->value); if (!entry) { status_push(self->status, STATUS_ERROR, node->line, "undefined <%s>", node->token->value); return; } if (entry->is_local) { prog_add_instruction(prog, OP_LOCAL_LOAD, entry->addr); } else { prog_add_instruction(prog, OP_GLOBAL_LOAD, entry->addr); } } break; default: { fprintf(stderr, "cannot compile node %s\n", NodeKindStr[node->kind]); abort(); } break; } }