1
0
Fork 0
mirror of https://gitlab.com/niansa/pilang2.git synced 2025-03-06 20:49:22 +01:00

Moved builtin module into own file and added some macro magic

This commit is contained in:
niansa 2020-06-05 16:04:33 +02:00
parent 327ce8a334
commit be73075efd
2 changed files with 394 additions and 345 deletions

371
modules/builtin.hh Normal file
View file

@ -0,0 +1,371 @@
command_tmpl(cmd_ret) {
std::string retstring;
for (const std::string & arg : args){
retstring.append(arg);
}
return retstring;
}
command_tmpl(cmd_catch) {
if (args.size() != 1) {
return badarguments;
}
std::string boolstr = *args.begin();
if (str_lower(boolstr) == "true")
catcherrs = true;
else if (str_lower(boolstr) == "false")
catcherrs = false;
else
return badarguments;
return success;
}
command_tmpl(cmd_get) {
if (args.size() != 2) {
return badarguments;
}
auto argsit = args.begin();
std::string string = *argsit;
argsit++;
long unsigned int position = std::stoi(*argsit);
if (position < string.length()) {
std::string res;
res.push_back(string.at(position));
return res;
} else {
return badarguments;
}
}
command_tmpl(cmd_len) {
int result = 0;
for (const std::string & arg : args){
result += arg.length();
}
return std::to_string(result);
}
command_tmpl(cmd_exit) {
//Check amount of arguments
if (args.size() != 1) {
return badarguments;
}
std::string exitcode = *args.begin();
if (is_float(exitcode))
_exit(std::stoi(exitcode));
else
return badarguments;
}
command_tmpl(cmd_marker) {
// Check amount of arguments
if (args.size() != 2) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
std::string action = *argsit;
argsit++;
std::string markername = *argsit;
// Set or goto
if (action == "goto") {
markergotoname = markername;
throw markergoto();
} else if (action == "set") {
markersetqueue.push_back(markername);
} else {
return badarguments;
}
return success;
}
command_tmpl(cmd_printnnl) {
std::cout << cmd_ret(args) << std::flush;
return success;
}
command_tmpl(cmd_print) {
auto result = cmd_printnnl(args);
std::cout << std::endl;
return result;
}
command_tmpl(cmd_input) {
std::string hint = cmd_ret(args);
cmd_printnnl({hint});
std::string result;
std::getline(readkbd(hint), result);
return result;
}
command_tmpl(cmd_set) {
//Check amount of arguments
if (args.size() != 2) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
std::string key = *argsit;
argsit++;
std::string value = *argsit;
// Store in environment
variables[key] = value;
// Return success
return success;
}
command_tmpl(cmd_append) {
//Check amount of arguments
if (args.size() < 2) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
std::string variablename = *argsit;
argsit++;
for (; argsit != args.end(); argsit++)
variables[variablename].append(*argsit);
return success;
}
std::string cmd_incdec(bool type, command_args) { // TODO
bool asint = false;
//Check amount of arguments
if (args.size() < 1 or args.size() > 3) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
if (*argsit == "asint") {
asint = true;
argsit++;
}
std::string variablename = *argsit;
float incby;
if (args.size() > 1) {
argsit++;
incby = std::atof((*argsit).c_str());
} else {
incby = 1;
}
// Modify variable if it exists
if (variables.find(variablename) == variables.end()) {
return nosuchvariable;
} else {
float currval = std::atof(variables[variablename].c_str());
if (type)
currval += incby;
else
currval -= incby;
if (!asint)
variables[variablename] = std::to_string(currval);
else
variables[variablename] = std::to_string((int)currval);
}
return success;
}
command_tmpl(cmd_inc) {
return cmd_incdec(true, args);
}
command_tmpl(cmd_dec) {
return cmd_incdec(false, args);
}
command_tmpl(cmd_del) {
if (args.size() < 1) {
return badarguments;
}
for (const std::string & arg : args) {
auto varit = variables.find(arg);
if (varit != variables.end()) {
variables.erase(variables.find(arg));
}
}
return success;
}
command_tmpl(cmd_eval) {
if (args.size() < 1) {
return badarguments;
}
std::string result;
for (const std::string & arg : args) {
result = execline(arg);
}
return result;
}
command_tmpl(cmd_cmp) {
bool matches;
//Check amount of arguments
if (args.size() < 4) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
std::string action = *argsit;
argsit++;
std::string var1 = *argsit;
argsit++;
std::string var2 = *argsit;
argsit++;
// Compare
if (action == "equal")
matches = var1 == var2;
else if (action == "nonequal")
matches = var1 != var2;
else if (action == "bigger")
matches = std::atof(var1.c_str()) > std::atof(var2.c_str());
else if (action == "smaller")
matches = std::atof(var1.c_str()) < std::atof(var2.c_str());
else if (action == "isnum" or action == "isnotnum") {
matches = is_float(var1) and is_float(var2);
if (action == "isnotnum")
matches = !matches;
} else
return badarguments;
// Eval on match
if (matches) {
std::string result;
while (argsit != args.end()) {
result = execline(*argsit);
argsit++;
}
return result;
} else {
return failed;
}
}
std::string cmd_lowerupper(bool type, command_args) {
if (args.size() < 1) {
return badarguments;
}
std::string result;
for (auto argsit = args.begin(); argsit != args.end(); argsit++) {
if (type)
result.append(str_upper(*argsit));
else
result.append(str_lower(*argsit));
}
return result;
}
command_tmpl(cmd_upper) {
return cmd_lowerupper(true, args);
}
command_tmpl(cmd_lower) {
return cmd_lowerupper(false, args);
}
std::string cmd_addsub(bool type, command_args) {
//Check amount of arguments
if (args.size() < 2) {
return badarguments;
}
// Initialise variables
bool asint = false;
float numarg;
// Get arguments
auto argsit = args.begin();
if (*argsit == "asint") {
asint = true;
argsit++;
}
// Initialise initial result
if (!is_float(*argsit))
return badarguments;
float result = std::atof((*argsit).c_str());
argsit++;
// Calculate
for (; argsit != args.end(); argsit++) {
if (!is_float(*argsit))
return badarguments;
numarg = std::atof((*argsit).c_str());
if (type)
result += numarg;
else
result -= numarg;
}
// Return result
if (asint)
return std::to_string((int) result);
else
return std::to_string(result);
}
command_tmpl(cmd_add) {
return cmd_addsub(true, args);
}
command_tmpl(cmd_sub) {
return cmd_addsub(false, args);
}
command_tmpl(cmd_sleep) {
// Check amount of arguments
if (args.size() != 1) {
return badarguments;
}
// Check argument
auto argsit = args.begin();
if (!is_float(*argsit))
return badarguments;
// Get argument
float sleepsecs = std::atof((*argsit).c_str());
sleep(sleepsecs);
return success;
}
command_tmpl(cmd_argv) {
// Check amount of arguments
if (args.size() != 1) {
return badarguments;
}
// Check argument
auto argsit = args.begin();
if (!is_float(*argsit))
return badarguments;
long unsigned int argnum = std::atoi((*argsit).c_str());
if (argnum >= cmdargs.size())
return badarguments;
// Get argument
return cmdargs[argnum];
}
command_tmpl(cmd_argc) {
return std::to_string(cmdargs.size());
}
command_tmpl(cmd_commands) {
std::stringstream res;
for (auto it = commands.begin(); it != commands.end(); it++) {
res << &it->first[sizeof("cmd_") - 1] << " ";
}
return res.str();
}
void register_builtin_commands() {
command_register(cmd_argc);
command_register(cmd_argv);
command_register(cmd_sleep);
command_register(cmd_add);
command_register(cmd_sub);
command_register(cmd_upper);
command_register(cmd_lower);
command_register(cmd_eval);
command_register(cmd_cmp);
command_register(cmd_del);
command_register(cmd_append);
command_register(cmd_inc);
command_register(cmd_dec);
command_register(cmd_set);
command_register(cmd_input);
command_register(cmd_print);
command_register(cmd_printnnl);
command_register(cmd_marker);
command_register(cmd_exit);
command_register(cmd_len);
command_register(cmd_get);
command_register(cmd_catch);
command_register(cmd_ret);
command_register(cmd_commands);
}

