fakir/libstd/fun.cpp

199 lines
4.6 KiB
C++

#include "fun.hpp"
#define NUM_BINOP(OP)\
auto lhs = args[0]; \
auto rhs = args[1]; \
bool res = false; \
\
if (lhs->type() == TYPE_INT) \
{ \
res = std::get<int>(lhs->value()) OP std::get<int>(rhs->value()); \
} \
\
if (lhs->type() == TYPE_FLOAT) \
{ \
res = std::get<float>(lhs->value()) OP std::get<float>(rhs->value()); \
} \
\
return std::make_shared<Constant>(TYPE_BOOL, res, loc)
namespace fkstd
{
STDRET assert_eq(Loc loc, STDARGS args)
{
auto oracle = args[0];
auto expr = args[1];
if (!oracle->equals(*expr))
{
std::stringstream ss;
ss << "assertion failed: expected '"
<< oracle->string()
<< "', got '"
<< expr->string()
<< "'";
loc.error<assert_error>(LOG_ERROR, ss.str());
}
return std::make_shared<Constant>(TYPE_BOOL, true, loc);
}
STDRET println(Loc loc, STDARGS args)
{
std::string sep;
for (auto arg: args)
{
std::cout << sep << arg->string();
sep = " ";
}
if (args.size() > 0)
{
loc = args.front()->loc();
}
std::cout << std::endl;
return std::make_shared<Constant>(TYPE_INT, 0, loc);
}
STDRET add_int(Loc loc, STDARGS args)
{
int result = 0;
for (auto arg: args)
{
result += std::get<int>(arg->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET sub_int(Loc loc, STDARGS args)
{
if (args.empty())
{
return std::make_shared<Constant>(TYPE_INT, 0, loc);
}
if (args.size() == 1)
{
return std::make_shared<Constant>(TYPE_INT,
-std::get<int>(args[0]->value()),
loc);
}
int result = std::get<int>(args[0]->value());
for (size_t i=1; i<args.size(); i++)
{
result -= std::get<int>(args[i]->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET mul_int(Loc loc, STDARGS args)
{
int result = 1;
for (auto arg: args)
{
result *= std::get<int>(arg->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET div_int(Loc loc, STDARGS args)
{
if (args.empty())
{
return std::make_shared<Constant>(TYPE_INT, 1, loc);
}
if (args.size() == 1)
{
return std::make_shared<Constant>(TYPE_INT,
1/std::get<int>(args[0]->value()),
loc);
}
int result = std::get<int>(args[0]->value());
for (size_t i=1; i<args.size(); i++)
{
result /= std::get<int>(args[i]->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET mod_int(Loc loc, STDARGS args)
{
if (args.empty())
{
return std::make_shared<Constant>(TYPE_INT, 1, loc);
}
int result = std::get<int>(args[0]->value());
for (size_t i=1; i<args.size(); i++)
{
result %= std::get<int>(args[i]->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET pow_int(Loc loc, STDARGS args)
{
if (args.empty())
{
return std::make_shared<Constant>(TYPE_INT, 1, loc);
}
int result = std::get<int>(args[0]->value());
for (size_t i=1; i<args.size(); i++)
{
result = std::pow(result, std::get<int>(args[i]->value()));
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET lt(Loc loc, STDARGS args)
{
NUM_BINOP(<);
}
STDRET le(Loc loc, STDARGS args)
{
NUM_BINOP(<=);
}
STDRET gt(Loc loc, STDARGS args)
{
NUM_BINOP(>);
}
STDRET ge(Loc loc, STDARGS args)
{
NUM_BINOP(>=);
}
STDRET eq(Loc loc, STDARGS args)
{
NUM_BINOP(==);
}
STDRET ne(Loc loc, STDARGS args)
{
NUM_BINOP(!=);
}
}