#include "Compiler.hpp" #include "lib/Opcodes.hpp" #include "Code.hpp" namespace jk { /*explicit*/ Compiler::Compiler(std::shared_ptr sym, Logger& logger) : m_sym { sym } , m_logger(logger) { } /*virtual*/ Compiler::~Compiler() { } void Compiler::compile(std::shared_ptr node, std::shared_ptr program) { switch (node->type()) { case NODE_PROG: { for (size_t i=0; isize(); i++) { compile(node->child(i).lock(), program); } } break; case NODE_FUNCALL: { for (size_t i=0; isize(); i++) { compile(node->child(i).lock(), program); } program->push_instr(OPCODE_CALL, node->size() - 1); } break; case NODE_VARDECL: { std::string ident = node->child(0).lock()->repr(); auto entry = m_sym->find(ident); assert(entry); compile(node->child(1).lock(), program); program->push_instr(OPCODE_STORE, entry->addr); } break; case NODE_IDENT: { std::string ident = node->repr(); auto sym = m_sym->find(ident); assert(sym); OpcodeType op_load = OPCODE_LOAD; if (sym->is_global) { op_load = OPCODE_LOAD_GLOBAL; } program->push_instr(op_load, sym->addr); } break; case NODE_INT: { auto value = Value::make_int(std::stoi(node->repr())); size_t addr = program->push_constant(value); program->push_instr(OPCODE_PUSH_CONST, addr); } break; default: std::cerr << "cannot compile unknown node '" << NodeTypeStr[node->type()] << "'" << std::endl; abort(); } } }