View file

@ -112,357 +112,33 @@ std::string get_rstring(std::string rstring) {
return rstring;
}
// Function template
#define command_args std::vector<std::string> args
#define command_rawtmpl(func) func(command_args)
#define command_tmpl(func) std::string command_rawtmpl(func)
typedef std::function<command_rawtmpl(std::string)> command_type;
// Builtin functions
std::string cmd_ret(std::vector<std::string> args) {
std::string retstring;
for (const std::string & arg : args){
retstring.append(arg);
}
return retstring;
}
std::string cmd_catch(std::vector<std::string> args) {
if (args.size() != 1) {
return badarguments;
}
std::string boolstr = *args.begin();
if (str_lower(boolstr) == "true")
catcherrs = true;
else if (str_lower(boolstr) == "false")
catcherrs = false;
else
return badarguments;
return success;
}
std::string cmd_get(std::vector<std::string> args) {
if (args.size() != 2) {
return badarguments;
}
auto argsit = args.begin();
std::string string = *argsit;
argsit++;
long unsigned int position = std::stoi(*argsit);
if (position < string.length()) {
std::string res;
res.push_back(string.at(position));
return res;
} else {
return badarguments;
}
}
std::string cmd_len(std::vector<std::string> args) {
int result = 0;
for (const std::string & arg : args){
result += arg.length();
}
return std::to_string(result);
}
std::string cmd_exit(std::vector<std::string> args) {
//Check amount of arguments
if (args.size() != 1) {
return badarguments;
}
std::string exitcode = *args.begin();
if (is_float(exitcode))
_exit(std::stoi(exitcode));
else
return badarguments;
}
std::string cmd_marker(std::vector<std::string> args) {
// Check amount of arguments
if (args.size() != 2) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
std::string action = *argsit;
argsit++;
std::string markername = *argsit;
// Set or goto
if (action == "goto") {
markergotoname = markername;
throw markergoto();
} else if (action == "set") {
markersetqueue.push_back(markername);
} else {
return badarguments;
}
return success;
}
std::string cmd_printnnl(std::vector<std::string> args) {
std::cout << cmd_ret(args) << std::flush;
return success;
}
std::string cmd_print(std::vector<std::string> args) {
auto result = cmd_printnnl(args);
std::cout << std::endl;
return result;
}
std::string cmd_input(std::vector<std::string> args) {
std::string hint = cmd_ret(args);
cmd_printnnl({hint});
std::string result;
std::getline(readkbd(hint), result);
return result;
}
std::string cmd_set(std::vector<std::string> args) {
//Check amount of arguments
if (args.size() != 2) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
std::string key = *argsit;
argsit++;
std::string value = *argsit;
// Store in environment
variables[key] = value;
// Return success
return success;
}
std::string cmd_append(std::vector<std::string> args) {
//Check amount of arguments
if (args.size() < 2) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
std::string variablename = *argsit;
argsit++;
for (; argsit != args.end(); argsit++)
variables[variablename].append(*argsit);
return success;
}
std::string cmd_incdec(bool type, std::vector<std::string> args) {
bool asint = false;
//Check amount of arguments
if (args.size() < 1 or args.size() > 3) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
if (*argsit == "asint") {
asint = true;
argsit++;
}
std::string variablename = *argsit;
float incby;
if (args.size() > 1) {
argsit++;
incby = std::atof((*argsit).c_str());
} else {
incby = 1;
}
// Modify variable if it exists
if (variables.find(variablename) == variables.end()) {
return nosuchvariable;
} else {
float currval = std::atof(variables[variablename].c_str());
if (type)
currval += incby;
else
currval -= incby;
if (!asint)
variables[variablename] = std::to_string(currval);
else
variables[variablename] = std::to_string((int)currval);
}
return success;
}
std::string cmd_del(std::vector<std::string> args) {
if (args.size() < 1) {
return badarguments;
}
for (const std::string & arg : args) {
auto varit = variables.find(arg);
if (varit != variables.end()) {
variables.erase(variables.find(arg));
}
}
return success;
}
std::string cmd_eval(std::vector<std::string> args) {
if (args.size() < 1) {
return badarguments;
}
std::string result;
for (const std::string & arg : args) {
result = execline(arg);
}
return result;
}
std::string cmd_cmp(std::vector<std::string> args) {
bool matches;
//Check amount of arguments
if (args.size() < 4) {
return badarguments;
}
// Get arguments
auto argsit = args.begin();
std::string action = *argsit;
argsit++;
std::string var1 = *argsit;
argsit++;
std::string var2 = *argsit;
argsit++;
// Compare
if (action == "equal")
matches = var1 == var2;
else if (action == "nonequal")
matches = var1 != var2;
else if (action == "bigger")
matches = std::atof(var1.c_str()) > std::atof(var2.c_str());
else if (action == "smaller")
matches = std::atof(var1.c_str()) < std::atof(var2.c_str());
else if (action == "isnum" or action == "isnotnum") {
matches = is_float(var1) and is_float(var2);
if (action == "isnotnum")
matches = !matches;
} else
return badarguments;
// Eval on match
if (matches) {
std::string result;
while (argsit != args.end()) {
result = execline(*argsit);
argsit++;
}
return result;
} else {
return failed;
}
}
std::string cmd_lowerupper(bool type, std::vector<std::string> args) {
if (args.size() < 1) {
return badarguments;
}
std::string result;
for (auto argsit = args.begin(); argsit != args.end(); argsit++) {
if (type)
result.append(str_upper(*argsit));
else
result.append(str_lower(*argsit));
}
return result;
}
std::string cmd_addsub(bool type, std::vector<std::string> args) {
//Check amount of arguments
if (args.size() < 2) {
return badarguments;
}
// Initialise variables
bool asint = false;
float numarg;
// Get arguments
auto argsit = args.begin();
if (*argsit == "asint") {
asint = true;
argsit++;
}
// Initialise initial result
if (!is_float(*argsit))
return badarguments;
float result = std::atof((*argsit).c_str());
argsit++;
// Calculaté
for (; argsit != args.end(); argsit++) {
if (!is_float(*argsit))
return badarguments;
numarg = std::atof((*argsit).c_str());
if (type)
result += numarg;
else
result -= numarg;
}
// Return result
if (asint)
return std::to_string((int) result);
else
return std::to_string(result);
}
std::string cmd_sleep(std::vector<std::string> args) {
// Check amount of arguments
if (args.size() != 1) {
return badarguments;
}
// Check argument
auto argsit = args.begin();
if (!is_float(*argsit))
return badarguments;
// Get argument
float sleepsecs = std::atof((*argsit).c_str());
sleep(sleepsecs);
return success;
}
std::string cmd_argv(std::vector<std::string> args) {
// Check amount of arguments
if (args.size() != 1) {
return badarguments;
}
// Check argument
auto argsit = args.begin();
if (!is_float(*argsit))
return badarguments;
long unsigned int argnum = std::atoi((*argsit).c_str());
if (argnum >= cmdargs.size())
return badarguments;
// Get argument
return cmdargs[argnum];
}
std::string cmd_argc(std::vector<std::string> args) {
return std::to_string(cmdargs.size());
// Function struct and map
std::map<std::string, command_type> commands;
#define command_register(func) commands[#func] = func;
// Module includes
#include "../modules/builtin.hh"
// Module loaders
void load_modules() {
// Execute your module registration functions here
register_builtin_commands();
}
// Function executor
std::string run_command(std::string command, std::vector<std::string> args) {
//std::cout << "Running command:" << command << "!" << std::endl;
if (command == "ret")
return cmd_ret(args);
else if (command == "catch")
return cmd_catch(args);
else if (command == "get")
return cmd_get(args);
else if (command == "len")
return cmd_len(args);
else if (command == "exit")
return cmd_exit(args);
else if (command == "marker")
return cmd_marker(args);
else if (command == "print")
return cmd_print(args);
else if (command == "printnnl")
return cmd_printnnl(args);
else if (command == "input")
return cmd_input(args);
else if (command == "set")
return cmd_set(args);
else if (command == "append")
return cmd_append(args);
else if (command == "inc")
return cmd_incdec(true, args);
else if (command == "dec")
return cmd_incdec(false, args);
else if (command == "del")
return cmd_del(args);
else if (command == "eval")
return cmd_eval(args);
else if (command == "cmp")
return cmd_cmp(args);
else if (command == "lower")
return cmd_lowerupper(false, args);
else if (command == "upper")
return cmd_lowerupper(true, args);
else if (command == "add")
return cmd_addsub(true, args);
else if (command == "sub")
return cmd_addsub(false, args);
else if (command == "sleep")
return cmd_sleep(args);
else if (command == "argv")
return cmd_argv(args);
else if (command == "argc")
return cmd_argc(args);
else
if (commands.find("cmd_" + command) == commands.end()) {
return nosuchcommand;
} else {
return commands["cmd_" + command](args);
}
}
// Interpreter initialiser
@ -558,6 +234,8 @@ int _main(int argc, char *argv[]) {
using namespace std;
signal(SIGSEGV, sigsegv_handler);
std::string line;
load_modules();
// Start CLI or run file
if (argc < 2) { // Start interactive CLI
// Show copyright note
cout << "pilang Copyright (C) 2020 niansa" << endl;