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

Implemented basic functions

This commit is contained in:
niansa 2021-02-04 13:45:05 +01:00
parent 303c5f828b
commit 1bcb03f0cc
5 changed files with 27 additions and 19 deletions

View file

@ -13,6 +13,7 @@ namespace Pilang3 {
namespace exceptions { namespace exceptions {
class langException : public std::exception {}; class langException : public std::exception {};
class emptyExpr : public langException {};
class BadInteger : public langException {}; class BadInteger : public langException {};
class BadArgs : public langException {}; class BadArgs : public langException {};
class NoSuchCommand : public langException {}; class NoSuchCommand : public langException {};
@ -48,7 +49,7 @@ namespace Pilang3 {
using Cmdargs = std::vector<Variable>; using Cmdargs = std::vector<Variable>;
using Cmdfnc = std::function<Variable (SharedEnvironment, Cmdargs&)>; using Cmdfnc = std::function<Variable (SharedEnvironment, Cmdargs&)>;
using Cmddesc = std::tuple<Cmdfnc, uint16_t, std::vector<Variable::Type>, bool>; using Cmddesc = std::tuple<Cmdfnc, std::vector<Variable::Type>, bool>;
extern std::unordered_map<std::string, Cmddesc> builtinCmds; extern std::unordered_map<std::string, Cmddesc> builtinCmds;

View file

@ -13,11 +13,13 @@ int main() {
// CLI loop // CLI loop
while (true) { while (true) {
std::getline(std::cin, line); std::getline(std::cin, line);
//try { try {
Evaluation evaluation(env, line); Evaluation evaluation(env, line);
evaluation.execute(env); evaluation.execute(env);
//} catch (exceptions::langException& e) { } catch (exceptions::emptyExpr&) {
// std::cout << "E: Language exception: " << &e << std::endl; // Do nothing
//} } catch (exceptions::langException& e) {
std::cout << "E: Language exception: " << &e << std::endl;
}
} }
} }

View file

@ -40,10 +40,10 @@ public:
} }
Std() { Std() {
Pilang3::builtinCmds["return"] = {retval, 1, {Variable::id_any}, false}; Pilang3::builtinCmds["return"] = {retval, {Variable::id_any}, false};
Pilang3::builtinCmds["set"] = {set, 2, {Variable::id_string, Variable::id_any}, false}; Pilang3::builtinCmds["set"] = {set, {Variable::id_string, Variable::id_any}, false};
Pilang3::builtinCmds["get"] = {get, 1, {Variable::id_string}, false}; Pilang3::builtinCmds["get"] = {get, {Variable::id_string}, false};
Pilang3::builtinCmds["concat"] = {concat, 0, {}, true}; Pilang3::builtinCmds["concat"] = {concat, {}, true};
} }
}; };

View file

@ -14,7 +14,7 @@ public:
} }
StdIO() { StdIO() {
Pilang3::builtinCmds["print"] = {print, 1, {Variable::id_string}, false}; Pilang3::builtinCmds["print"] = {print, {Variable::id_string}, false};
} }
}; };

View file

@ -10,22 +10,26 @@
#include "pilang.hpp" #include "pilang.hpp"
static inline bool is_sep(const char character) {
return character == ' ' or character == '\t' or character == '\n';
}
namespace Pilang3 { namespace Pilang3 {
std::unordered_map<std::string, std::tuple<Cmdfnc, uint16_t, std::vector<Variable::Type>, bool>> builtinCmds; std::unordered_map<std::string, Cmddesc> builtinCmds;
Evaluation::Evaluation(SharedEnvironment env, const std::string& expression, const bool autoeval) { Evaluation::Evaluation(SharedEnvironment env, const std::string& expression, const bool autoeval) {
// Count off trailing spaces // Count off trailing spaces
ssize_t tspaces = 0; ssize_t tspaces = 0;
for (const auto& character : expression) { for (const auto& character : expression) {
if (character == ' ' or character == '\t') { if (is_sep(character)) {
tspaces++; tspaces++;
} else { } else {
break; break;
} }
} }
// Parse arguments if any // Parse arguments if any
if (not expression.empty()) { if (not expression.empty() and static_cast<ssize_t>(expression.size()) != tspaces) {
Variable thisarg; Variable thisarg;
bool in_command_name = true; bool in_command_name = true;
bool newarg = false; bool newarg = false;
@ -52,7 +56,7 @@ namespace Pilang3 {
// Start new argument // Start new argument
else if (newarg) { else if (newarg) {
// Skip spaces // Skip spaces
if (character == ' ' or character == ',' or character == '\n' or character == ';') continue; if (is_sep(character)) continue;
// Guess type by first character // Guess type by first character
newarg = false; newarg = false;
if (std::isdigit(character) or character == '-' or character == '+') { if (std::isdigit(character) or character == '-' or character == '+') {
@ -80,7 +84,7 @@ namespace Pilang3 {
switch (thisarg.type) { switch (thisarg.type) {
case Variable::id_integer: { case Variable::id_integer: {
// Integer // Integer
if (character == ' ') continue; if (is_sep(character)) continue;
else if (maybe_end_of_arg) { else if (maybe_end_of_arg) {
// End argument // End argument
try { try {
@ -180,20 +184,21 @@ namespace Pilang3 {
return std::get<SharedFunction>(res->second->data)->execute(env); return std::get<SharedFunction>(res->second->data)->execute(env);
}; };
} else { } else {
uint16_t argslen;
std::vector<Variable::Type> argstypes; std::vector<Variable::Type> argstypes;
bool anymoreopts; bool anymoreopts;
std::tie(command, argslen, argstypes, anymoreopts) = res->second; std::tie(command, argstypes, anymoreopts) = res->second;
// Check args // Check args
if ((arguments.size() > argslen and not anymoreopts) or (arguments.size() < argslen)) { if ((arguments.size() > argstypes.size() and not anymoreopts) or (arguments.size() < argstypes.size())) {
throw exceptions::BadArgs(); throw exceptions::BadArgs();
} }
for (uint16_t argidx = 0; argidx != argslen; argidx++) { for (uint16_t argidx = 0; argidx != argstypes.size(); argidx++) {
if (argstypes[argidx] != Variable::id_any and argstypes[argidx] != arguments[argidx].type) { if (argstypes[argidx] != Variable::id_any and argstypes[argidx] != arguments[argidx].type) {
throw exceptions::BadArgs(); throw exceptions::BadArgs();
} }
} }
} }
} else {
throw exceptions::emptyExpr();
} }
} }