2023-09-20 19:21:51 +00:00
|
|
|
#include "macro.hpp"
|
2023-09-21 19:17:39 +00:00
|
|
|
#include "src/Compiler.hpp"
|
2023-09-20 19:21:51 +00:00
|
|
|
|
|
|
|
namespace fkstd
|
|
|
|
{
|
2023-09-22 12:17:21 +00:00
|
|
|
void set_addr(Compiler& compiler,
|
|
|
|
std::shared_ptr<Node> node,
|
|
|
|
std::shared_ptr<Program> program)
|
|
|
|
{
|
|
|
|
auto ident = node->child(1)->repr();
|
|
|
|
compiler.compile_prog(node->child(2), program);
|
2023-09-22 20:04:57 +00:00
|
|
|
std::cout << "push " << node->child(2)->string() << std::endl;
|
2023-09-22 12:17:21 +00:00
|
|
|
auto entry = compiler.sym()->find(ident);
|
2023-09-22 20:04:57 +00:00
|
|
|
|
|
|
|
if (entry)
|
|
|
|
{
|
|
|
|
program->add(OP_STORE_LOCAL, entry->addr());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto entry = compiler.sym()->find_global(ident);
|
|
|
|
program->add(OP_STORE_CLOSURE, entry->addr());
|
|
|
|
}
|
2023-09-22 12:17:21 +00:00
|
|
|
}
|
|
|
|
|
2023-09-20 19:21:51 +00:00
|
|
|
void assert_static_fail(Compiler& compiler,
|
|
|
|
std::shared_ptr<Node> node,
|
|
|
|
std::shared_ptr<Program> program)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
compiler.compile_prog(node->child(1), program);
|
|
|
|
}
|
|
|
|
catch(std::exception const&)
|
|
|
|
{
|
|
|
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
|
|
|
true,
|
|
|
|
node->loc()));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << "assertion failed";
|
|
|
|
node->loc().error<assert_error>(LOG_ERROR, ss.str());
|
|
|
|
}
|
2023-09-21 13:59:46 +00:00
|
|
|
|
|
|
|
void decl(Compiler& compiler,
|
|
|
|
std::shared_ptr<Node> node,
|
|
|
|
std::shared_ptr<Program> program)
|
|
|
|
{
|
|
|
|
static addr_t addr = 0;
|
|
|
|
addr++;
|
|
|
|
|
|
|
|
std::string ident = node->child(1)->repr();
|
|
|
|
auto rhs = node->child(2);
|
|
|
|
|
2023-09-22 07:49:28 +00:00
|
|
|
compiler.push_decl(ident);
|
2023-09-21 13:59:46 +00:00
|
|
|
compiler.compile_prog(rhs, program);
|
2023-09-22 07:49:28 +00:00
|
|
|
compiler.pop_decl();
|
2023-09-21 13:59:46 +00:00
|
|
|
|
2023-09-21 19:17:39 +00:00
|
|
|
auto entry = compiler.sym()->declare_local(ident,
|
|
|
|
addr,
|
|
|
|
node->loc())
|
|
|
|
.set_node(rhs);
|
2023-09-21 13:59:46 +00:00
|
|
|
|
|
|
|
program->add(OP_STORE_LOCAL, addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void block(Compiler& compiler,
|
|
|
|
std::shared_ptr<Node> node,
|
|
|
|
std::shared_ptr<Program> program)
|
|
|
|
{
|
|
|
|
compiler.sym()->enter_scope();
|
|
|
|
|
|
|
|
for (size_t i=1; i<node->size(); i++)
|
|
|
|
{
|
|
|
|
compiler.compile_prog(node->child(i), program);
|
|
|
|
|
|
|
|
if (i != node->size() - 1)
|
|
|
|
{
|
|
|
|
program->add(OP_POP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
compiler.sym()->leave_scope();
|
|
|
|
}
|
2023-09-21 21:30:51 +00:00
|
|
|
|
|
|
|
void if_macro(Compiler& compiler,
|
|
|
|
std::shared_ptr<Node> node,
|
|
|
|
std::shared_ptr<Program> program)
|
|
|
|
{
|
|
|
|
auto if_expr = node->child(1);
|
|
|
|
auto then_expr = node->child(2);
|
|
|
|
auto else_expr = node->child(3);
|
|
|
|
|
|
|
|
compiler.compile_prog(if_expr, program);
|
|
|
|
size_t to_else = program->add(OP_BNE, 0 /*else*/);
|
|
|
|
|
|
|
|
compiler.compile_prog(then_expr, program);
|
|
|
|
size_t to_end = program->add(OP_BR, 0 /* end */);
|
|
|
|
|
|
|
|
program->set_param(to_else, program->size());
|
|
|
|
compiler.compile_prog(else_expr, program);
|
|
|
|
program->set_param(to_end, program->size());
|
|
|
|
}
|
2023-09-24 11:03:33 +00:00
|
|
|
|
|
|
|
void and_macro(Compiler& compiler,
|
|
|
|
std::shared_ptr<Node> node,
|
|
|
|
std::shared_ptr<Program> program)
|
|
|
|
{
|
|
|
|
std::vector<size_t> to_false;
|
|
|
|
|
|
|
|
for (size_t i=1; i<node->size(); i++)
|
|
|
|
{
|
|
|
|
compiler.compile_prog(node->child(i), program);
|
|
|
|
size_t addr = program->add(OP_BNE, 0 /* to end*/);
|
|
|
|
to_false.push_back(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
|
|
|
true,
|
|
|
|
node->loc()));
|
|
|
|
|
|
|
|
size_t out_addr = program->add(OP_BR, 0 /* to end*/);
|
|
|
|
|
|
|
|
for (auto addr: to_false)
|
|
|
|
{
|
|
|
|
program->set_param(addr, program->size());
|
|
|
|
}
|
|
|
|
|
|
|
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
|
|
|
false,
|
|
|
|
node->loc()));
|
|
|
|
|
|
|
|
program->set_param(out_addr, program->size());
|
|
|
|
}
|
|
|
|
|
|
|
|
void or_macro(Compiler& compiler,
|
|
|
|
std::shared_ptr<Node> node,
|
|
|
|
std::shared_ptr<Program> program)
|
|
|
|
{
|
|
|
|
std::vector<size_t> to_true;
|
|
|
|
|
|
|
|
for (size_t i=1; i<node->size(); i++)
|
|
|
|
{
|
|
|
|
compiler.compile_prog(node->child(i), program);
|
|
|
|
program->add(OP_NOT);
|
|
|
|
size_t addr = program->add(OP_BNE, 0 /* to end*/);
|
|
|
|
to_true.push_back(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
|
|
|
false,
|
|
|
|
node->loc()));
|
|
|
|
|
|
|
|
size_t out_addr = program->add(OP_BR, 0 /* to end*/);
|
|
|
|
|
|
|
|
for (auto addr: to_true)
|
|
|
|
{
|
|
|
|
program->set_param(addr, program->size());
|
|
|
|
}
|
|
|
|
|
|
|
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
|
|
|
true,
|
|
|
|
node->loc()));
|
|
|
|
|
|
|
|
program->set_param(out_addr, program->size());
|
|
|
|
}
|
2023-09-20 19:21:51 +00:00
|
|
|
}
|