99054b671fc61223fa5f101c5fa54c538f13ba2c
[m6w6/ext-psi] / src / parser_proc.y
1 %include {
2 #include <assert.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "parser.h"
7
8 }
9
10 %name PSI_ParserProc
11 %token_prefix PSI_T_
12 %token_type {PSI_Token *}
13 %token_destructor {free($$);}
14 %default_destructor {(void)P;}
15 %extra_argument {PSI_Parser *P}
16 /* TOKEN is defined inside syntax_error */
17 %syntax_error {
18 if (TOKEN) {
19 PSI_ParserSyntaxError(P, P->psi.file.fn, P->line, "Unexpected token '%s'", TOKEN->text);
20 } else {
21 PSI_ParserSyntaxError(P, P->psi.file.fn, P->line, "Unexpected end of input");
22 }
23 }
24
25 %nonassoc NAME.
26 %fallback NAME FREE SET LET RETURN LIB INT.
27
28 file ::= blocks.
29
30 blocks ::= block.
31 blocks ::= blocks block.
32
33 block ::= LIB(T) QUOTED_STRING(libname) EOS. {
34 if (P->psi.file.ln) {
35 PSI_ParserSyntaxError(P, P->psi.file.ln, T->line, "Extra 'lib %s' statement has no effect", libname->text);
36 } else {
37 P->psi.file.ln = strndup(libname->text + 1, libname->size - 2);
38 }
39 free(libname);
40 free(T);
41 }
42
43 block ::= decl(decl). {
44 P->decls = add_decl(P->decls, decl);
45 }
46 block ::= impl(impl). {
47 P->impls = add_impl(P->impls, impl);
48 }
49 block ::= decl_typedef(def). {
50 P->defs = add_decl_typedef(P->defs, def);
51 if (def->type->strct) {
52 P->structs = add_decl_struct(P->structs, def->type->strct);
53 }
54 }
55 block ::= constant(constant). {
56 P->consts = add_constant(P->consts, constant);
57 }
58 block ::= decl_struct(strct). {
59 P->structs = add_decl_struct(P->structs, strct);
60 }
61
62 %type decl_struct {decl_struct*}
63 %destructor decl_struct {free_decl_struct($$);}
64 decl_struct(strct) ::= STRUCT NAME(N) struct_size(size_) LBRACE struct_args(args) RBRACE. {
65 strct = init_decl_struct(N->text, args);
66 strct->size = size_;
67 free(N);
68 }
69
70 %type struct_size {size_t}
71 struct_size(size) ::= . {
72 size = 0;
73 }
74 struct_size(size) ::= COLON COLON LPAREN NUMBER(SIZ) RPAREN. {
75 size = atol(SIZ->text);
76 free(SIZ);
77 }
78
79 %token_class const_type_token BOOL INT FLOAT STRING.
80 %type const_type {const_type*}
81 %destructor const_type {free_const_type($$);}
82 const_type(type_) ::= const_type_token(T). {
83 type_ = init_const_type(T->type, T->text);
84 free(T);
85 }
86 %type constant {constant*}
87 %destructor constant {free_constant($$);}
88 constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val) EOS. {
89 constant = init_constant(type, T->text, val);
90 free(T);
91 }
92
93 %type decl_typedef {decl_typedef*}
94 %destructor decl_typedef {free_decl_typedef($$);}
95 decl_typedef(def) ::= TYPEDEF decl_type(type) NAME(ALIAS) EOS. {
96 def = init_decl_typedef(ALIAS->text, type);
97 free(ALIAS);
98 }
99 /* support opaque types */
100 decl_typedef(def) ::= TYPEDEF VOID(V) NAME(ALIAS) EOS. {
101 def = init_decl_typedef(ALIAS->text, init_decl_type(V->type, V->text));
102 free(V);
103 free(ALIAS);
104 }
105 decl_typedef(def) ::= TYPEDEF STRUCT(S) NAME(N) NAME(ALIAS) EOS. {
106 def = init_decl_typedef(ALIAS->text, init_decl_type(S->type, N->text));
107 free(ALIAS);
108 free(S);
109 free(N);
110 }
111 decl_typedef(def) ::= TYPEDEF decl_struct(s) NAME(ALIAS) EOS. {
112 def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_STRUCT, s->name));
113 def->type->strct = s;
114 free(ALIAS);
115 }
116
117 %type decl {decl*}
118 %destructor decl {free_decl($$);}
119 decl(decl) ::= decl_abi(abi) decl_func(func) LPAREN decl_args(args) RPAREN EOS. {
120 decl = init_decl(abi, func, args);
121 }
122
123 %type decl_func {decl_arg*}
124 %destructor decl_func {free_decl_arg($$);}
125 decl_func(func) ::= decl_arg(arg). {
126 func = arg;
127 }
128 /* special case for void functions */
129 decl_func(func) ::= VOID(T) NAME(N). {
130 func = init_decl_arg(
131 init_decl_type(T->type, T->text),
132 init_decl_var(N->text, 0, 0)
133 );
134 free(T);
135 free(N);
136 }
137
138 %type decl_abi {decl_abi*}
139 %destructor decl_abi {free_decl_abi($$);}
140 decl_abi(abi) ::= NAME(T). {
141 abi = init_decl_abi(T->text);
142 free(T);
143 }
144
145 %type decl_var {decl_var*}
146 %destructor decl_var {free_decl_var($$);}
147 decl_var(var) ::= indirection(p) NAME(T). {
148 var = init_decl_var(T->text, p, 0);
149 free(T);
150 }
151 decl_var(var) ::= indirection(p) NAME(T) LBRACKET NUMBER(D) RBRACKET. {
152 var = init_decl_var(T->text, p+1, atol(D->text));
153 free(T);
154 free(D);
155 }
156
157 %type decl_vars {decl_vars*}
158 %destructor decl_vars {free_decl_vars($$);}
159 decl_vars(vars) ::= decl_var(var). {
160 vars = init_decl_vars(var);
161 }
162 decl_vars(vars) ::= decl_vars(vars_) COMMA decl_var(var). {
163 vars = add_decl_var(vars_, var);
164 }
165
166 %type decl_arg {decl_arg*}
167 %destructor decl_arg {free_decl_arg($$);}
168 decl_arg(arg_) ::= const_decl_type(type) decl_var(var). {
169 arg_ = init_decl_arg(type, var);
170 }
171 /* void pointers need a specific rule */
172 decl_arg(arg_) ::= VOID(T) pointers(p) NAME(N). {
173 arg_ = init_decl_arg(
174 init_decl_type(T->type, T->text),
175 init_decl_var(N->text, p, 0)
176 );
177 free(T);
178 free(N);
179 }
180 decl_arg(arg_) ::= CONST VOID(T) pointers(p) NAME(N). {
181 arg_ = init_decl_arg(
182 init_decl_type(T->type, T->text),
183 init_decl_var(N->text, p, 0)
184 );
185 free(T);
186 free(N);
187 }
188
189 %type decl_args {decl_args*}
190 %destructor decl_args {free_decl_args($$);}
191 decl_args ::= .
192 decl_args ::= VOID.
193 decl_args(args) ::= decl_arg(arg). {
194 args = init_decl_args(arg);
195 }
196 decl_args(args) ::= decl_args(args_) COMMA decl_arg(arg). {
197 args = add_decl_arg(args_, arg);
198 }
199 %type struct_args {decl_args*}
200 %destructor struct_args {free_decl_args($$);}
201 struct_args(args) ::= struct_arg(arg). {
202 args = init_decl_args(arg);
203 }
204 struct_args(args) ::= struct_args(args_) struct_arg(arg). {
205 args = add_decl_arg(args_, arg);
206 }
207 %type struct_arg {decl_arg*}
208 %destructor struct_arg {free_decl_arg($$);}
209 struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. {
210 arg_->layout = layout_;
211 arg = arg_;
212 }
213
214 %type struct_layout {decl_struct_layout*}
215 %destructor struct_layout {free_decl_struct_layout($$);}
216 struct_layout(layout) ::= . {
217 layout = NULL;
218 }
219 struct_layout(layout) ::= COLON COLON LPAREN NUMBER(POS) COMMA NUMBER(SIZ) RPAREN. {
220 layout = init_decl_struct_layout(atol(POS->text), atol(SIZ->text));
221 free(POS);
222 free(SIZ);
223 }
224
225 %token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME.
226 %type decl_type {decl_type*}
227 %destructor decl_type {free_decl_type($$);}
228 decl_type(type_) ::= decl_type_token(T). {
229 type_ = init_decl_type(T->type, T->text);
230 free(T);
231 }
232 /* unsigned, urgh */
233 decl_type(type_) ::= UNSIGNED NAME(T). {
234 type_ = init_decl_type(T->type, T->text);
235 type_->name = realloc(type_->name, T->size + sizeof("unsigned"));
236 memmove(type_->name + sizeof("unsigned"), type_->name, T->size);
237 memcpy(type_->name, "unsigned", sizeof("unsigned")-1);
238 type_->name[sizeof("unsigned")] = ' ';
239 type_->name[T->size + sizeof("unsigned")] = 0;
240 }
241 /* we have to support plain int here because we have it in our lexer rules */
242 decl_type(type_) ::= INT(T). {
243 type_ = init_decl_type(PSI_T_NAME, T->text);
244 free(T);
245 }
246 /* structs ! */
247 decl_type(type_) ::= STRUCT(S) NAME(T). {
248 type_ = init_decl_type(S->type, T->text);
249 free(S);
250 free(T);
251 }
252
253 %type const_decl_type {decl_type*}
254 %destructor const_decl_type {free_decl_type($$);}
255 const_decl_type(type) ::= decl_type(type_). {
256 type = type_;
257 }
258 const_decl_type(type) ::= CONST decl_type(type_). {
259 type = type_;
260 }
261
262 %type impl {impl*}
263 %destructor impl {free_impl($$);}
264 impl(impl) ::= impl_func(func) LBRACE impl_stmts(stmts) RBRACE. {
265 impl = init_impl(func, stmts);
266 }
267
268 %type impl_func {impl_func*}
269 %destructor impl_func {free_impl_func($$);}
270 impl_func(func) ::= FUNCTION NSNAME(NAME) impl_args(args) COLON impl_type(type). {
271 func = init_impl_func(NAME->text, args, type, 0);
272 free(NAME);
273 }
274 impl_func(func) ::= FUNCTION REFERENCE NSNAME(NAME) impl_args(args) COLON impl_type(type). {
275 func = init_impl_func(NAME->text, args, type, 1);
276 free(NAME);
277 }
278
279 %token_class impl_def_val_token NULL NUMBER TRUE FALSE QUOTED_STRING.
280 %type impl_def_val {impl_def_val*}
281 %destructor impl_def_val {free_impl_def_val($$);}
282 impl_def_val(def) ::= impl_def_val_token(T). {
283 def = init_impl_def_val(T->type, T->text);
284 free(T);
285 }
286
287 %type impl_var {impl_var*}
288 %destructor impl_var {free_impl_var($$);}
289 impl_var(var) ::= DOLLAR NAME(T). {
290 var = init_impl_var(T->text, 0);
291 free(T);
292 }
293 impl_var(var) ::= REFERENCE DOLLAR NAME(T). {
294 var = init_impl_var(T->text, 1);
295 free(T);
296 }
297
298 %type impl_arg {impl_arg*}
299 %destructor impl_arg {free_impl_arg($$);}
300 impl_arg(arg) ::= impl_type(type) impl_var(var). {
301 arg = init_impl_arg(type, var, NULL);
302 }
303 impl_arg(arg) ::= impl_type(type) impl_var(var) EQUALS impl_def_val(def). {
304 arg = init_impl_arg(type, var, def);
305 }
306
307 %type impl_args {impl_args*}
308 %destructor impl_args {free_impl_args($$);}
309 impl_args(args) ::= LPAREN RPAREN. {
310 args = NULL;
311 }
312 impl_args(args) ::= LPAREN impl_arg_list(args_) RPAREN. {
313 args = args_;
314 }
315 %type impl_arg_list {impl_args*}
316 %destructor impl_arg_list {free_impl_args($$);}
317 impl_arg_list(args) ::= impl_arg(arg). {
318 args = init_impl_args(arg);
319 }
320 impl_arg_list(args) ::= impl_arg_list(args_) COMMA impl_arg(arg). {
321 args = add_impl_arg(args_, arg);
322 }
323
324 %type impl_stmts {impl_stmts*}
325 %destructor impl_stmts {free_impl_stmts($$);}
326 impl_stmts(stmts) ::= impl_stmt(stmt). {
327 stmts = init_impl_stmts(stmt);
328 }
329 impl_stmts(stmts) ::= impl_stmts(stmts_) impl_stmt(stmt). {
330 stmts = add_impl_stmt(stmts_, stmt);
331 }
332
333 %type impl_stmt {impl_stmt*}
334 %destructor impl_stmt {free_impl_stmt($$);}
335 impl_stmt(stmt) ::= let_stmt(let). {
336 stmt = init_impl_stmt(PSI_T_LET, let);
337 }
338 impl_stmt(stmt) ::= set_stmt(set). {
339 stmt = init_impl_stmt(PSI_T_SET, set);
340 }
341 impl_stmt(stmt) ::= return_stmt(ret). {
342 stmt = init_impl_stmt(PSI_T_RETURN, ret);
343 }
344 impl_stmt(stmt) ::= free_stmt(free). {
345 stmt = init_impl_stmt(PSI_T_FREE, free);
346 }
347
348 %type let_stmt {let_stmt*}
349 %destructor let_stmt {free_let_stmt($$);}
350 let_stmt(let) ::= LET decl_var(var) EOS. {
351 let = init_let_stmt(var, NULL);
352 }
353 let_stmt(let) ::= LET decl_var(var) EQUALS let_value(val) EOS. {
354 let = init_let_stmt(var, val);
355 }
356
357 %type let_value {let_value*}
358 %destructor let_value {free_let_value($$);}
359 let_value(val) ::= CALLOC(F) LPAREN NUMBER(N) COMMA decl_type(t) RPAREN. {
360 val = init_let_value(
361 init_let_func(F->type, F->text,
362 init_let_calloc(
363 atol(N->text), t
364 )
365 ), NULL, 0
366 );
367 free(F);
368 free(N);
369 }
370 let_value(val) ::= reference(r) let_func(func) LPAREN impl_var(var) RPAREN. {
371 val = init_let_value(func, var, r);
372 }
373 let_value(val) ::= reference(r) NULL. {
374 val = init_let_value(NULL, NULL, r);
375 }
376
377 %token_class let_func_token ARRVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL.
378 %type let_func {let_func*}
379 %destructor let_func {free_let_func($$);}
380 let_func(func) ::= let_func_token(T). {
381 func = init_let_func(T->type, T->text, NULL);
382 free(T);
383 }
384
385 %type set_stmt {set_stmt*}
386 %destructor set_stmt {free_set_stmt($$);}
387 set_stmt(set) ::= SET impl_var(var) EQUALS set_value(val) EOS. {
388 set = init_set_stmt(var, val);
389 }
390
391 %type set_value {set_value*}
392 %destructor set_value {free_set_value($$);}
393 set_value(val) ::= set_func(func) LPAREN decl_vars(vars) RPAREN. {
394 val = init_set_value(func, vars);
395 }
396 set_value(val) ::= set_func(func_) LPAREN decl_vars(vars_) COMMA set_vals(vals) RPAREN. {
397 val = vals;
398 val->func = func_;
399 val->vars = vars_;
400 }
401 %type set_vals {set_value*}
402 %destructor set_vals {free_set_value($$);}
403 set_vals(vals) ::= set_value(val). {
404 vals = add_inner_set_value(init_set_value(NULL, NULL), val);
405 }
406 set_vals(vals) ::= set_vals(vals_) COMMA set_value(val). {
407 vals = add_inner_set_value(vals_, val);
408 }
409
410 %token_class set_func_token TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL VOID.
411 %type set_func {set_func*}
412 %destructor set_func {free_set_func($$);}
413 set_func(func) ::= set_func_token(T). {
414 func = init_set_func(T->type, T->text);
415 free(T);
416 }
417
418 %type return_stmt {return_stmt*}
419 %destructor return_stmt {free_return_stmt($$);}
420 return_stmt(ret) ::= RETURN set_value(val) EOS. {
421 ret = init_return_stmt(val);
422 }
423
424 %type free_stmt {free_stmt*}
425 %destructor free_stmt {free_free_stmt($$);}
426 free_stmt(free) ::= FREE free_calls(calls) EOS. {
427 free = init_free_stmt(calls);
428 }
429
430 %type free_calls {free_calls*}
431 %destructor free_calls {free_free_calls($$);}
432 free_calls(calls) ::= free_call(call). {
433 calls = init_free_calls(call);
434 }
435 free_calls(calls) ::= free_calls(calls_) COMMA free_call(call). {
436 calls = add_free_call(calls_, call);
437 }
438
439 %type free_call {free_call*}
440 %destructor free_call {free_free_call($$);}
441 free_call(call) ::= NAME(F) LPAREN decl_vars(vars) RPAREN. {
442 call = init_free_call(F->text, vars);
443 }
444
445 %token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY.
446 %type impl_type {impl_type*}
447 %destructor impl_type {free_impl_type($$);}
448 impl_type(type_) ::= impl_type_token(T). {
449 type_ = init_impl_type(T->type, T->text);
450 free(T);
451 }
452
453 %type reference {char}
454 reference(r) ::= . {r = 0;}
455 reference(r) ::= REFERENCE. {r = 1;}
456
457 %type indirection {unsigned}
458 indirection(i) ::= . {i = 0;}
459 indirection(i) ::= pointers(p). {i = p;}
460
461 %type pointers {unsigned}
462 pointers(p) ::= POINTER. {p = 1;}
463 pointers(p) ::= pointers(P) POINTER. {p = P+1;}