mirror of
https://gitlab.com/niansa/pilang3.git
synced 2025-03-06 20:49:20 +01:00
137 lines
4.5 KiB
C++
137 lines
4.5 KiB
C++
#include <string>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <stack>
|
|
#include <variant>
|
|
#include <exception>
|
|
#include <memory>
|
|
#include <functional>
|
|
|
|
|
|
|
|
namespace Pilang3 {
|
|
using integer_type = int64_t;
|
|
|
|
namespace exceptions {
|
|
class langException : public std::exception {public: const char *what() const noexcept {return "Runtime error";}};
|
|
class emptyExpr : public langException {public: const char *what() const noexcept {return "Empty expression";}};
|
|
class BadInteger : public langException {public: const char *what() const noexcept {return "Bad integer";}};
|
|
class BadArgs : public langException {public: const char *what() const noexcept {return "Bad arguments";}};
|
|
class NoSuchCommand : public langException {public: const char *what() const noexcept {return "No such command";}};
|
|
class NoSuchVariable : public langException {public: const char *what() const noexcept {return "No such variable";}};
|
|
class UnexpectedEndOfExpression : public langException {public: const char *what() const noexcept {return "Unexpected end of expression";}};
|
|
class exit : public langException {public: int code; const char *what() const noexcept {return "Interpreter exit";} exit(int code) {this->code = code;}};
|
|
}
|
|
|
|
class Environment;
|
|
class Evaluation;
|
|
class Function;
|
|
class Condition;
|
|
struct Variable;
|
|
using SharedEnvironment = std::shared_ptr<Environment>;
|
|
using SharedVariable = std::shared_ptr<Variable>;
|
|
using SharedEvaluation = std::shared_ptr<Evaluation>;
|
|
using SharedFunction = std::shared_ptr<Function>;
|
|
using SharedEvaluationWBool = std::tuple<SharedEvaluation, bool>;
|
|
|
|
namespace condition {
|
|
enum type {
|
|
_none,
|
|
equals,
|
|
not_equals,
|
|
biggerthan,
|
|
smallerthan,
|
|
biggerthanorequals,
|
|
smallerthanorequals,
|
|
ncpp_and,
|
|
ncpp_or,
|
|
_end
|
|
};
|
|
using array = std::vector<Variable*>;
|
|
}
|
|
|
|
struct Variable {
|
|
enum Type {
|
|
id_string,
|
|
id_integer,
|
|
id_reference,
|
|
id_evaluation,
|
|
id_function,
|
|
id_condition [[maybe_unused]],
|
|
id_type [[maybe_unused]],
|
|
id_retval [[maybe_unused]],
|
|
id_any [[maybe_unused]],
|
|
id_null [[maybe_unused]]
|
|
} type;
|
|
|
|
using Data = std::variant<std::string, integer_type, SharedVariable, SharedEvaluationWBool, SharedFunction, condition::array, Type>;
|
|
Data data;
|
|
|
|
static void derefer(SharedEnvironment env, Variable& var);
|
|
};
|
|
|
|
using Cmdargs = std::vector<Variable>;
|
|
using Cmdfnc = std::function<Variable (SharedEnvironment, Cmdargs&)>;
|
|
using Cmddesc = std::tuple<Cmdfnc, std::vector<Variable::Type>, bool>;
|
|
|
|
extern std::unordered_map<std::string, Cmddesc> builtinCmds;
|
|
|
|
class Environment {
|
|
public:
|
|
using Scope = std::unordered_map<std::string, SharedVariable>;
|
|
|
|
std::stack<Scope> variableScope;
|
|
Scope *globalScope;
|
|
void *anybuf = nullptr;
|
|
|
|
Environment() {
|
|
variableScope.push({
|
|
{"true", std::make_shared<Variable>(Variable{Variable::id_integer, 1})},
|
|
{"false", std::make_shared<Variable>(Variable{Variable::id_integer, 0})}
|
|
});
|
|
globalScope = &variableScope.top();
|
|
}
|
|
|
|
Scope &currScope() {
|
|
return variableScope.top();
|
|
}
|
|
};
|
|
|
|
class Evaluation {
|
|
public:
|
|
Cmdargs arguments;
|
|
std::tuple<std::string /*Command name in case cmddesc was not found in eval time*/, Cmddesc> command = {"", {nullptr, {}, false}};
|
|
std::string command_name;
|
|
ssize_t exprlen = -1;
|
|
|
|
Evaluation(SharedEnvironment env, const std::string& expression, const bool autoeval = true, const bool autoderef = true);
|
|
|
|
void derefer(SharedEnvironment env);
|
|
Variable execute(SharedEnvironment env);
|
|
};
|
|
|
|
class Function {
|
|
public:
|
|
std::vector<SharedEvaluation> evalChain;
|
|
std::vector<std::string> argumentNames;
|
|
bool new_scope = false;
|
|
|
|
Variable execute(SharedEnvironment env, Cmdargs& args);
|
|
};
|
|
|
|
class Condition {
|
|
public:
|
|
enum {
|
|
// Condition special types
|
|
id_equals,
|
|
id_notequals,
|
|
id_biggerthan,
|
|
id_smallerthan
|
|
};
|
|
|
|
ssize_t exprlen = -1;
|
|
std::vector<std::string*> arr;
|
|
|
|
Condition(const std::string& expression);
|
|
};
|
|
};
|