fakir/src/Compiler.cpp

103 lines
2.7 KiB
C++
Raw Normal View History

#include "Compiler.hpp"
namespace fk
{
2023-09-20 15:17:13 +00:00
/*explicit*/ Compiler::Compiler(std::shared_ptr<SymTable> sym)
: m_sym { sym }
{
}
/*virtual*/ Compiler::~Compiler()
{
}
std::shared_ptr<Program> Compiler::compile(std::shared_ptr<Node> node)
{
auto prog = std::make_shared<Program>();
2023-09-20 15:17:13 +00:00
compile_prog(node, prog);
return prog;
}
2023-09-20 15:17:13 +00:00
void Compiler::compile_prog(std::shared_ptr<Node> node,
std::shared_ptr<Program> prog)
{
switch (node->type())
{
case NODE_MODULE: {
for (size_t i=0; i<node->size(); i++)
{
2023-09-20 15:17:13 +00:00
compile_prog(node->child(i), prog);
prog->add(OP_POP);
}
} break;
2023-09-20 15:17:13 +00:00
case NODE_CALL: {
std::string ident = node->child(0)->repr();
for (size_t i=0; i<node->size(); 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<compile_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<Constant>(TYPE_INT,
stoi(node->repr()),
node->loc()));
} break;
case NODE_FLOAT: {
prog->load_const(std::make_shared<Constant>(TYPE_FLOAT,
stof(node->repr()),
node->loc()));
} break;
case NODE_BOOL: {
prog->load_const(std::make_shared<Constant>(TYPE_BOOL,
node->repr() == "true",
node->loc()));
} break;
case NODE_STRING: {
std::string str = node->repr();
prog->load_const(std::make_shared<Constant>(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<compile_error>(LOG_ERROR, ss.str());
} break;
}
}
}