#include #include "lib/Function.hpp" #include "lib/Loader.hpp" #include "lib/Node.hpp" #include "lib/Opcodes.hpp" #include "lib/SymTable.hpp" #include "lib/Value.hpp" extern "C" void num_arith(jk::Loader& loader) { loader.declare("+", [](auto args){ int res = 0; for (auto arg: args) { res += arg->as_int(); } return jk::Value::make_int(res); }); loader.declare("-", [](auto args){ int res = args[0]->as_int(); for (size_t i=1; ias_int(); } return jk::Value::make_int(res); }); loader.declare("*", [](auto args){ int res = 1; for (auto arg: args) { res *= arg->as_int(); } return jk::Value::make_int(res); }); loader.declare("/", [](auto args){ int res = args[0]->as_int(); for (size_t i=1; ias_int(); } return jk::Value::make_int(res); }); loader.declare("^", [](auto args){ int res = args[0]->as_int(); for (size_t i=1; ias_int()); } return jk::Value::make_int(res); }); loader.declare("%", [](auto args){ int res = args[0]->as_int(); for (size_t i=1; ias_int(); } return jk::Value::make_int(res); }); } extern "C" void bool_arith(jk::Loader& loader) { loader.declare_static("and", [loader](std::shared_ptr node, std::shared_ptr program, std::shared_ptr sym) { std::vector to_false; for (size_t i=1; isize(); i++) { loader.compiler()->compile(node->child(i).lock(), program, sym); to_false.push_back(program->size()); program->push_instr(jk::OPCODE_BRF, 0); } program->push_instr(jk::OPCODE_PUSH_CONST, program->push_constant(jk::Value::make_bool(true))); size_t end = program->size(); program->push_instr(jk::OPCODE_BR, 0); for (auto addr: to_false) { program->set_param(addr, program->size()); } program->push_instr(jk::OPCODE_PUSH_CONST, program->push_constant(jk::Value::make_bool(false))); program->set_param(end, program->size()); }); loader.declare_static("or", [loader](std::shared_ptr node, std::shared_ptr program, std::shared_ptr sym) { std::vector to_false; for (size_t i=1; isize(); i++) { loader.compiler()->compile(node->child(i).lock(), program, sym); program->push_instr(jk::OPCODE_NOT); to_false.push_back(program->size()); program->push_instr(jk::OPCODE_BRF, 0); } program->push_instr(jk::OPCODE_PUSH_CONST, program->push_constant(jk::Value::make_bool(false))); size_t end = program->size(); program->push_instr(jk::OPCODE_BR, 0); for (auto addr: to_false) { program->set_param(addr, program->size()); } program->push_instr(jk::OPCODE_PUSH_CONST, program->push_constant(jk::Value::make_bool(true))); program->set_param(end, program->size()); }); loader.declare("not", [](auto args){ auto value = args[0]->as_bool(); return jk::Value::make_bool(!value); }); } extern "C" void lib(jk::Loader& loader) { num_arith(loader); bool_arith(loader); loader.declare("dump", [](auto args){ std::string sep; for (auto arg: args) { std::cout << sep << arg->string(); sep = " "; } if (args.empty() == false) { std::cout << std::endl; } return jk::Value::make_nil(); }); }