#include <sstream> #include <memory> #include "pilang.hpp" using namespace Pilang3; class Std { public: static Variable exit(SharedEnvironment, Cmdargs& args) { throw exceptions::exit(std::get<integer_type>(args[0].data)); } static Variable retval(SharedEnvironment, Cmdargs& args) { return Variable({ Variable::id_retval, std::make_shared<Variable>(args[0]) }); } static Variable set(SharedEnvironment env, Cmdargs& args) { auto varName = std::get<std::string>(args[0].data); auto& scope = env->currScope(); auto res = scope.find(varName); if (res != scope.end()) { *res->second = args[1]; } else { scope[varName] = std::make_shared<Variable>(args[1]); } return args[1]; } static Variable local(SharedEnvironment env, Cmdargs& args) { env->currScope()[std::get<std::string>(args[0].data)] = std::make_shared<Variable>(args[1]); return args[1]; } static Variable global(SharedEnvironment env, Cmdargs& args) { (*env->globalScope)[std::get<std::string>(args[0].data)] = std::make_shared<Variable>(args[1]); return args[1]; } static Variable concat(SharedEnvironment, Cmdargs& args) { std::ostringstream fres; for (const auto& arg : args) { switch (arg.type) { case Variable::id_integer: fres << std::get<integer_type>(arg.data); break; case Variable::id_string: fres << std::get<std::string>(arg.data); break; case Variable::id_reference: fres << "REF<" << std::get<std::string>(arg.data) << '>'; break; case Variable::id_type: fres << std::get<Variable::Type>(arg.data); break; default: fres << "<ID" << arg.type << '>'; break; } } return Variable({ Variable::id_string, fres.str() }); } Std() { builtinCmds["exit"] = {exit, {Variable::id_integer}, false}; builtinCmds["return"] = {retval, {Variable::id_any}, false}; builtinCmds["="] = builtinCmds["set"] = {set, {Variable::id_string, Variable::id_any}, false}; builtinCmds[":="] = builtinCmds["local"] = {local, {Variable::id_string, Variable::id_any}, false}; builtinCmds["!="] = builtinCmds["global"] = {global, {Variable::id_string, Variable::id_any}, false}; builtinCmds["concat"] = {concat, {}, true}; } }; static Std inst;