2023-09-17 19:36:58 +00:00
|
|
|
#include "Compiler.hpp"
|
|
|
|
#include "src/Node.hpp"
|
|
|
|
#include "src/Program.hpp"
|
|
|
|
|
|
|
|
namespace zn
|
|
|
|
{
|
2023-09-18 15:33:04 +00:00
|
|
|
/*explicit*/ Compiler::Compiler(Logger& logger, SymTable& sym)
|
2023-09-17 19:36:58 +00:00
|
|
|
: m_logger { logger }
|
2023-09-18 15:33:04 +00:00
|
|
|
, m_sym { sym }
|
2023-09-17 19:36:58 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*virtual*/ Compiler::~Compiler()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Compiler::compile(Node const& node, Program& program)
|
|
|
|
{
|
|
|
|
switch (node.type())
|
|
|
|
{
|
2023-09-18 15:33:04 +00:00
|
|
|
// MODULES
|
|
|
|
// =======
|
2023-09-17 19:36:58 +00:00
|
|
|
case NODE_MODULE: {
|
|
|
|
for (size_t i=0; i<node.size(); i++)
|
|
|
|
{
|
|
|
|
compile(*node.child_at(i), program);
|
|
|
|
program.append(OPCODE_POP);
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2023-09-18 15:33:04 +00:00
|
|
|
// FUNCTION STUFF
|
|
|
|
// ==============
|
|
|
|
case NODE_CALL: {
|
|
|
|
for (size_t i=0; i<node.size(); i++)
|
|
|
|
{
|
|
|
|
compile(*node.child_at(i), program);
|
|
|
|
}
|
|
|
|
|
|
|
|
program.append(OPCODE_CALL_NATIVE, node.size() - 1);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
// VALUES
|
|
|
|
// ======
|
|
|
|
case NODE_IDENT: {
|
|
|
|
std::string ident = node.repr();
|
|
|
|
auto sym = m_sym.find(ident);
|
|
|
|
assert(sym);
|
|
|
|
|
|
|
|
if (sym->prototype)
|
|
|
|
{
|
|
|
|
auto ref = std::make_shared<Constant>(TYPE_REF,
|
|
|
|
node.loc(),
|
|
|
|
(int) sym->addr);
|
|
|
|
size_t val = program.add_constant(ref);
|
|
|
|
program.append(OPCODE_LOAD_CONST, val);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
program.append(OPCODE_LOAD_LOCAL, sym->addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
} break;
|
|
|
|
|
2023-09-17 19:36:58 +00:00
|
|
|
case NODE_INT: {
|
|
|
|
size_t addr = program
|
|
|
|
.add_constant(std::make_shared<Constant>
|
2023-09-18 15:33:04 +00:00
|
|
|
(TYPE_INT, node.loc(),
|
|
|
|
std::stoi(node.repr())));
|
2023-09-17 19:36:58 +00:00
|
|
|
program.append(OPCODE_LOAD_CONST, addr);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
default: {
|
|
|
|
std::cerr << "cannot compile node '"
|
|
|
|
<< node.string() << "'" << std::endl;
|
|
|
|
abort();
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|