#include "../src/Loader.hpp" #include "src/Logger.hpp" GRINO_ERROR(assertion_error); extern "C" void lib_int(grino::Loader& loader) { loader.add_native("+", [](auto args){ int result = 0; for (auto value: args) { result += value->as_int(); } grino::Loc loc {"???", 0}; if (args.empty() == false) { loc = args.front()->loc(); } return grino::Value::make_int(loc, result); }); loader.add_native("*", [](auto args){ int result = 1; for (auto value: args) { result *= value->as_int(); } grino::Loc loc {"???", 0}; if (args.empty() == false) { loc = args.front()->loc(); } return grino::Value::make_int(loc, result); }); loader.add_native("-", [](auto args){ grino::Loc loc {"???", 0}; if (args.empty() == false) { loc = args.front()->loc(); } else { return grino::Value::make_int(loc, 0); } int result = args[0]->as_int(); if (args.size() == 1) { return grino::Value::make_int(loc, -result); } for (size_t i=1; ias_int(); } return grino::Value::make_int(loc, result); }); loader.add_native("/", [](auto args){ grino::Loc loc {"???", 0}; if (args.empty() == false) { loc = args.front()->loc(); } else { return grino::Value::make_int(loc, 1); } int result = args[0]->as_int(); if (args.size() == 1) { return grino::Value::make_int(loc, result); } for (size_t i=1; ias_int(); } return grino::Value::make_int(loc, result); }); loader.add_native("%", [](auto args){ grino::Loc loc {"???", 0}; if (args.empty() == false) { loc = args.front()->loc(); } else { return grino::Value::make_int(loc, 1); } int result = args[0]->as_int(); if (args.size() == 1) { return grino::Value::make_int(loc, result); } for (size_t i=1; ias_int(); } return grino::Value::make_int(loc, result); }); loader.add_native("^", [](auto args){ grino::Loc loc {"???", 0}; if (args.empty() == false) { loc = args.front()->loc(); } else { return grino::Value::make_int(loc, 1); } int result = args[0]->as_int(); if (args.size() == 1) { return grino::Value::make_int(loc, result); } for (size_t i=1; ias_int()); } return grino::Value::make_int(loc, result); }); } extern "C" void lib_assert(grino::Loader& loader) { loader.add_native("assert", [](auto args){ for (auto value: args) { if (!value->as_bool()) { grino::Logger logger; logger.log(grino::LOG_ASSERT, value->loc(), "assertion failed"); } } return grino::Value::make_bool(args.front()->loc(), true); }); loader.add_native("assert-eq?", [](auto args){ auto lhs = args.front(); for (size_t i=1; iequals(*rhs)) { grino::Logger logger; std::stringstream ss; ss << "'" << lhs->string() << "' is not equals to '" << rhs->string() << "'"; logger.log(grino::LOG_ASSERT, lhs->loc(), ss.str()); } } return grino::Value::make_bool(args.front()->loc(), true); }); } extern "C" void lib(grino::Loader& loader) { lib_assert(loader); lib_int(loader); loader.add_native("dump", [](auto args){ std::string sep; std::stringstream ss; for (auto arg: args) { ss << sep << arg->string(); sep = " "; } std::cout << ss.str() << std::endl; return grino::Value::make_nil(args.back()->loc()); }); loader.add_native("eq?", [](auto args){ auto lhs = args.front(); for (size_t i=1; iequals(*rhs)) { return grino::Value::make_bool(rhs->loc(), false); } } return grino::Value::make_bool(args.front()->loc(), true); }); }