233 lines
4.5 KiB
C++
233 lines
4.5 KiB
C++
#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; i<args.size(); i++)
|
|
{
|
|
result -= args[i]->as_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; i<args.size(); i++)
|
|
{
|
|
result /= args[i]->as_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; i<args.size(); i++)
|
|
{
|
|
result %= args[i]->as_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; i<args.size(); i++)
|
|
{
|
|
result = std::pow(result, args[i]->as_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<assertion_error>(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; i<args.size(); i++)
|
|
{
|
|
auto rhs = args[i];
|
|
|
|
if (!lhs->equals(*rhs))
|
|
{
|
|
grino::Logger logger;
|
|
std::stringstream ss;
|
|
|
|
ss << "'" << lhs->string() << "' is not equals to '"
|
|
<< rhs->string() << "'";
|
|
|
|
logger.log<assertion_error>(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; i<args.size(); i++)
|
|
{
|
|
auto rhs = args[i];
|
|
|
|
if (!lhs->equals(*rhs))
|
|
{
|
|
return grino::Value::make_bool(rhs->loc(), false);
|
|
}
|
|
}
|
|
|
|
return grino::Value::make_bool(args.front()->loc(), true);
|
|
});
|
|
}
|