1
0
Fork 0
mirror of https://gitlab.com/niansa/pilang3.git synced 2025-03-06 20:49:20 +01:00
pilang3/include/pilang.hpp
2021-03-10 20:09:24 +01:00

138 lines
4.6 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,
ncpp_not,
_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 subderef = 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);
};
};