#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_IDENT: { std::string ident = node->repr(); auto sym = m_sym->find(ident); if (!sym) { m_logger.log(LOG_ERROR, node->loc(), std::string() + "'" + ident + "' is undefined"); } OpcodeType op_load = OPCODE_LOAD; if (sym->is_global) { op_load = OPCODE_LOAD_GLOBAL; } if (sym->type->type() == TYPE_FUNCTION) { 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(); } } }