#include "Compiler.hpp" namespace fk { /*explicit*/ Compiler::Compiler(std::shared_ptr sym) : m_sym { sym } { } /*virtual*/ Compiler::~Compiler() { } std::shared_ptr Compiler::compile(std::shared_ptr node) { auto prog = std::make_shared(); compile_prog(node, prog); return prog; } void Compiler::compile_prog(std::shared_ptr node, std::shared_ptr prog) { switch (node->type()) { case NODE_MODULE: { for (size_t i=0; isize(); i++) { compile_prog(node->child(i), prog); prog->add(OP_POP); } } break; case NODE_CALL: { std::string ident = node->child(0)->repr(); for (size_t i=0; isize(); i++) { compile_prog(node->child(i), prog); } prog->add(OP_CALL_NATIVE, node->size() - 1); } break; case NODE_IDENT: { auto entry = m_sym->find(node->repr()); if (!entry) { std::stringstream ss; ss << "'" << node->repr() << "' is undefined"; node->loc().error(LOG_ERROR, ss.str()); } if (!entry->is_global()) { throw std::runtime_error { "not implemented yet" }; } prog->add(OP_LOAD_GLOBAL, entry->addr()); } break; case NODE_INT: { prog->load_const(std::make_shared(TYPE_INT, stoi(node->repr()), node->loc())); } break; case NODE_FLOAT: { prog->load_const(std::make_shared(TYPE_FLOAT, stof(node->repr()), node->loc())); } break; case NODE_BOOL: { prog->load_const(std::make_shared(TYPE_BOOL, node->repr() == "true", node->loc())); } break; case NODE_STRING: { std::string str = node->repr(); prog->load_const(std::make_shared(TYPE_STRING, str.substr(1, str.size() - 2), node->loc())); } break; default: { std::stringstream ss; ss << "cannot compile expression '" << (NodeTypeStr[node->type()] + strlen("NODE_")) << "'"; node->loc().error(LOG_ERROR, ss.str()); } break; } } }