#include "macro.hpp" #include "src/Compiler.hpp" namespace fkstd { void set_addr(Compiler& compiler, std::shared_ptr node, std::shared_ptr program) { auto ident = node->child(1)->repr(); compiler.compile_prog(node->child(2), program); auto entry = compiler.sym()->find(ident); if (entry) { program->add(OP_STORE_LOCAL, entry->addr()); } else { auto entry = compiler.sym()->find_global(ident); program->add(OP_STORE_CLOSURE, entry->addr()); } } void assert_static_fail(Compiler& compiler, std::shared_ptr node, std::shared_ptr program) { try { compiler.compile_prog(node->child(1), program); } catch(std::exception const&) { program->load_const(std::make_shared(TYPE_BOOL, true, node->loc())); return; } std::stringstream ss; ss << "assertion failed"; node->loc().error(LOG_ERROR, ss.str()); } void decl(Compiler& compiler, std::shared_ptr node, std::shared_ptr program) { static addr_t addr = 0; addr++; std::string ident = node->child(1)->repr(); auto rhs = node->child(2); compiler.push_decl(ident); compiler.compile_prog(rhs, program); compiler.pop_decl(); auto entry = compiler.sym()->declare_local(ident, node->loc()) .set_node(rhs); program->add(OP_STORE_LOCAL, entry.addr()); } void block(Compiler& compiler, std::shared_ptr node, std::shared_ptr program) { compiler.sym()->enter_scope(); for (size_t i=1; isize(); i++) { compiler.compile_prog(node->child(i), program); if (i != node->size() - 1) { program->add(OP_POP); } } compiler.sym()->leave_scope(); } void if_macro(Compiler& compiler, std::shared_ptr node, std::shared_ptr 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()); } void and_macro(Compiler& compiler, std::shared_ptr node, std::shared_ptr program) { std::vector to_false; for (size_t i=1; isize(); 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(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(TYPE_BOOL, false, node->loc())); program->set_param(out_addr, program->size()); } void or_macro(Compiler& compiler, std::shared_ptr node, std::shared_ptr program) { std::vector to_true; for (size_t i=1; isize(); 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(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(TYPE_BOOL, true, node->loc())); program->set_param(out_addr, program->size()); } }