Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epidemian
GitHub Repository: epidemian/gravity
Path: blob/master/src/compiler/gravity_ast.h
1214 views
1
//
2
// gravity_ast.h
3
// gravity
4
//
5
// Created by Marco Bambini on 02/09/14.
6
// Copyright (c) 2014 CreoLabs. All rights reserved.
7
//
8
9
#ifndef __GRAVITY_AST__
10
#define __GRAVITY_AST__
11
12
#include "debug_macros.h"
13
#include "gravity_array.h"
14
#include "gravity_token.h"
15
16
/*
17
AST can be uniform (the same data struct is used for all expressions/statements/declarations) or
18
non-uniform. I choosed a non-uniform AST node implementation with a common base struct.
19
It requires more work but design and usage is much more cleaner and we benefit from static check.
20
*/
21
22
typedef enum {
23
// statements: 7
24
NODE_LIST_STAT, NODE_COMPOUND_STAT, NODE_LABEL_STAT, NODE_FLOW_STAT, NODE_JUMP_STAT, NODE_LOOP_STAT, NODE_EMPTY_STAT,
25
26
// declarations: 6
27
NODE_ENUM_DECL, NODE_FUNCTION_DECL, NODE_VARIABLE_DECL, NODE_CLASS_DECL, NODE_MODULE_DECL, NODE_VARIABLE,
28
29
// expressions: 8
30
NODE_BINARY_EXPR, NODE_UNARY_EXPR, NODE_FILE_EXPR, NODE_LIST_EXPR, NODE_LITERAL_EXPR, NODE_IDENTIFIER_EXPR,
31
NODE_POSTFIX_EXPR, NODE_KEYWORD_EXPR,
32
33
// postfix subexpression type
34
NODE_CALL_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
35
} gnode_n;
36
37
typedef enum {
38
LOCATION_LOCAL,
39
LOCATION_GLOBAL,
40
LOCATION_UPVALUE,
41
LOCATION_CLASS_IVAR_SAME,
42
LOCATION_CLASS_IVAR_OUTER
43
} gnode_location_type;
44
45
// BASE NODE
46
typedef struct {
47
gnode_n tag; // node type from gnode_n enum
48
uint32_t refcount; // reference count to manage duplicated nodes
49
gtoken_s token; // token type and location
50
bool is_assignment; // flag to check if it is an assignment node
51
} gnode_t;
52
53
// UPVALUE STRUCT
54
typedef struct {
55
gnode_t *node; // reference to the original var node
56
uint32_t index; // can be an index in the stack or in the upvalue list (depending on the is_direct flag)
57
uint32_t selfindex; // always index inside uplist
58
bool is_direct; // flag to check if var is local to the direct enclosing func
59
} gupvalue_t;
60
61
// shortcut for array of common structs
62
typedef marray_t(gnode_t *) gnode_r;
63
typedef marray_t(gupvalue_t *) gupvalue_r;
64
typedef struct symboltable_t symboltable_t;
65
66
// LOCATION
67
typedef struct {
68
gnode_location_type type; // location type
69
uint16_t index; // symbol index
70
uint16_t nup; // upvalue index or outer index
71
} gnode_location_t;
72
73
// STATEMENTS
74
typedef struct {
75
gnode_t base; // NODE_LIST_STAT | NODE_COMPOUND_STAT
76
symboltable_t *symtable; // node internal symbol table
77
gnode_r *stmts; // array of statements node
78
uint32_t nclose; // initialized to UINT32_MAX
79
} gnode_compound_stmt_t;
80
typedef gnode_compound_stmt_t gnode_list_stmt_t;
81
82
typedef struct {
83
gnode_t base; // CASE or DEFAULT
84
gnode_t *expr; // expression in case of CASE
85
gnode_t *stmt; // common statement
86
} gnode_label_stmt_t;
87
88
typedef struct {
89
gnode_t base; // IF, SWITCH, TOK_OP_TERNARY
90
gnode_t *cond; // common condition (it's an expression)
91
gnode_t *stmt; // common statement
92
gnode_t *elsestmt; // optional else statement in case of IF
93
} gnode_flow_stmt_t;
94
95
typedef struct {
96
gnode_t base; // WHILE, REPEAT or FOR
97
gnode_t *cond; // used in WHILE and FOR
98
gnode_t *stmt; // common statement
99
gnode_t *expr; // used in REPEAT and FOR
100
uint32_t nclose; // initialized to UINT32_MAX
101
} gnode_loop_stmt_t;
102
103
typedef struct {
104
gnode_t base; // BREAK, CONTINUE or RETURN
105
gnode_t *expr; // optional expression in case of RETURN
106
} gnode_jump_stmt_t;
107
108
// DECLARATIONS
109
typedef struct {
110
gnode_t base; // FUNCTION_DECL or FUNCTION_EXPR
111
gnode_t *env; // shortcut to node where function is declared
112
gtoken_t access; // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
113
gtoken_t storage; // TOK_KEY_STATIC | TOK_KEY_EXTERN
114
symboltable_t *symtable; // function internal symbol table
115
const char *identifier; // function name
116
gnode_r *params; // function params
117
gnode_compound_stmt_t *block; // internal function statements
118
uint16_t nlocals; // locals counter
119
uint16_t nparams; // formal parameters counter
120
gupvalue_r *uplist; // list of upvalues used in function (can be empty)
121
} gnode_function_decl_t;
122
typedef gnode_function_decl_t gnode_function_expr_t;
123
124
typedef struct {
125
gnode_t base; // VARIABLE
126
gnode_t *env; // shortcut to node where variable is declared
127
const char *identifier; // variable name
128
const char *annotation_type; // optional annotation type
129
gnode_t *expr; // optional assignment expression/declaration
130
gtoken_t access; // optional access token (duplicated value from its gnode_variable_decl_t)
131
uint16_t index; // local variable index (if local)
132
bool upvalue; // flag set if this variable is used as an upvalue
133
} gnode_var_t;
134
135
typedef struct {
136
gnode_t base; // VARIABLE_DECL
137
gtoken_t type; // TOK_KEY_VAR | TOK_KEY_CONST
138
gtoken_t access; // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
139
gtoken_t storage; // TOK_KEY_STATIC | TOK_KEY_EXTERN
140
gnode_r *decls; // variable declarations list (gnode_var_t)
141
} gnode_variable_decl_t;
142
143
typedef struct {
144
gnode_t base; // ENUM_DECL
145
gnode_t *env; // shortcut to node where enum is declared
146
gtoken_t access; // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
147
gtoken_t storage; // TOK_KEY_STATIC | TOK_KEY_EXTERN
148
symboltable_t *symtable; // enum internal hash table
149
const char *identifier; // enum name
150
} gnode_enum_decl_t;
151
152
typedef struct {
153
gnode_t base; // CLASS_DECL
154
bool bridge; // flag to check of a bridged class
155
bool is_struct; // flag to mark the class as a struct
156
gnode_t *env; // shortcut to node where class is declared
157
gtoken_t access; // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
158
gtoken_t storage; // TOK_KEY_STATIC | TOK_KEY_EXTERN
159
const char *identifier; // class name
160
gnode_t *superclass; // super class ptr
161
gnode_r *protocols; // array of protocols (currently unused)
162
gnode_r *decls; // class declarations list
163
symboltable_t *symtable; // class internal symbol table
164
void *data; // used to keep track of super classes
165
uint32_t nivar; // instance variables counter
166
uint32_t nsvar; // static variables counter
167
} gnode_class_decl_t;
168
169
typedef struct {
170
gnode_t base; // MODULE_DECL
171
gnode_t *env; // shortcut to node where module is declared
172
gtoken_t access; // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
173
gtoken_t storage; // TOK_KEY_STATIC | TOK_KEY_EXTERN
174
const char *identifier; // module name
175
gnode_r *decls; // module declarations list
176
symboltable_t *symtable; // module internal symbol table
177
} gnode_module_decl_t;
178
179
// EXPRESSIONS
180
typedef struct {
181
gnode_t base; // BINARY_EXPR
182
gtoken_t op; // operation
183
gnode_t *left; // left node
184
gnode_t *right; // right node
185
} gnode_binary_expr_t;
186
187
typedef struct {
188
gnode_t base; // UNARY_EXPR
189
gtoken_t op; // operation
190
gnode_t *expr; // node
191
} gnode_unary_expr_t;
192
193
typedef struct {
194
gnode_t base; // FILE
195
cstring_r *identifiers; // identifier name
196
gnode_location_t location; // identifier location
197
} gnode_file_expr_t;
198
199
typedef struct {
200
gnode_t base; // LITERAL
201
gliteral_t type; // LITERAL_STRING, LITERAL_FLOAT, LITERAL_INT, LITERAL_BOOL
202
uint32_t len; // used only for TYPE_STRING
203
union {
204
char *str; // LITERAL_STRING
205
double d; // LITERAL_FLOAT
206
int64_t n64; // LITERAL_INT or LITERAL_BOOL
207
} value;
208
} gnode_literal_expr_t;
209
210
typedef struct {
211
gnode_t base; // IDENTIFIER or ID
212
const char *value; // identifier name
213
const char *value2; // NULL for IDENTIFIER (check if just one value or an array)
214
gnode_t *symbol; // pointer to identifier declaration (if any)
215
gnode_location_t location; // location coordinates
216
gupvalue_t *upvalue; // upvalue location reference
217
} gnode_identifier_expr_t;
218
219
typedef struct {
220
gnode_t base; // KEYWORD token
221
} gnode_keyword_expr_t;
222
223
typedef gnode_keyword_expr_t gnode_empty_stmt_t;
224
typedef gnode_keyword_expr_t gnode_base_t;
225
226
typedef struct {
227
gnode_t base; // NODE_CALLFUNC_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
228
gnode_t *id; // id(...) or id[...] or id.
229
gnode_r *list; // list of postfix_subexpr
230
} gnode_postfix_expr_t;
231
232
typedef struct {
233
gnode_t base; // NODE_CALLFUNC_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
234
union {
235
gnode_t *expr; // used in case of NODE_SUBSCRIPT_EXPR or NODE_ACCESS_EXPR
236
gnode_r *args; // used in case of NODE_CALLFUNC_EXPR
237
};
238
} gnode_postfix_subexpr_t;
239
240
typedef struct {
241
gnode_t base; // LIST_EXPR
242
bool ismap; // flag to check if the node represents a map (otehrwise it is a list)
243
gnode_r *list1; // node items (cannot use a symtable here because order is mandatory in array)
244
gnode_r *list2; // used only in case of map
245
} gnode_list_expr_t;
246
247
gnode_t *gnode_jump_stat_create (gtoken_s token, gnode_t *expr);
248
gnode_t *gnode_label_stat_create (gtoken_s token, gnode_t *expr, gnode_t *stmt);
249
gnode_t *gnode_flow_stat_create (gtoken_s token, gnode_t *cond, gnode_t *stmt1, gnode_t *stmt2);
250
gnode_t *gnode_loop_stat_create (gtoken_s token, gnode_t *cond, gnode_t *stmt, gnode_t *expr);
251
gnode_t *gnode_block_stat_create (gnode_n type, gtoken_s token, gnode_r *stmts);
252
gnode_t *gnode_empty_stat_create (gtoken_s token);
253
254
gnode_t *gnode_enum_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, symboltable_t *symtable);
255
gnode_t *gnode_class_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_t *superclass, gnode_r *protocols, gnode_r *declarations, bool is_struct);
256
gnode_t *gnode_module_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *declarations);
257
gnode_t *gnode_variable_decl_create (gtoken_s token, gtoken_t type, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *declarations);
258
gnode_t *gnode_variable_create (gtoken_s token, const char *identifier, const char *annotation_type, gtoken_t storage_specifier, gnode_t *expr);
259
260
gnode_t *gnode_function_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *params, gnode_compound_stmt_t *block);
261
262
gnode_t *gnode_binary_expr_create (gtoken_t op, gnode_t *left, gnode_t *right);
263
gnode_t *gnode_unary_expr_create (gtoken_t op, gnode_t *expr);
264
gnode_t *gnode_file_expr_create (gtoken_s token, cstring_r *list);
265
gnode_t *gnode_identifier_expr_create (gtoken_s token, const char *identifier, const char *identifier2);
266
gnode_t *gnode_literal_string_expr_create (gtoken_s token, const char *s, uint32_t len);
267
gnode_t *gnode_literal_float_expr_create (gtoken_s token, double f);
268
gnode_t *gnode_literal_int_expr_create (gtoken_s token, int64_t n);
269
gnode_t *gnode_literal_bool_expr_create (gtoken_s token, int32_t n);
270
gnode_t *gnode_keyword_expr_create (gtoken_s token);
271
gnode_t *gnode_postfix_subexpr_create (gtoken_s token, gnode_n type, gnode_t *expr, gnode_r *list);
272
gnode_t *gnode_postfix_expr_create (gtoken_s token, gnode_t *id, gnode_r *list);
273
gnode_t *gnode_list_expr_create (gtoken_s token, gnode_r *list1, gnode_r *list2, bool ismap);
274
275
gnode_t *gnode_duplicate (gnode_t *node, bool deep);
276
gnode_r *gnode_array_create (void);
277
gnode_r *gnode_array_remove_byindex(gnode_r *list, size_t index);
278
gupvalue_t *gnode_function_add_upvalue(gnode_function_decl_t *f, gnode_var_t *symbol, uint16_t n);
279
cstring_r *cstring_array_create (void);
280
void_r *void_array_create (void);
281
void gnode_array_sethead(gnode_r *list, gnode_t *node);
282
283
bool gnode_is_equal (gnode_t *node1, gnode_t *node2);
284
bool gnode_is_expression (gnode_t *node);
285
bool gnode_is_literal (gnode_t *node);
286
bool gnode_is_literal_int (gnode_t *node);
287
bool gnode_is_literal_number (gnode_t *node);
288
bool gnode_is_literal_string (gnode_t *node);
289
void gnode_literal_dump (gnode_literal_expr_t *node, char *buffer, int buffersize);
290
void gnode_free (gnode_t *node);
291
292
// MARK: -
293
294
#define gnode_array_init(r) marray_init(*r)
295
#define gnode_array_size(r) ((r) ? marray_size(*r) : 0)
296
#define gnode_array_push(r, node) marray_push(gnode_t*,*r,node)
297
#define gnode_array_pop(r) (marray_size(*r) ? marray_pop(*r) : NULL)
298
#define gnode_array_get(r, i) (((i) >= 0 && (i) < marray_size(*r)) ? marray_get(*r, (i)) : NULL)
299
#define gnode_array_free(r) do {marray_destroy(*r); mem_free((void*)r);} while (0)
300
#define gtype_array_each(r, block, type) { size_t _len = gnode_array_size(r); \
301
for (size_t _i=0; _i<_len; ++_i) { \
302
type val = (type)gnode_array_get(r, _i); \
303
block;} \
304
}
305
#define gnode_array_each(r, block) gtype_array_each(r, block, gnode_t*)
306
#define gnode_array_eachbase(r, block) gtype_array_each(r, block, gnode_base_t*)
307
308
#define cstring_array_free(r) marray_destroy(*r)
309
#define cstring_array_push(r, s) marray_push(const char*,*r,s)
310
#define cstring_array_each(r, block) gtype_array_each(r, block, const char*)
311
312
#define NODE_TOKEN_TYPE(_node) _node->base.token.type
313
#define NODE_TAG(_node) ((gnode_base_t *)_node)->base.tag
314
#define NODE_ISA(_node,_tag) (NODE_TAG(_node) == _tag)
315
#define NODE_ISA_FUNCTION(_node) (NODE_ISA(_node, NODE_FUNCTION_DECL))
316
#define NODE_ISA_CLASS(_node) (NODE_ISA(_node, NODE_CLASS_DECL))
317
318
#endif
319
320