-
Notifications
You must be signed in to change notification settings - Fork 0
/
ast.cpp
181 lines (158 loc) · 6.78 KB
/
ast.cpp
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include"ast.h"
// turn all fields into pointers
using namespace std;
/************************* Expressions *********************/
Expression::Expression() = default;
Expression::~Expression() = default;
string Expression::serialize() const {return "";}
string Expression::getType() const {return type;}
string Identifier::serialize() const {return value;}
string Identifier::getType() const {return type;}
IntLiteral::IntLiteral(Token tok, int val) : token(tok), value(val) {};
string IntLiteral::serialize() const {return token.literal;};
string IntLiteral::getType() const {return type;};
BoolLiteral::BoolLiteral(Token tok, bool val) : token(tok), value(val){};
string BoolLiteral::serialize() const {return token.literal;}
string BoolLiteral::getType() const {return type;};
StringLiteral::StringLiteral(Token tok, string val) : token(tok), value(val) {};
string StringLiteral::serialize() const {return "\"" + value + "\"";};
string StringLiteral::getType() const {return type;};
FnLiteral::FnLiteral(Token tok, vector<unique_ptr<Expression>>&& params, unique_ptr<BlockStatement>& body) : token(tok), params(move(params)), body(move(body)) {};
string FnLiteral::serialize() const {
string paramStr = "(";
for (int i = 0; i < params.size(); i++) {
Expression* param = params.at(i).get();
paramStr += param->serialize();
if (i == params.size() - 1) {
paramStr += ")";
} else {
paramStr += ", ";
}
}
return "fn" + paramStr + body.get()->serialize();
}
string FnLiteral::getType() const {return type;};
ArrayLiteral::ArrayLiteral(Token tok, vector<unique_ptr<Expression>>&& elements) : token(tok), elements(move(elements)) {};
string ArrayLiteral::serialize() const {
string res = "[";
for (int i = 0; i < elements.size(); i++) {
res += elements.at(i).get()->serialize();
if (i < elements.size() - 1) res += ", ";
}
res += "]";
return res;
}
string ArrayLiteral::getType() const {return type;};
HashLiteral::HashLiteral(Token tok, vector<pair<unique_ptr<Expression>, unique_ptr<Expression>>>& pairs) : token(tok), pairs(move(pairs)) {};
string HashLiteral::serialize() const {
string res = "{";
int i = 0;
for (const auto& pair : pairs) {
res += pair.first.get()->serialize();
res += ": ";
res += pair.second.get()->serialize();
if (i++ < pairs.size() - 1) res += ", ";
}
res += "}";
return res;
}
string HashLiteral::getType() const {return type;};
IndexExpression::IndexExpression(Token tok, unique_ptr<Expression>& entity, unique_ptr<Expression>& index) : token(tok), entity(move(entity)), index(move(index)) {};
string IndexExpression::serialize() const {
string res = entity.get()->serialize();
res += "[";
res += index.get()->serialize();
res += "]";
return res;
}
string IndexExpression::getType() const {
return type;
}
PrefixExpression::PrefixExpression() = default;
PrefixExpression::PrefixExpression(Token tok, string Operator, unique_ptr<Expression>& right) : token(tok), Operator(Operator), right(move(right)) {};
string PrefixExpression::serialize() const {
return Operator + right.get()->serialize();
}
string PrefixExpression::getType() const {
return type;
}
InfixExpression::InfixExpression() = default;
InfixExpression::InfixExpression(Token tok, string Operator, unique_ptr<Expression>& left, unique_ptr<Expression>& right) : token(tok), Operator(Operator), left(move(left)), right(move(right)) {};
string InfixExpression::serialize() const {
string res = "(" + left.get()->serialize() + " " + Operator + " " + right.get()->serialize() + ")";
return res;
};
string InfixExpression::getType() const {
return type;
}
IfExpression::IfExpression(Token tok,
unique_ptr<Expression>& cond,
unique_ptr<BlockStatement>& cons,
unique_ptr<BlockStatement>& alt) : token(tok), condition(move(cond)), consequence(move(cons)), alternative(move(alt)){};
string IfExpression::serialize() const {
string alt;
if (alternative != nullptr) alt = " else " + alternative.get()->serialize();
return "if " + condition.get()->serialize() + " " +
consequence.get()->serialize() + alt;
}
string IfExpression::getType() const {return type;};
CallExpression::CallExpression(Token tok, unique_ptr<Expression>& function, vector<unique_ptr<Expression>>&& args) : token(tok), function(move(function)), args(move(args)) {};
string CallExpression::serialize() const {
string paramStr = "(";
for (int i = 0; i < args.size(); i++) {
paramStr += args.at(i).get()->serialize();
if (i == args.size() - 1) paramStr += ")";
else paramStr += ", ";
}
return function.get()->serialize() + paramStr;
}
string CallExpression::getType() const {return type;};
/************************* Statements ************************/
Statement::Statement() = default;
Statement::~Statement() = default;
string Statement::serialize() const {return "";};
string Statement::getType() const {return type;};
LetStatement::LetStatement() = default;
LetStatement::LetStatement(Token tok, Identifier ident, unique_ptr<Expression>& val) : token(tok), identifier(ident), value(move(val)) {};
string LetStatement::serialize() const {
return token.literal
+ " "
+ identifier.serialize()
+ " = "
+ value.get()->serialize() + ";";
};
string LetStatement::getType() const {return type;};
ReturnStatement::ReturnStatement() = default;
ReturnStatement::ReturnStatement(Token tok, unique_ptr<Expression>& val) : token(tok), value(move(val)) {}
string ReturnStatement::serialize() const {
return token.literal + " " + value.get()->serialize() + ";";
}
string ReturnStatement::getType() const {return type;};
/* To allow for a single line expression like "x + 5;"*/
ExpressionStatement::ExpressionStatement() {
expression = nullptr;
};
ExpressionStatement::ExpressionStatement(Token tok, unique_ptr<Expression>& express): token(tok), expression(move(express)) {};
string ExpressionStatement::serialize() const {
return expression.get()->serialize();
}
string ExpressionStatement::getType() const {return type;};
BlockStatement::BlockStatement(Token tok, vector<unique_ptr<Statement>>&& stmts) : token(tok), statements(move(stmts)) {};
string BlockStatement::serialize() {
string res = "{";
for (int i = 0; i < statements.size(); i++) {
res += statements.at(i).get()->serialize(); + ";";
}
return res + "}";
}
string BlockStatement::getType() const {return type;};
/*********************** Program (root node) ********************/
string Program::serialize() const {
string res = "";
for (int i = 0; i < statements.size(); i++) {
Statement* stmt = statements.at(i).get();
res += stmt->serialize();
}
return res;
}
string Program::getType() const {return type;};