This repository has been archived on 2024-03-07. You can view files and clone it, but cannot push or open issues/pull-requests.
zarn/src/Compiler.cpp

130 lines
3.2 KiB
C++
Raw Normal View History

2023-09-17 19:36:58 +00:00
#include "Compiler.hpp"
#include "Node.hpp"
#include "Program.hpp"
#include "NativeMacro.hpp"
2023-09-17 19:36:58 +00:00
namespace zn
{
/*explicit*/ Compiler::Compiler(Logger& logger, SymTable& sym)
2023-09-17 19:36:58 +00:00
: m_logger { logger }
, m_sym { sym }
2023-09-17 19:36:58 +00:00
{
}
/*virtual*/ Compiler::~Compiler()
{
}
void Compiler::add_macro(std::shared_ptr<NativeMacro> macro)
{
m_macros.push_back(macro);
}
2023-09-17 19:36:58 +00:00
void Compiler::compile(Node const& node, Program& program)
{
switch (node.type())
{
// 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;
// FUNCTION STUFF
// ==============
case NODE_CALL: {
std::string ident = node.child_at(0)->repr();
auto sym = m_sym.find(ident);
if (sym)
{
for (size_t i=0; i<node.size(); i++)
{
compile(*node.child_at(i), program);
}
program.append(OPCODE_CALL_NATIVE, node.size() - 1);
}
else
{
bool found_macro = false;
for (auto macro: m_macros)
{
if (macro->name() == ident)
{
2023-09-18 17:32:16 +00:00
macro->execute(node, *this,
program, m_sym);
found_macro = true;
break;
}
}
if (!found_macro)
{
std::stringstream ss;
ss << "cannot call undefined function '"
<< ident
<< "'";
m_logger.log<compile_error>(LOG_ERROR,
node.loc(),
ss.str());
}
}
} break;
// VALUES
// ======
case NODE_IDENT: {
std::string ident = node.repr();
auto sym = m_sym.find(ident);
if (!sym)
{
std::stringstream ss;
ss << "cannot use undefined variable '"
<< ident
<< "'";
m_logger.log<compile_error>(LOG_ERROR,
node.loc(),
ss.str());
}
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>
(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;
}
}
}