]> git.xonotic.org Git - xonotic/gmqcc.git/blob - ast.h
ir.c: importing ir_block
[xonotic/gmqcc.git] / ast.h
1 #ifndef GMQCC_AST_H__
2 #define GMQCC_AST_H__
3
4 #include "astir.h"
5 #include "ir.h"
6
7 /* Note: I will not be using a _t suffix for the
8  * "main" ast node types for now.
9  */
10
11 typedef union ast_node_u ast_node;
12 typedef union ast_expression_u ast_expression;
13
14 typedef struct ast_value_s      ast_value;
15 typedef struct ast_function_s   ast_function;
16 typedef struct ast_block_s      ast_block;
17 typedef struct ast_binary_s     ast_binary;
18
19 /* Node interface with common components
20  */
21 typedef void ast_node_delete(ast_node*);
22 typedef struct
23 {
24     lex_ctx_t        context;
25     /* I don't feel comfortable using keywords like 'delete' as names... */
26     ast_node_delete *destroy;
27 } ast_node_common;
28
29 #define ast_delete(x) ( ( (ast_node*)(x) ) -> node.destroy )((ast_node*)(x))
30
31 /* Expression interface
32  *
33  * Any expression or block returns an ir_value, and needs
34  * to know the current function.
35  */
36 typedef qbool ast_expression_codegen(ast_expression*,
37                                      ast_function*,
38                                      ir_value**);
39 typedef struct
40 {
41     ast_node_common         node;
42     ast_expression_codegen *codegen;
43 } ast_expression_common;
44
45 /* Value
46  *
47  * Types are also values, both have a type and a name.
48  * especially considering possible constructs like typedefs.
49  * typedef float foo;
50  * is like creating a 'float foo', foo serving as the type's name.
51  */
52 struct ast_value_s
53 {
54     ast_expression_common expression;
55
56     const char *name;
57
58     int         vtype;
59     ast_value  *next;
60
61     qbool isconst;
62     union {
63         double        vfloat;
64         int           vint;
65         vector_t      vvec;
66         const char   *vstring;
67         int           ventity;
68         ast_function *vfunc;
69     } constval;
70
71     ir_value *ir_v;
72
73     /* if vtype is qc_function, params contain parameters, and
74      * 'next' the return type.
75      */
76     MEM_VECTOR_MAKE(ast_value*, params);
77 };
78 ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int qctype);
79 void ast_value_delete(ast_value*);
80
81 void ast_value_set_name(ast_value*, const char *name);
82
83 qbool ast_value_codegen(ast_value*, ast_function*, ir_value**);
84
85 /* Binary
86  *
87  * A value-returning binary expression.
88  */
89 struct ast_binary_s
90 {
91     ast_expression_common expression;
92
93     int       op;
94     ast_value *left;
95     ast_value *right;
96 };
97 ast_binary* ast_binary_new(lex_ctx_t  ctx,
98                            int        op,
99                            ast_value *left,
100                            ast_value *right);
101 void ast_binary_delete(ast_binary*);
102
103 /* hmm, seperate functions? */
104 qbool ast_bin_add_codegen(ast_binary*, ir_function*, ir_value**);
105 /* ... */
106
107 /* maybe for this one */
108 qbool ast_bin_store_codegen(ast_binary*, ir_function*, ir_value**);
109
110 /* could decide what to use */
111 qbool ast_binary_codegen(ast_binary*, ir_function*, ir_value**);
112
113 /* Blocks
114  *
115  */
116 struct ast_block_s
117 {
118     ast_expression_common expression;
119
120     MEM_VECTOR_MAKE(ast_value*,      locals);
121     MEM_VECTOR_MAKE(ast_expression*, exprs);
122 };
123 ast_block* ast_block_new(lex_ctx_t ctx);
124 void ast_block_delete(ast_block*);
125
126 MEM_VECTOR_PROTO(ast_block, ast_value*, locals);
127 MEM_VECTOR_PROTO(ast_block, ast_expression*, exprs);
128
129 qbool ast_block_codegen(ast_block*, ir_function*, ir_value**);
130
131 /* Function
132  *
133  * Contains a list of blocks... at least in theory.
134  * Usually there's just the main block, other blocks are inside that.
135  *
136  * Technically, functions don't need to be an AST node, since we have
137  * neither functions inside functions, nor lambdas, and function
138  * pointers could just work with a name. However, this way could be
139  * more flexible, and adds no real complexity.
140  */
141 struct ast_function_s
142 {
143     ast_node_common node;
144
145     ast_value  *vtype;
146     const char *name;
147
148     MEM_VECTOR_MAKE(ast_block*, blocks);
149 };
150 ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype);
151 void ast_function_delete(ast_function*);
152
153 MEM_VECTOR_PROTO(ast_function, ast_block*, blocks);
154
155 qbool ast_function_codegen(ast_function *self, ir_builder *builder);
156
157 /* Expression union
158  */
159 union ast_expression_u
160 {
161     ast_expression_common expression;
162
163     ast_binary binary;
164     ast_block  block;
165 };
166
167 /* Node union
168  */
169 union ast_node_u
170 {
171     ast_node_common node;
172     ast_expression  expression;
173 };
174
175 #endif