mirror of
https://gitlab.com/niansa/pilang3.git
synced 2025-03-06 20:49:20 +01:00
98 lines
3.5 KiB
C++
98 lines
3.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;
|
|
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>;
|
|
|
|
struct Variable {
|
|
enum Type {
|
|
id_string,
|
|
id_integer,
|
|
id_reference,
|
|
id_evaluation,
|
|
id_function,
|
|
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, Type>;
|
|
Data data;
|
|
};
|
|
|
|
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({});
|
|
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);
|
|
};
|
|
};
|