-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterpreter.h
More file actions
108 lines (88 loc) · 3.12 KB
/
interpreter.h
File metadata and controls
108 lines (88 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef INTERPRETER_H
#define INTERPRETER_H
#include "ast.h"
#include "token.h"
#include <unordered_map>
#include <any>
#include <string>
#include <vector>
#include <functional>
namespace AR437 {
class RuntimeError : public std::exception {
private:
std::string message;
public:
RuntimeError(const std::string& msg) : message(msg) {}
const char* what() const noexcept override {
return message.c_str();
}
};
class ReturnValue : public std::exception {
private:
std::any value;
public:
ReturnValue(std::any val) : value(val) {}
std::any getValue() const { return value; }
};
class Environment {
private:
std::unordered_map<std::string, std::any> variables;
Environment* enclosing;
public:
Environment(Environment* enc = nullptr) : enclosing(enc) {}
void define(const std::string& name, std::any value);
std::any get(const std::string& name);
void assign(const std::string& name, std::any value);
bool exists(const std::string& name);
};
class Function {
public:
std::string name;
std::vector<std::string> parameters;
Block* body; // Use raw pointer instead of unique_ptr to avoid move issues
Environment* closure;
Function(const std::string& n, const std::vector<std::string>& params,
Block* b, Environment* env)
: name(n), parameters(params), body(b), closure(env) {}
std::any call(const std::vector<std::any>& arguments, class Interpreter* interpreter);
};
class Interpreter : public ASTVisitor {
private:
Environment* globals;
Environment* environment;
std::unordered_map<std::string, std::unique_ptr<Function>> functions;
std::any lastValue;
std::string anyToString(const std::any& value);
bool isTruthy(const std::any& value);
bool isEqual(const std::any& left, const std::any& right);
std::any performBinaryOperation(const std::any& left, TokenType operator_, const std::any& right);
std::any performUnaryOperation(TokenType operator_, const std::any& operand);
public:
Interpreter();
~Interpreter();
void interpret(Program& program);
Environment* getGlobalEnvironment() { return globals; }
// Visitor methods
void visit(NumberLiteral& node) override;
void visit(StringLiteral& node) override;
void visit(BooleanLiteral& node) override;
void visit(NullLiteral& node) override;
void visit(Identifier& node) override;
void visit(BinaryOperation& node) override;
void visit(UnaryOperation& node) override;
void visit(Assignment& node) override;
void visit(FunctionCall& node) override;
void visit(ExpressionStatement& node) override;
void visit(VariableDeclaration& node) override;
void visit(Block& node) override;
void visit(IfStatement& node) override;
void visit(WhileStatement& node) override;
void visit(ReturnStatement& node) override;
void visit(DisplayStatement& node) override;
void visit(ReadStatement& node) override;
void visit(FunctionDeclaration& node) override;
void visit(Program& node) override;
void executeBlock(Block& block, Environment* env);
};
} // namespace AR437
#endif // INTERPRETER_H