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-02-14 20:57:15 +01:00

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