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); }