enums
[m6w6/ext-psi] / src / parser_proc.y
1 %include {
2 #include <stddef.h>
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdarg.h>
7
8 #include "parser.h"
9
10 void psi_error(int, const char *, int, const char *, ...);
11 }
12
13 %name PSI_ParserProc
14 %token_prefix PSI_T_
15 %token_type {PSI_Token *}
16 %token_destructor {free($$);}
17 %default_destructor {(void)P;}
18 %extra_argument {PSI_Parser *P}
19 /* TOKEN is defined inside syntax_error */
20 %syntax_error {
21 ++P->errors;
22 if (TOKEN && TOKEN->type != PSI_T_EOF) {
23 psi_error(PSI_WARNING, TOKEN->file, TOKEN->line, "PSI syntax error: Unexpected token '%s'", TOKEN->text);
24 } else {
25 psi_error(PSI_WARNING, P->psi.file.fn, P->line, "PSI syntax error: Unexpected end of input");
26 }
27 }
28
29 %nonassoc NAME.
30 %left PLUS MINUS.
31 %left SLASH ASTERISK.
32 %fallback NAME TEMP FREE SET LET RETURN LIB STRING.
33
34 file ::= blocks.
35
36 blocks ::= block.
37 blocks ::= blocks block.
38
39 block ::= EOF.
40 block ::= EOS.
41
42 block ::= LIB(T) QUOTED_STRING(libname) EOS. {
43 if (P->psi.file.ln) {
44 P->error(T, PSI_WARNING, "Extra 'lib %s' statement has no effect", libname->text);
45 } else {
46 P->psi.file.ln = strndup(libname->text + 1, libname->size - 2);
47 }
48 free(libname);
49 free(T);
50 }
51
52 block ::= decl(decl). {
53 P->decls = add_decl(P->decls, decl);
54 }
55 block ::= impl(impl). {
56 P->impls = add_impl(P->impls, impl);
57 }
58 block ::= decl_typedef(def). {
59 P->defs = add_decl_typedef(P->defs, def);
60 if (def->type->strct) {
61 P->structs = add_decl_struct(P->structs, def->type->strct);
62 }
63 }
64 block ::= constant(constant). {
65 P->consts = add_constant(P->consts, constant);
66 }
67 block ::= decl_struct(strct). {
68 P->structs = add_decl_struct(P->structs, strct);
69 }
70 block ::= decl_enum(e). {
71 P->enums = add_decl_enum(P->enums, e);
72 }
73
74 enum_name(n) ::= ENUM NAME(N). {
75 n = N;
76 }
77
78 %type decl_enum {decl_enum *}
79 %destructor decl_enum {free_decl_enum($$);}
80 decl_enum(e) ::= enum_name(N) LBRACE decl_enum_items(list) RBRACE. {
81 e = init_decl_enum(N->text, list);
82 e->token = N;
83 }
84
85 %type decl_enum_items {decl_enum_items*}
86 %destructor decl_enum_items {free_decl_enum_items($$);}
87 decl_enum_items(l) ::= decl_enum_item(i). {
88 l = init_decl_enum_items(i);
89 }
90 decl_enum_items(l) ::= decl_enum_items(l_) COMMA decl_enum_item(i). {
91 l = add_decl_enum_item(l_, i);
92 }
93
94 %type decl_enum_item {decl_enum_item*}
95 %destructor decl_enum_item {free_decl_enum_item($$);}
96 decl_enum_item(i) ::= NAME(N) EQUALS num_exp(num). {
97 i = init_decl_enum_item(N->text, num);
98 i->token = N;
99 }
100 decl_enum_item(i) ::= NAME(N). {
101 i = init_decl_enum_item(N->text, NULL);
102 i->token = N;
103 }
104
105 struct_name(n) ::= STRUCT NAME(N). {
106 n = N;
107 }
108
109 %type decl_struct_args {decl_args*}
110 %destructor decl_struct_args {free_decl_args($$);}
111 decl_struct_args(args_) ::= LBRACE struct_args(args) RBRACE. {
112 args_ = args;
113 }
114 decl_struct_args(args_) ::= EOS. {
115 args_ = init_decl_args(NULL);
116 }
117
118
119 %type decl_struct {decl_struct*}
120 %destructor decl_struct {free_decl_struct($$);}
121 decl_struct(strct) ::= struct_name(N) struct_size(size_) decl_struct_args(args). {
122 strct = init_decl_struct(N->text, args);
123 strct->size = size_;
124 strct->token = N;
125 }
126
127 %type struct_size {size_t}
128 struct_size(size) ::= . {
129 size = 0;
130 }
131 struct_size(size) ::= COLON COLON LPAREN NUMBER(SIZ) RPAREN. {
132 size = atol(SIZ->text);
133 free(SIZ);
134 }
135
136 %token_class const_type_token BOOL INT FLOAT STRING.
137 %type const_type {const_type*}
138 %destructor const_type {free_const_type($$);}
139 const_type(type_) ::= const_type_token(T). {
140 type_ = init_const_type(T->type, T->text);
141 free(T);
142 }
143 %type constant {constant*}
144 %destructor constant {free_constant($$);}
145 constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val) EOS. {
146 constant = init_constant(type, T->text, val);
147 free(T);
148 }
149
150 %type decl_typedef {decl_typedef*}
151 %destructor decl_typedef {free_decl_typedef($$);}
152 decl_typedef(def) ::= TYPEDEF decl_typedef_body(def_) EOS. {
153 def = def_;
154 }
155 %type decl_typedef_body {decl_typedef*}
156 %destructor decl_typedef_body {free_decl_typedef($$);}
157 decl_typedef_body(def) ::= decl_type(type) NAME(ALIAS). {
158 def = init_decl_typedef(ALIAS->text, type);
159 def->token = ALIAS;
160 }
161
162 /* support opaque types */
163 decl_typedef_body(def) ::= VOID(V) indirection(i) NAME(ALIAS). {
164 def = init_decl_typedef(ALIAS->text, init_decl_type(i?PSI_T_POINTER:V->type, V->text));
165 def->token = ALIAS;
166 def->type->token = V;
167 }
168
169 %type decl {decl*}
170 %destructor decl {free_decl($$);}
171 decl(decl) ::= decl_abi(abi) decl_func(func) LPAREN decl_args(args) RPAREN EOS. {
172 decl = init_decl(abi, func, args);
173 }
174
175 %type decl_func {decl_arg*}
176 %destructor decl_func {free_decl_arg($$);}
177 decl_func(func) ::= decl_arg(arg). {
178 func = arg;
179 }
180 /* special case for void functions */
181 decl_func(func) ::= VOID(T) NAME(N). {
182 func = init_decl_arg(
183 init_decl_type(T->type, T->text),
184 init_decl_var(N->text, 0, 0)
185 );
186 func->type->token = T;
187 //free(T);
188 free(N);
189 }
190
191 %type decl_abi {decl_abi*}
192 %destructor decl_abi {free_decl_abi($$);}
193 decl_abi(abi) ::= NAME(T). {
194 abi = init_decl_abi(T->text);
195 abi->token = T;
196 }
197
198 %type decl_var {decl_var*}
199 %destructor decl_var {free_decl_var($$);}
200 decl_var(var) ::= indirection(p) NAME(T). {
201 var = init_decl_var(T->text, p, 0);
202 var->token = T;
203 }
204 decl_var(var) ::= indirection(p) NAME(T) LBRACKET NUMBER(D) RBRACKET. {
205 var = init_decl_var(T->text, p+1, atol(D->text));
206 var->token = T;
207 free(D);
208 }
209
210 %type decl_vars {decl_vars*}
211 %destructor decl_vars {free_decl_vars($$);}
212 decl_vars(vars) ::= decl_var(var). {
213 vars = init_decl_vars(var);
214 }
215 decl_vars(vars) ::= decl_vars(vars_) COMMA decl_var(var). {
216 vars = add_decl_var(vars_, var);
217 }
218
219 %type decl_arg {decl_arg*}
220 %destructor decl_arg {free_decl_arg($$);}
221 decl_arg(arg_) ::= const_decl_type(type) decl_var(var). {
222 arg_ = init_decl_arg(type, var);
223 }
224 /* void pointers need a specific rule */
225 decl_arg(arg_) ::= VOID(T) pointers(p) NAME(N). {
226 arg_ = init_decl_arg(
227 init_decl_type(T->type, T->text),
228 init_decl_var(N->text, p, 0)
229 );
230 arg_->type->token = T;
231 arg_->var->token = N;
232 arg_->token = N;
233 }
234 decl_arg(arg_) ::= CONST VOID(T) pointers(p) NAME(N). {
235 arg_ = init_decl_arg(
236 init_decl_type(T->type, T->text),
237 init_decl_var(N->text, p, 0)
238 );
239 arg_->type->token = T;
240 arg_->var->token = N;
241 arg_->token = N;
242 }
243
244 %type decl_args {decl_args*}
245 %destructor decl_args {free_decl_args($$);}
246 decl_args ::= .
247 decl_args ::= VOID.
248 decl_args(args) ::= decl_arg(arg). {
249 args = init_decl_args(arg);
250 }
251 decl_args(args) ::= decl_args(args_) COMMA decl_arg(arg). {
252 args = add_decl_arg(args_, arg);
253 }
254 decl_args(args) ::= decl_args(args_) COMMA ELLIPSIS. {
255 args = args_;
256 args->varargs = 1;
257 }
258 %type struct_args {decl_args*}
259 %destructor struct_args {free_decl_args($$);}
260 struct_args(args) ::= struct_arg(arg). {
261 args = init_decl_args(arg);
262 }
263 struct_args(args) ::= struct_args(args_) struct_arg(arg). {
264 args = add_decl_arg(args_, arg);
265 }
266 %type struct_arg {decl_arg*}
267 %destructor struct_arg {free_decl_arg($$);}
268 struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. {
269 arg_->layout = layout_;
270 arg = arg_;
271 }
272
273 %type struct_layout {decl_struct_layout*}
274 %destructor struct_layout {free_decl_struct_layout($$);}
275 struct_layout(layout) ::= . {
276 layout = NULL;
277 }
278 struct_layout(layout) ::= COLON COLON LPAREN NUMBER(POS) COMMA NUMBER(SIZ) RPAREN. {
279 layout = init_decl_struct_layout(atol(POS->text), atol(SIZ->text));
280 free(POS);
281 free(SIZ);
282 }
283
284 /* un/signed, urgh */
285 decl_scalar_type(type_) ::= CHAR(C). {
286 type_ = C;
287 }
288 decl_scalar_type(type_) ::= SHORT(S) decl_scalar_type_short(s). {
289 if (s) {
290 type_ = PSI_TokenCat(2, S, s);
291 free(S);
292 free(s);
293 } else {
294 type_ = S;
295 }
296 }
297 decl_scalar_type_short(s) ::= . {
298 s = NULL;
299 }
300
301 decl_scalar_type_short(s) ::= INT(I). {
302 s = I;
303 }
304 decl_scalar_type(type_) ::= INT(I). {
305 type_ = I;
306 }
307 decl_scalar_type(type_) ::= LONG(L) decl_scalar_type_long(l). {
308 if (l) {
309 type_ = PSI_TokenCat(2, L, l);
310 free(L);
311 free(l);
312 } else {
313 type_ = L;
314 }
315 }
316 decl_scalar_type_long(l) ::= . {
317 l = NULL;
318 }
319 decl_scalar_type_long(l) ::= DOUBLE(D). {
320 l = D;
321 }
322 decl_scalar_type_long(l) ::= LONG(L) decl_scalar_type_long_long(ll). {
323 if (ll) {
324 l = PSI_TokenCat(2, L, ll);
325 free(L);
326 free(ll);
327 } else {
328 l = L;
329 }
330 }
331 decl_scalar_type_long_long(ll) ::= . {
332 ll = NULL;
333 }
334 decl_scalar_type_long_long(ll) ::= INT(I). {
335 ll = I;
336 }
337 decl_type(type_) ::= UNSIGNED(U) decl_scalar_type(N). {
338 PSI_Token *T = PSI_TokenCat(2, U, N);
339 type_ = init_decl_type(T->type, T->text);
340 type_->token = T;
341 free(U);
342 free(N);
343 }
344 decl_type(type_) ::= SIGNED(S) decl_scalar_type(N). {
345 PSI_Token *T = PSI_TokenCat(2, S, N);
346 type_ = init_decl_type(T->type, T->text);
347 type_->token = T;
348 free(S);
349 free(N);
350 }
351 decl_type(type_) ::= UNSIGNED(U). {
352 type_ = init_decl_type(PSI_T_NAME, U->text);
353 type_->token = U;
354 }
355 decl_type(type_) ::= SIGNED(S). {
356 type_ = init_decl_type(PSI_T_NAME, S->text);
357 type_->token = S;
358 }
359 decl_type(type_) ::= decl_scalar_type(N). {
360 type_ = init_decl_type(N->type, N->text);
361 type_->token = N;
362 }
363 /* structs ! */
364 decl_type(type_) ::= STRUCT(S) NAME(T). {
365 type_ = init_decl_type(S->type, T->text);
366 type_->token = T;
367 free(S);
368 }
369 decl_type(type_) ::= ENUM(E) NAME(T). {
370 type_ = init_decl_type(E->type, T->text);
371 type_->token = T;
372 free(E);
373 }
374 %token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME.
375 %type decl_type {decl_type*}
376 %destructor decl_type {free_decl_type($$);}
377 decl_type(type_) ::= decl_type_token(T). {
378 type_ = init_decl_type(T->type, T->text);
379 type_->token = T;
380 }
381
382
383 %type const_decl_type {decl_type*}
384 %destructor const_decl_type {free_decl_type($$);}
385 const_decl_type(type) ::= decl_type(type_). {
386 type = type_;
387 }
388 const_decl_type(type) ::= CONST decl_type(type_). {
389 type = type_;
390 }
391
392 %type impl {impl*}
393 %destructor impl {free_impl($$);}
394 impl(impl) ::= impl_func(func) LBRACE impl_stmts(stmts) RBRACE. {
395 impl = init_impl(func, stmts);
396 }
397
398 %type impl_func {impl_func*}
399 %destructor impl_func {free_impl_func($$);}
400 impl_func(func) ::= FUNCTION reference(r) NSNAME(NAME) impl_args(args) COLON impl_type(type). {
401 func = init_impl_func(NAME->text, args, type, r);
402 func->token = NAME;
403 }
404
405 %token_class impl_def_val_token NULL NUMBER TRUE FALSE QUOTED_STRING.
406 %type impl_def_val {impl_def_val*}
407 %destructor impl_def_val {free_impl_def_val($$);}
408 impl_def_val(def) ::= impl_def_val_token(T). {
409 def = init_impl_def_val(T->type, T->text);
410 free(T);
411 }
412
413 %type impl_var {impl_var*}
414 %destructor impl_var {free_impl_var($$);}
415 impl_var(var) ::= reference(r) DOLLAR NAME(T). {
416 var = init_impl_var(T->text, r);
417 var->token = T;
418 }
419
420 %type impl_arg {impl_arg*}
421 %destructor impl_arg {free_impl_arg($$);}
422 impl_arg(arg) ::= impl_type(type) impl_var(var). {
423 arg = init_impl_arg(type, var, NULL);
424 }
425 impl_arg(arg) ::= impl_type(type) impl_var(var) EQUALS impl_def_val(def). {
426 arg = init_impl_arg(type, var, def);
427 }
428
429 %type impl_args {impl_args*}
430 %destructor impl_args {free_impl_args($$);}
431 impl_args(args) ::= LPAREN RPAREN. {
432 args = NULL;
433 }
434 impl_args(args) ::= LPAREN impl_arg_list(args_) RPAREN. {
435 args = args_;
436 }
437 impl_args(args) ::= LPAREN impl_arg_list(args_) COMMA impl_vararg(va) RPAREN. {
438 args = args_;
439 args->vararg.name = va;
440 }
441
442 %type impl_vararg {impl_arg*}
443 %destructor impl_vararg {free_impl_arg($$);}
444 impl_vararg(va) ::= impl_type(type) reference(r) ELLIPSIS DOLLAR NAME(T). {
445 va = init_impl_arg(type, init_impl_var(T->text, r), NULL);
446 free(T);
447 }
448
449 %type impl_arg_list {impl_args*}
450 %destructor impl_arg_list {free_impl_args($$);}
451 impl_arg_list(args) ::= impl_arg(arg). {
452 args = init_impl_args(arg);
453 }
454 impl_arg_list(args) ::= impl_arg_list(args_) COMMA impl_arg(arg). {
455 args = add_impl_arg(args_, arg);
456 }
457
458 %type impl_stmts {impl_stmts*}
459 %destructor impl_stmts {free_impl_stmts($$);}
460 impl_stmts(stmts) ::= impl_stmt(stmt). {
461 stmts = init_impl_stmts(stmt);
462 }
463 impl_stmts(stmts) ::= impl_stmts(stmts_) impl_stmt(stmt). {
464 stmts = add_impl_stmt(stmts_, stmt);
465 }
466
467 %type impl_stmt {impl_stmt*}
468 %destructor impl_stmt {free_impl_stmt($$);}
469 impl_stmt(stmt) ::= let_stmt(let). {
470 stmt = init_impl_stmt(PSI_T_LET, let);
471 }
472 impl_stmt(stmt) ::= set_stmt(set). {
473 stmt = init_impl_stmt(PSI_T_SET, set);
474 }
475 impl_stmt(stmt) ::= return_stmt(ret). {
476 stmt = init_impl_stmt(PSI_T_RETURN, ret);
477 }
478 impl_stmt(stmt) ::= free_stmt(free). {
479 stmt = init_impl_stmt(PSI_T_FREE, free);
480 }
481
482 %token_class num_exp_token NUMBER NSNAME.
483 %token_class num_exp_op_token PLUS MINUS ASTERISK SLASH.
484 %type num_exp {num_exp*}
485 %destructor num_exp {free_num_exp($$);}
486 num_exp(exp) ::= num_exp_token(tok). {
487 exp = init_num_exp(tok->type, tok->text);
488 exp->token = tok;
489 }
490 num_exp(exp) ::= decl_var(var). {
491 exp = init_num_exp(PSI_T_NAME, var);
492 exp->token = PSI_TokenCopy(var->token);
493 }
494 num_exp(exp) ::= num_exp(exp_) num_exp_op_token(operator_) num_exp(operand_). {
495 exp_->operator = operator_->type;
496 exp_->operand = operand_;
497 exp = exp_;
498 free(operator_);
499 }
500
501 %type let_stmt {let_stmt*}
502 %destructor let_stmt {free_let_stmt($$);}
503 let_stmt(let) ::= LET decl_var(var) EOS. {
504 let = init_let_stmt(var, init_let_val(PSI_LET_NULL, NULL));
505 }
506 let_stmt(let) ::= LET decl_var(var) EQUALS reference(r) let_val(val) EOS. {
507 val->flags.one.is_reference = r ? 1 : 0;
508 let = init_let_stmt(var, val);
509 }
510 let_stmt(let) ::= TEMP decl_var(var) EQUALS decl_var(val) EOS. {
511 let = init_let_stmt(var, init_let_val(PSI_LET_TMP, val));
512 }
513
514 %type let_val {let_val*}
515 %destructor let_val {free_let_val($$);}
516 let_val(val) ::= NULL. {
517 val = init_let_val(PSI_LET_NULL, NULL);
518 }
519 let_val(val) ::= num_exp(exp). {
520 val = init_let_val(PSI_LET_NUMEXP, exp);
521 }
522 let_val(val) ::= CALLOC LPAREN let_calloc(alloc) RPAREN. {
523 val = init_let_val(PSI_LET_CALLOC, alloc);
524 }
525 let_val(val) ::= let_func(func). {
526 val = init_let_val(PSI_LET_FUNC, func);
527 }
528
529 %type let_calloc {let_calloc*}
530 %destructor let_calloc {free_let_calloc($$);}
531 let_calloc(alloc) ::= num_exp(nmemb) COMMA num_exp(size). {
532 alloc = init_let_calloc(nmemb, size);
533 }
534 %token_class let_func_token OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL.
535 %type let_func {let_func*}
536 %destructor let_func {free_let_func($$);}
537 let_func(func) ::= let_func_token(T) LPAREN impl_var(var) RPAREN. {
538 func = init_let_func(T->type, T->text, var);
539 free(T);
540 }
541
542
543 %type set_stmt {set_stmt*}
544 %destructor set_stmt {free_set_stmt($$);}
545 set_stmt(set) ::= SET impl_var(var) EQUALS set_value(val) EOS. {
546 set = init_set_stmt(var, val);
547 }
548
549 %type set_value {set_value*}
550 %destructor set_value {free_set_value($$);}
551 set_value(val) ::= set_func(func) LPAREN decl_var(var) RPAREN. {
552 val = init_set_value(func, init_decl_vars(var));
553 }
554 set_value(val) ::= set_func(func) LPAREN decl_var(var) COMMA num_exp(num_) RPAREN. {
555 val = init_set_value(func, init_decl_vars(var));
556 val->num = num_;
557 }
558 set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA ELLIPSIS(T) RPAREN. {
559 free_set_func(func_);
560 val = init_set_value(init_set_func(T->type, T->text), init_decl_vars(var));
561 val->func->token = T;
562 }
563 set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA set_vals(vals) RPAREN. {
564 val = vals;
565 val->func = func_;
566 val->vars = init_decl_vars(var);
567 }
568 set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA num_exp(num_) COMMA set_vals(vals) RPAREN. {
569 val = vals;
570 val->func = func_;
571 val->num = num_;
572 val->vars = init_decl_vars(var);
573 }
574 %type set_vals {set_value*}
575 %destructor set_vals {free_set_value($$);}
576 set_vals(vals) ::= set_value(val). {
577 vals = add_inner_set_value(init_set_value(NULL, NULL), val);
578 }
579 set_vals(vals) ::= set_vals(vals_) COMMA set_value(val). {
580 vals = add_inner_set_value(vals_, val);
581 }
582
583 %token_class set_func_token TO_OBJECT TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL VOID.
584 %type set_func {set_func*}
585 %destructor set_func {free_set_func($$);}
586 set_func(func) ::= set_func_token(T). {
587 func = init_set_func(T->type, T->text);
588 func->token = T;
589 }
590
591 %type return_stmt {return_stmt*}
592 %destructor return_stmt {free_return_stmt($$);}
593 return_stmt(ret) ::= RETURN(T) set_value(val) EOS. {
594 ret = init_return_stmt(val);
595 ret->token = T;
596 }
597
598 %type free_stmt {free_stmt*}
599 %destructor free_stmt {free_free_stmt($$);}
600 free_stmt(free) ::= FREE free_calls(calls) EOS. {
601 free = init_free_stmt(calls);
602 }
603
604 %type free_calls {free_calls*}
605 %destructor free_calls {free_free_calls($$);}
606 free_calls(calls) ::= free_call(call). {
607 calls = init_free_calls(call);
608 }
609 free_calls(calls) ::= free_calls(calls_) COMMA free_call(call). {
610 calls = add_free_call(calls_, call);
611 }
612
613 %type free_call {free_call*}
614 %destructor free_call {free_free_call($$);}
615 free_call(call) ::= NAME(F) LPAREN decl_vars(vars) RPAREN. {
616 call = init_free_call(F->text, vars);
617 call->token = F;
618 }
619
620 %token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY OBJECT.
621 %type impl_type {impl_type*}
622 %destructor impl_type {free_impl_type($$);}
623 impl_type(type_) ::= impl_type_token(T). {
624 type_ = init_impl_type(T->type, T->text);
625 free(T);
626 }
627
628 %type reference {char}
629 reference(r) ::= . {r = 0;}
630 reference(r) ::= AMPERSAND. {r = 1;}
631
632 %type indirection {unsigned}
633 indirection(i) ::= . {i = 0;}
634 indirection(i) ::= pointers(p). {i = p;}
635
636 %type pointers {unsigned}
637 pointers(p) ::= ASTERISK. {p = 1;}
638 pointers(p) ::= pointers(P) ASTERISK. {p = P+1;}