-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathast.h
More file actions
267 lines (200 loc) · 6.81 KB
/
ast.h
File metadata and controls
267 lines (200 loc) · 6.81 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
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#ifndef __AST_H
#define __AST_H 1
#include <string.h>
#include "gen.h"
/* FALL_THROUGH may be used as an argument to BoolExp::genBoolExp().
Labels are represented as positive integers so FALL_THROUGH has negative value */
const int FALL_THROUGH = -1;
// all nodes in the AST (Abstract Syntax Tree) are of types derived from ASTnode
class ASTnode {
};
// expressions
// this is an abstract class
class Exp : public ASTnode {
public:
// return value is the temporary variable in which the result of the expression will be stored
// For example, return value 17 means result will be stored in _t17
virtual int genExp () = 0; // every subclass should override this (or be abstract too)
Exp () { _result = -1; _type = UNKNOWN; }
// Exp (int result, myType _type) : ASTnode () { this->_result = result; this->_type = _type; }
int _result;/* example: _result is 17 means result of expression will be in _t17.
_result is -1 means: not known yet (_result is set to a new temporary when
code for the expression is generated) */
myType _type;
};
class BinaryOp : public Exp {
public:
BinaryOp (enum op op, Exp *left, Exp *right, int line);
int genExp (); // override
enum op _op;
Exp *_left; // left operand
Exp *_right; // right operand
int _line; // source line number of operator
};
class NumNode : public Exp {
public:
int genExp (); // override
NumNode (int ival) { _u.ival = ival; _type = _INT;}
NumNode (double fval) { _u.fval = fval; _type = _FLOAT;}
union {
int ival;
double fval;
} _u;
};
class IdNode : public Exp {
public:
int genExp (); // override
IdNode (char *name, int line);
char _name [100];
int _line; // source line number
};
// boolean expressions
// this is an abstract class
class BoolExp : public ASTnode {
public: // some members should be private ...
/* generate code for boolean expression. The code should jump to
truelabel or to falselabel depending on the value of the expression.
truelabel may be FALL_THROUGH meaning code should fall through to
next instruction (rather than jump to a label) when the expression is
true. falselabel may also be FALL_TROUGH */
virtual void genBoolExp (int truelabel, int falselabel) = 0; // every subclass should
// override this (or be abstract too)
};
// nodes for simple boolean expressions having the form
// expression RELOP expression
// for example a < b
// another example: (a + 3) < (z * 5 + y).
class SimpleBoolExp : public BoolExp {
public:
SimpleBoolExp (enum op op, Exp *left, Exp *right)
{ this->_op = op; this->_left = left; this->_right = right;}
void genBoolExp (int truelabel, int falselabel); // override
enum op _op;
Exp *_left; // left operand
Exp *_right; // right operand
};
class Or : public BoolExp {
public:
Or (BoolExp *left, BoolExp *right) { _left = left; _right = right; }
void genBoolExp (int truelabel, int falselabel); // override
BoolExp *_left; // left operand
BoolExp *_right; // right operand
};
class And : public BoolExp {
public:
And (BoolExp *left, BoolExp *right) { _left = left; _right = right; }
void genBoolExp (int truelabel, int falselabel); // override
BoolExp *_left; // left operand
BoolExp *_right; // right operand
};
class Not : public BoolExp {
public:
Not (BoolExp *operand) { _operand = operand;}
void genBoolExp (int truelabel, int falselabel); // override
BoolExp *_operand;
};
class Fand : public BoolExp {
public:
Fand (BoolExp *left, BoolExp *right) { _left = left; _right = right; }
void genBoolExp (int truelabel, int falselabel); // override
BoolExp *_left; // left operand
BoolExp *_right; // right operand
};
// statements
// this is an abstract class
class Stmt: public ASTnode {
public:
Stmt () {_next = NULL; }
virtual void genStmt () = 0; // every subclass should override this (or be abstract too)
Stmt *_next; // used to link together statements in the same block
};
class ReadStmt: public Stmt {
public:
ReadStmt (IdNode *id, int line) : Stmt() { _id = id; _line = line;};
void genStmt (); // override
IdNode *_id; // note: IdNode is subclass of Exp but this IdNode is not really an expression
int _line; // line in source code
};
class WriteStmt: public Stmt {
public:
WriteStmt (Exp *exp, int line) : Stmt() { _exp = exp; _line = line;};
void genStmt (); // override
Exp *_exp;
int _line; // line in source code
};
class AssignStmt : public Stmt {
public:
AssignStmt (IdNode *lhs, Exp *rhs, int line);
void genStmt (); // override
IdNode *_lhs; // left hand side
Exp *_rhs; // right hand side
int _line; // line in source code
};
class IfStmt : public Stmt {
public:
IfStmt (BoolExp *condition, Stmt *thenStmt, Stmt *elseStmt)
: Stmt ()
{ this->_condition = condition; this->_thenStmt = thenStmt; this->_elseStmt = elseStmt; }
void genStmt (); // override
BoolExp *_condition;
Stmt *_thenStmt;
Stmt *_elseStmt;
};
class WhileStmt: public Stmt {
public:
WhileStmt (BoolExp *condition, Stmt *body)
: Stmt ()
{ _condition = condition; _body = body; }
void genStmt (); // override
BoolExp *_condition;
Stmt *_body;
};
class ForStmt: public Stmt {
public:
ForStmt ( AssignStmt *init, BoolExp *condition, Stmt *body, AssignStmt *afterStep)
: Stmt ()
{ _condition = condition; _body = body; _init = init; _afterStep = afterStep;}
void genStmt (); // override
BoolExp *_condition;
Stmt *_body;
Stmt *_init;
Stmt*_afterStep;
};
// a block contains a list of statements. For now -- no declarations in a block
class Block: public Stmt {
public:
Block (Stmt *stmtlist) { _stmtlist = stmtlist; }
void genStmt (); // override
Stmt* _stmtlist; // pointer to the first statement. each statement points to the next stmt
};
class BreakStmt : public Stmt {
public:
BreakStmt (int line) { _line = line; }
void genStmt(); // override
int _line; // source line of switch token
};
class Case : public ASTnode {
public:
Case (int number, Stmt *stmt, bool hasBreak) {
_number = number;
_stmt = stmt;
_hasBreak = hasBreak;
_next = NULL;
_label = -1; // will be set when code is generated
}
int _number;
Stmt *_stmt;
bool _hasBreak;
Case *_next;
int _label;
};
class SwitchStmt : public Stmt {
public:
SwitchStmt (Exp *exp, Case *caselist, Stmt *default_stmt, int line);
void genStmt (); // override
Exp *_exp;
Case *_caselist;
Stmt *_default_stmt;
int _line; // source line of switch token
};
#endif // not defined __AST_H