2023-09-20 15:17:13 +00:00
|
|
|
#include "fun.hpp"
|
|
|
|
|
2023-09-21 21:30:51 +00:00
|
|
|
#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)
|
|
|
|
|
|
|
|
|
2023-09-20 15:17:13 +00:00
|
|
|
namespace fkstd
|
|
|
|
{
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET assert_eq(Loc loc, Module&, STDARGS args)
|
2023-09-20 19:21:51 +00:00
|
|
|
{
|
|
|
|
auto oracle = args[0];
|
|
|
|
auto expr = args[1];
|
|
|
|
|
|
|
|
if (!oracle->equals(*expr))
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << "assertion failed: expected '"
|
|
|
|
<< oracle->string()
|
|
|
|
<< "', got '"
|
|
|
|
<< expr->string()
|
|
|
|
<< "'";
|
|
|
|
|
2023-09-21 20:26:13 +00:00
|
|
|
loc.error<assert_error>(LOG_ERROR, ss.str());
|
2023-09-20 19:21:51 +00:00
|
|
|
}
|
|
|
|
|
2023-09-21 20:26:13 +00:00
|
|
|
return std::make_shared<Constant>(TYPE_BOOL, true, loc);
|
2023-09-20 19:21:51 +00:00
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET println(Loc loc, Module&, STDARGS args)
|
2023-09-20 15:17:13 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2023-09-21 20:26:13 +00:00
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET add_int(Loc loc, Module&, STDARGS args)
|
2023-09-21 20:26:13 +00:00
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
|
|
|
|
for (auto arg: args)
|
|
|
|
{
|
|
|
|
result += std::get<int>(arg->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_INT, result, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET sub_int(Loc loc, Module&, STDARGS args)
|
2023-09-21 20:26:13 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET mul_int(Loc loc, Module&, STDARGS args)
|
2023-09-21 20:26:13 +00:00
|
|
|
{
|
|
|
|
int result = 1;
|
|
|
|
|
|
|
|
for (auto arg: args)
|
|
|
|
{
|
|
|
|
result *= std::get<int>(arg->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_INT, result, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET div_int(Loc loc, Module&, STDARGS args)
|
2023-09-21 20:26:13 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET mod_int(Loc loc, Module&, STDARGS args)
|
2023-09-21 20:26:13 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET pow_int(Loc loc, Module&, STDARGS args)
|
2023-09-21 20:26:13 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2023-09-21 21:30:51 +00:00
|
|
|
|
2023-09-24 12:43:12 +00:00
|
|
|
STDRET add_float(Loc loc, Module&, STDARGS args)
|
2023-09-24 12:22:01 +00:00
|
|
|
{
|
|
|
|
if (args.empty())
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, 0.0f, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
float result = std::get<float>(args[0]->value());
|
|
|
|
|
|
|
|
for (size_t i=1; i<args.size(); i++)
|
|
|
|
{
|
|
|
|
result = result + std::get<float>(args[i]->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-24 12:43:12 +00:00
|
|
|
STDRET sub_float(Loc loc, Module&, STDARGS args)
|
2023-09-24 12:22:01 +00:00
|
|
|
{
|
|
|
|
if (args.empty())
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, 0.0f, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
float result = std::get<float>(args[0]->value());
|
|
|
|
|
|
|
|
for (size_t i=1; i<args.size(); i++)
|
|
|
|
{
|
|
|
|
result = result - std::get<float>(args[i]->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.size() == 1)
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, -result, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-24 12:43:12 +00:00
|
|
|
STDRET mul_float(Loc loc, Module&, STDARGS args)
|
2023-09-24 12:22:01 +00:00
|
|
|
{
|
|
|
|
if (args.empty())
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
float result = std::get<float>(args[0]->value());
|
|
|
|
|
|
|
|
for (size_t i=1; i<args.size(); i++)
|
|
|
|
{
|
|
|
|
result = result * std::get<float>(args[i]->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-24 12:43:12 +00:00
|
|
|
STDRET div_float(Loc loc, Module&, STDARGS args)
|
2023-09-24 12:22:01 +00:00
|
|
|
{
|
|
|
|
if (args.empty())
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
float result = std::get<float>(args[0]->value());
|
|
|
|
|
|
|
|
for (size_t i=1; i<args.size(); i++)
|
|
|
|
{
|
|
|
|
result = result / std::get<float>(args[i]->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.size() == 1)
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f/result, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-24 12:43:12 +00:00
|
|
|
STDRET mod_float(Loc loc, Module&, STDARGS args)
|
2023-09-24 12:22:01 +00:00
|
|
|
{
|
|
|
|
if (args.empty())
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
float result = std::get<float>(args[0]->value());
|
|
|
|
|
|
|
|
for (size_t i=1; i<args.size(); i++)
|
|
|
|
{
|
|
|
|
result = std::fmod(result, std::get<float>(args[i]->value()));
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-24 12:43:12 +00:00
|
|
|
STDRET pow_float(Loc loc, Module&, STDARGS args)
|
2023-09-24 12:22:01 +00:00
|
|
|
{
|
|
|
|
if (args.empty())
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
float result = std::get<float>(args[0]->value());
|
|
|
|
|
|
|
|
for (size_t i=1; i<args.size(); i++)
|
|
|
|
{
|
|
|
|
result = std::pow(result, std::get<float>(args[i]->value()));
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-25 19:28:57 +00:00
|
|
|
STDRET trunc(Loc loc, Module&, STDARGS args)
|
|
|
|
{
|
|
|
|
float val = std::get<float>(args[0]->value());
|
|
|
|
int res = val;
|
|
|
|
return std::make_shared<Constant>(TYPE_INT, res, loc);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET lt(Loc loc, Module&, STDARGS args)
|
2023-09-21 21:30:51 +00:00
|
|
|
{
|
|
|
|
NUM_BINOP(<);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET le(Loc loc, Module&, STDARGS args)
|
2023-09-21 21:30:51 +00:00
|
|
|
{
|
|
|
|
NUM_BINOP(<=);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET gt(Loc loc, Module&, STDARGS args)
|
2023-09-21 21:30:51 +00:00
|
|
|
{
|
|
|
|
NUM_BINOP(>);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET ge(Loc loc, Module&, STDARGS args)
|
2023-09-21 21:30:51 +00:00
|
|
|
{
|
|
|
|
NUM_BINOP(>=);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET eq(Loc loc, Module&, STDARGS args)
|
2023-09-21 21:30:51 +00:00
|
|
|
{
|
|
|
|
NUM_BINOP(==);
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:17:21 +00:00
|
|
|
STDRET ne(Loc loc, Module&, STDARGS args)
|
2023-09-21 21:30:51 +00:00
|
|
|
{
|
|
|
|
NUM_BINOP(!=);
|
|
|
|
}
|
2023-09-24 10:17:42 +00:00
|
|
|
|
2023-09-24 11:03:33 +00:00
|
|
|
STDRET bool_not(Loc loc, Module&, STDARGS args)
|
|
|
|
{
|
|
|
|
bool val = std::get<bool>(args[0]->value());
|
|
|
|
return std::make_shared<Constant>(TYPE_BOOL, !val, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
STDRET array_ref(Loc, Module& mod, STDARGS args)
|
2023-09-24 10:17:42 +00:00
|
|
|
{
|
|
|
|
auto ref_val = args[0]->value();
|
|
|
|
size_t ref = std::get<size_t>(ref_val);
|
|
|
|
|
|
|
|
std::shared_ptr<Array> val =
|
|
|
|
std::get<std::shared_ptr<Array>>(mod.vm()->load_global(ref));
|
|
|
|
|
|
|
|
for (size_t i=1; i<args.size() - 1; i++)
|
|
|
|
{
|
|
|
|
int k = std::get<int>(args[i]->value());
|
|
|
|
|
|
|
|
auto ref_val = val->at(k)->value();
|
|
|
|
size_t ref = std::get<size_t>(ref_val);
|
|
|
|
|
|
|
|
auto arr =
|
|
|
|
std::get<std::shared_ptr<Array>>(mod.vm()->load_global(ref));
|
|
|
|
|
|
|
|
val = arr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return val->at(std::get<int>(args.back()->value()));
|
|
|
|
}
|
2023-09-24 12:43:12 +00:00
|
|
|
|
2023-09-24 13:54:57 +00:00
|
|
|
STDRET array_set(Loc, Module& mod, STDARGS args)
|
|
|
|
{
|
|
|
|
auto ref_val = args[0]->value();
|
|
|
|
size_t ref = std::get<size_t>(ref_val);
|
|
|
|
|
|
|
|
int index = std::get<int>(args[1]->value());
|
|
|
|
|
|
|
|
std::shared_ptr<Array> val =
|
|
|
|
std::get<std::shared_ptr<Array>>(mod.vm()->load_global(ref));
|
|
|
|
|
|
|
|
val->set(index, args[2]);
|
|
|
|
return args[2];
|
|
|
|
}
|
|
|
|
|
2023-09-24 12:43:12 +00:00
|
|
|
STDRET string_cat(Loc loc, Module&, STDARGS args)
|
|
|
|
{
|
|
|
|
if (args.empty())
|
|
|
|
{
|
|
|
|
return std::make_shared<Constant>(TYPE_STRING, "", loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string value = std::get<std::string>(args[0]->value());
|
|
|
|
|
|
|
|
for (size_t i=1; i<args.size(); i++)
|
|
|
|
{
|
|
|
|
value += std::get<std::string>(args[i]->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_STRING, value, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
STDRET string_dup(Loc loc, Module&, STDARGS args)
|
|
|
|
{
|
|
|
|
std::string str = std::get<std::string>(args[0]->value());
|
|
|
|
int n = std::get<int>(args[1]->value());
|
|
|
|
std::string res;
|
|
|
|
|
|
|
|
for (int i=0; i<n; i++)
|
|
|
|
{
|
|
|
|
res += str;
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_STRING, res, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
STDRET char_at(Loc loc, Module&, STDARGS args)
|
|
|
|
{
|
|
|
|
std::string str = std::get<std::string>(args[0]->value());
|
|
|
|
int n = std::get<int>(args[1]->value());
|
|
|
|
|
|
|
|
return std::make_shared<Constant>(TYPE_STRING,
|
|
|
|
std::string(1, str[n]),
|
|
|
|
loc);
|
|
|
|
}
|
2023-09-20 15:17:13 +00:00
|
|
|
}
|