-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathast.h
More file actions
executable file
·182 lines (152 loc) · 4.87 KB
/
ast.h
File metadata and controls
executable file
·182 lines (152 loc) · 4.87 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
#ifndef AST_H
#define AST_H
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
typedef enum {
VAR_UNKNOWN = 0, // default should flip out
VAR_VOID,
VAR_STRING_ARRAY,
VAR_BOOL,
VAR_INT,
VAR_INT_ARRAY,
VAR_CLASS
} ast_var_type;
typedef struct {
ast_var_type type;
const char *classname; // Used by VAR_CLASS
} ast_type;
typedef enum {
INT_CONST,
BOOL_CONST,
VARNAME,
THIS_PTR,
NOT_EXPR,
NEW_CLASS,
NEW_INT_ARRAY,
ARRAY_LENGTH,
ARRAY_INDEX,
METHOD_CALL,
BINOP,
} ast_expr_type;
typedef struct ast_expr {
int lineno;
ast_expr_type type;
ast_type expr_type; // Used during typecheck
union {
int int_const; // INT_CONST
bool bool_const; // BOOL_CONST
struct {
const char *id; // VARNAME, NEW_CLASS
};
struct ast_expr *expr; // NOT_EXPR / NEW_INT_ARRAY / ARRAY_LENGTH
struct { // METHOD_CALL
struct ast_expr *object;
const char *method;
struct ast_expr *exp_list;
};
struct { // BINOP
struct ast_expr *lhs, *rhs;
int oper;
};
struct { // ARRAY_INDEX
struct ast_expr *array, *array_index;
};
};
struct ast_expr *next; // Non-NULL => ExpList
} ast_expr;
typedef enum {
BLOCK,
IF_ELSE,
WHILE_STMT,
SYS_OUT,
VAR_ASSIGN,
ARRAY_ASSIGN,
} ast_stmt_type;
typedef struct ast_stmt {
int lineno;
ast_stmt_type type;
union {
struct ast_stmt *stmt_list; // BLOCK
struct { // IF_ELSE / WHILE
ast_expr *cond;
union {
struct ast_stmt *while_branch; // WHILE
struct { // IF_ELSE
struct ast_stmt *true_branch, *false_branch;
};
};
};
struct { // VAR_ASSIGN / ARRAY_ASSIGN
const char *id;
ast_expr *array_index; // ARRAY_ASSIGN
ast_expr *assign_expr; // VAR_ASSIGN / ARRAY_ASSIGN
};
struct ast_expr *expr; // SYSO
};
// Statement List. A linked list stores a reference to the next class. Terminates with NULL
struct ast_stmt *next;
} ast_stmt;
typedef struct ast_vardecl {
int lineno;
ast_type type;
const char *id;
// VarList. A linked list stores a reference to the next class. Terminates with NULL
struct ast_vardecl *next;
} ast_vardecl;
typedef struct ast_methoddecl {
int lineno;
ast_type type;
const char *id;
ast_vardecl *params;
ast_vardecl *var_decl;
ast_stmt *body;
ast_expr *return_expr;
// MethodList. A linked list stores a reference to the next class. Terminates with NULL
struct ast_methoddecl *next;
} ast_methoddecl;
typedef struct ast_classdecl {
int lineno;
const char *id;
ast_vardecl *fields;
ast_methoddecl *methods;
// ClassList. A linked list stores a reference to the next class. Terminates with NULL
struct ast_classdecl *next;
} ast_classdecl;
typedef struct
{
int lineno;
const char *id;
ast_methoddecl *method;
} ast_mainclass;
typedef struct {
ast_mainclass main_class;
ast_classdecl *class_list;
} ast_program;
// Preprocessor Macros for creating a specific AST struct
#define EXPR_EMPTY(name, expr_type) ast_expr *name = new ast_expr; name->type = expr_type; name->lineno = yylineno; name->next = NULL;
#define EXPR(name, type, assign) EXPR_EMPTY(name, type) name->assign;
#define STATEMENT_EMPTY(name, stmt_type) ast_stmt *name = new ast_stmt; name->type = stmt_type; name->lineno = yylineno; name->next = NULL;
#define STATEMENT(name, type, assign) STATEMENT_EMPTY(name, type) name->assign;
#define VAR_DECLARATION(name, var_type, var_id) ast_vardecl *name = new ast_vardecl; name->type = var_type; name->id = var_id; name->lineno = yylineno; name->next = NULL;
#define VAR_DECLARATION_THIS(name) ast_vardecl *name = new ast_vardecl; ast_type class_type; \
class_type.type = VAR_CLASS; name->type = class_type; name->id = "this"; name->lineno = yylineno; name->next = NULL;
#define TYPE(name, var_type) ast_type name; name.type = var_type;
#define CLASS(name, class_id) TYPE(name, VAR_CLASS); name.classname = class_id;
#define METHOD_DECLARATION(name, method_type, method_id, method_params, method_vars, method_body, method_return) \
ast_methoddecl *name = new ast_methoddecl; name->next = NULL; name->type = method_type; \
name->id = method_id; name->params = method_params; name->var_decl = method_vars; \
name->body = method_body; name->lineno = yylineno; name->return_expr = method_return;
#define CLASS_DECLARATION(name, class_id, class_fields, class_methods) ast_classdecl *name = new ast_classdecl; \
name->lineno = yylineno; name->next = NULL; name->id = class_id; name->fields = class_fields; \
initialize_var_declaration_this(class_methods, class_id); \
name->methods = class_methods;
#define AST_PROGRAM(name, main, classlist) \
ast_program name; name.main_class = main; name.class_list = classlist;
// Map the id of the parent class to `this` in Method(this, arg1, arg2,..)
void initialize_var_declaration_this(ast_methoddecl *class_methods, char* classname);
// Print the AST
void ast_program_print(FILE *file, int indent_level, ast_program *program);
// Return a string representation of the `ast_type` passed in
const char *ast_type_str(ast_type type);
#endif