]> git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
cfd705088ff43fc11673e8e89eba08b6579db294
[xonotic/gmqcc.git] / parser.c
1 #include <stdio.h>
2 #include <stdarg.h>
3
4 #include "gmqcc.h"
5 #include "lexer.h"
6
7 typedef struct {
8     lex_file *lex;
9     int      tok;
10
11     MEM_VECTOR_MAKE(ast_value*, globals);
12     MEM_VECTOR_MAKE(ast_function*, functions);
13     MEM_VECTOR_MAKE(ast_value*, imm_float);
14
15     ast_function *function;
16     MEM_VECTOR_MAKE(ast_value*, locals);
17     size_t blocklocal;
18 } parser_t;
19
20 MEM_VEC_FUNCTIONS(parser_t, ast_value*, globals)
21 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_float)
22 MEM_VEC_FUNCTIONS(parser_t, ast_value*, locals)
23 MEM_VEC_FUNCTIONS(parser_t, ast_function*, functions)
24
25 void parseerror(parser_t *parser, const char *fmt, ...)
26 {
27         va_list ap;
28
29     if (parser)
30             printf("error %s:%lu: ", parser->lex->tok->ctx.file, (unsigned long)parser->lex->tok->ctx.line);
31         else
32             printf("error: ");
33
34         va_start(ap, fmt);
35         vprintf(fmt, ap);
36         va_end(ap);
37
38         printf("\n");
39 }
40
41 bool parser_next(parser_t *parser)
42 {
43     /* lex_do kills the previous token */
44     parser->tok = lex_do(parser->lex);
45     if (parser->tok == TOKEN_EOF || parser->tok >= TOKEN_ERROR)
46         return false;
47     return true;
48 }
49
50 /* lift a token out of the parser so it's not destroyed by parser_next */
51 token *parser_lift(parser_t *parser)
52 {
53     token *tok = parser->lex->tok;
54     parser->lex->tok = NULL;
55     return tok;
56 }
57
58 #define parser_tokval(p) (p->lex->tok->value)
59 #define parser_token(p)  (p->lex->tok)
60 #define parser_ctx(p)    (p->lex->tok->ctx)
61
62 ast_value* parser_const_float(parser_t *parser, double d)
63 {
64     size_t i;
65     ast_value *out;
66     for (i = 0; i < parser->imm_float_count; ++i) {
67         if (parser->imm_float[i]->constval.vfloat == d)
68             return parser->imm_float[i];
69     }
70     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT);
71     out->isconst = true;
72     out->constval.vfloat = d;
73     if (!parser_t_imm_float_add(parser, out)) {
74         ast_value_delete(out);
75         return NULL;
76     }
77     return out;
78 }
79
80 ast_value* parser_find_global(parser_t *parser, const char *name)
81 {
82     size_t i;
83     for (i = 0; i < parser->globals_count; ++i) {
84         if (!strcmp(parser->globals[i]->name, name))
85             return parser->globals[i];
86     }
87     return NULL;
88 }
89
90 ast_value* parser_find_local(parser_t *parser, const char *name, size_t upto)
91 {
92     size_t i;
93     ast_value *fun;
94     for (i = parser->locals_count; i > upto;) {
95         --i;
96         if (!strcmp(parser->locals[i]->name, name))
97             return parser->locals[i];
98     }
99     fun = parser->function->vtype;
100     for (i = 0; i < fun->params_count; ++i) {
101         if (!strcmp(fun->params[i]->name, name))
102             return fun->params[i];
103     }
104     return NULL;
105 }
106
107 ast_value* parser_find_var(parser_t *parser, const char *name)
108 {
109     ast_value *v;
110     v         = parser_find_local(parser, name, 0);
111     if (!v) v = parser_find_global(parser, name);
112     return v;
113 }
114
115 typedef struct {
116     MEM_VECTOR_MAKE(ast_value*, p);
117 } paramlist_t;
118 MEM_VEC_FUNCTIONS(paramlist_t, ast_value*, p)
119
120 static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc)
121 {
122     paramlist_t params;
123     ast_value *var;
124     lex_ctx   ctx = parser_ctx(parser);
125     int vtype = basetype;
126     int temptype;
127     size_t i;
128
129     MEM_VECTOR_INIT(&params, p);
130
131     *isfunc = false;
132
133     if (parser->tok == '(') {
134         *isfunc = true;
135         while (true) {
136             ast_value *param;
137             bool dummy;
138
139             if (!parser_next(parser))
140                 goto on_error;
141
142             if (parser->tok == ')')
143                 break;
144
145             temptype = parser_token(parser)->constval.t;
146             if (!parser_next(parser))
147                 goto on_error;
148
149             param = parser_parse_type(parser, temptype, &dummy);
150             (void)dummy;
151
152             if (!param)
153                 goto on_error;
154
155             if (parser->tok == TOKEN_IDENT) {
156                 /* named parameter */
157                 if (!ast_value_set_name(param, parser_tokval(parser)))
158                     goto on_error;
159                 if (!parser_next(parser))
160                     goto on_error;
161             }
162
163             if (!paramlist_t_p_add(&params, param)) {
164                 parseerror(parser, "Out of memory while parsing typename");
165                 goto on_error;
166             }
167
168             if (parser->tok == ',')
169                 continue;
170             if (parser->tok == ')')
171                 break;
172             parseerror(parser, "Unexpected token");
173             goto on_error;
174         }
175         if (!parser_next(parser))
176             goto on_error;
177     }
178
179     var = ast_value_new(ctx, "<unnamed>", vtype);
180     if (!var)
181         goto on_error;
182     MEM_VECTOR_MOVE(&params, p, var, params);
183     return var;
184 on_error:
185     for (i = 0; i < params.p_count; ++i)
186         ast_value_delete(params.p[i]);
187     MEM_VECTOR_CLEAR(&params, p);
188     return NULL;
189 }
190
191 typedef struct
192 {
193     size_t etype; /* 0 = expression, others are operators */
194     int             paren;
195     ast_expression *out;
196     ast_value      *value; /* need to know if we can assign */
197     ast_block      *block; /* for commas and function calls */
198     lex_ctx ctx;
199 } sy_elem;
200 typedef struct
201 {
202     MEM_VECTOR_MAKE(sy_elem, out);
203     MEM_VECTOR_MAKE(sy_elem, ops);
204 } shunt;
205 MEM_VEC_FUNCTIONS(shunt, sy_elem, out)
206 MEM_VEC_FUNCTIONS(shunt, sy_elem, ops)
207
208 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
209     sy_elem e;
210     e.etype = 0;
211     e.out   = v;
212     e.value = NULL;
213     e.block = NULL;
214     e.ctx   = ctx;
215     e.paren = 0;
216     return e;
217 }
218 static sy_elem syval(lex_ctx ctx, ast_value *v) {
219     sy_elem e;
220     e.etype = 0;
221     e.out   = (ast_expression*)v;
222     e.value = v;
223     e.block = NULL;
224     e.ctx   = ctx;
225     e.paren = 0;
226     return e;
227 }
228
229 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
230     sy_elem e;
231     e.etype = 0;
232     e.out   = (ast_expression*)v;
233     e.value = NULL;
234     e.block = v;
235     e.ctx   = ctx;
236     e.paren = 0;
237     return e;
238 }
239
240 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
241     sy_elem e;
242     e.etype = 1 + (op - operators);
243     e.out   = NULL;
244     e.value = NULL;
245     e.block = NULL;
246     e.ctx   = ctx;
247     e.paren = 0;
248     return e;
249 }
250
251 static sy_elem syparen(lex_ctx ctx, int p) {
252     sy_elem e;
253     e.etype = 0;
254     e.out   = NULL;
255     e.value = NULL;
256     e.block = NULL;
257     e.ctx   = ctx;
258     e.paren = p;
259     return e;
260 }
261
262 static bool parser_sy_pop(parser_t *parser, shunt *sy)
263 {
264     const oper_info *op;
265     lex_ctx ctx;
266     ast_expression *out = NULL;
267     ast_expression *exprs[3];
268     ast_value      *vars[3];
269     ast_block      *blocks[3];
270     size_t i;
271
272     if (!sy->ops_count) {
273         parseerror(parser, "internal error: missing operator");
274         return false;
275     }
276
277     if (sy->ops[sy->ops_count-1].paren) {
278         parseerror(parser, "unmatched parenthesis");
279         return false;
280     }
281
282     op = &operators[sy->ops[sy->ops_count-1].etype - 1];
283     ctx = sy->ops[sy->ops_count-1].ctx;
284
285     if (sy->out_count < op->operands) {
286         parseerror(parser, "internal error: not enough operands: %i", sy->out_count);
287         return false;
288     }
289
290     sy->ops_count--;
291
292     sy->out_count -= op->operands;
293     for (i = 0; i < op->operands; ++i) {
294         exprs[i]  = sy->out[sy->out_count+i].out;
295         vars[i]   = sy->out[sy->out_count+i].value;
296         blocks[i] = sy->out[sy->out_count+i].block;
297     }
298
299     switch (op->id)
300     {
301         default:
302             parseerror(parser, "internal error: unhandled operand");
303             return false;
304
305         case opid1(','):
306             if (blocks[0]) {
307                 if (!ast_block_exprs_add(blocks[0], exprs[1]))
308                     return false;
309             } else {
310                 blocks[0] = ast_block_new(ctx);
311                 if (!ast_block_exprs_add(blocks[0], exprs[0]) ||
312                     !ast_block_exprs_add(blocks[0], exprs[1]))
313                 {
314                     return false;
315                 }
316             }
317             if (!ast_block_set_type(blocks[0], exprs[1]))
318                 return false;
319             out = blocks[0];
320             break;
321
322         case opid1('+'):
323             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
324                 parseerror(parser, "Cannot add type %s and %s",
325                            type_name[exprs[0]->expression.vtype],
326                            type_name[exprs[1]->expression.vtype]);
327                 return false;
328             }
329             switch (exprs[0]->expression.vtype) {
330                 case TYPE_FLOAT:
331                     out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
332                     break;
333                 case TYPE_VECTOR:
334                     out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
335                     break;
336                 default:
337                     parseerror(parser, "Cannot add type %s and %s",
338                                type_name[exprs[0]->expression.vtype],
339                                type_name[exprs[1]->expression.vtype]);
340                     return false;
341             };
342             break;
343         case opid1('-'):
344             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
345                 parseerror(parser, "Cannot subtract type %s from %s",
346                            type_name[exprs[1]->expression.vtype],
347                            type_name[exprs[0]->expression.vtype]);
348                 return false;
349             }
350             switch (exprs[0]->expression.vtype) {
351                 case TYPE_FLOAT:
352                     out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
353                     break;
354                 case TYPE_VECTOR:
355                     out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
356                     break;
357                 default:
358                     parseerror(parser, "Cannot add type %s from %s",
359                                type_name[exprs[1]->expression.vtype],
360                                type_name[exprs[0]->expression.vtype]);
361                     return false;
362             };
363             break;
364         case opid1('*'):
365             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype &&
366                 exprs[0]->expression.vtype != TYPE_VECTOR &&
367                 exprs[0]->expression.vtype != TYPE_FLOAT &&
368                 exprs[1]->expression.vtype != TYPE_VECTOR &&
369                 exprs[1]->expression.vtype != TYPE_FLOAT)
370             {
371                 parseerror(parser, "Cannot multiply type %s from %s",
372                            type_name[exprs[1]->expression.vtype],
373                            type_name[exprs[0]->expression.vtype]);
374                 return false;
375             }
376             switch (exprs[0]->expression.vtype) {
377                 case TYPE_FLOAT:
378                     if (exprs[1]->expression.vtype == TYPE_VECTOR)
379                         out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
380                     else
381                         out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
382                     break;
383                 case TYPE_VECTOR:
384                     if (exprs[1]->expression.vtype == TYPE_FLOAT)
385                         out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
386                     else
387                         out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
388                     break;
389                 default:
390                     parseerror(parser, "Cannot add type %s from %s",
391                                type_name[exprs[1]->expression.vtype],
392                                type_name[exprs[0]->expression.vtype]);
393                     return false;
394             };
395             break;
396         case opid1('/'):
397             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
398                 exprs[0]->expression.vtype != TYPE_FLOAT)
399             {
400                 parseerror(parser, "Cannot divide types %s and %s",
401                            type_name[exprs[0]->expression.vtype],
402                            type_name[exprs[1]->expression.vtype]);
403                 return false;
404             }
405             out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
406             break;
407
408
409         case opid1('='):
410             if (!vars[0]) {
411                 parseerror(parser, "Cannot assign to non-variable");
412                 return false;
413             }
414             out = (ast_expression*)ast_store_new(ctx,
415                                                  type_store_instr[vars[0]->expression.vtype],
416                                                  vars[0], exprs[1]);
417             break;
418     }
419
420     if (!out) {
421         parseerror(parser, "failed to apply operand %s", op->op);
422         return false;
423     }
424
425     sy->out[sy->out_count++] = syexp(ctx, out);
426     return true;
427 }
428
429 static bool parser_close_paren(parser_t *parser, shunt *sy)
430 {
431     if (!sy->ops_count) {
432         parseerror(parser, "unmatched closing paren");
433         return false;
434     }
435     if (sy->ops[sy->ops_count-1].paren == 1) {
436         parseerror(parser, "empty parenthesis expression");
437         return false;
438     }
439     while (sy->ops_count) {
440         if (sy->ops[sy->ops_count-1].paren == 1) {
441             sy->ops_count--;
442             break;
443         }
444         if (!parser_sy_pop(parser, sy))
445             return false;
446     }
447     return true;
448 }
449
450 static ast_expression* parser_expression(parser_t *parser)
451 {
452     ast_expression *expr = NULL;
453     shunt sy;
454     bool wantop = false;
455
456     MEM_VECTOR_INIT(&sy, out);
457     MEM_VECTOR_INIT(&sy, ops);
458
459     while (true)
460     {
461         if (!wantop)
462         {
463             bool nextwant = true;
464             if (parser->tok == TOKEN_IDENT)
465             {
466                 /* variable */
467                 ast_value *var = parser_find_var(parser, parser_tokval(parser));
468                 if (!var) {
469                     parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
470                     goto onerr;
471                 }
472                 if (!shunt_out_add(&sy, syval(parser_ctx(parser), var))) {
473                     parseerror(parser, "out of memory");
474                     goto onerr;
475                 }
476             }
477             else if (parser->tok == TOKEN_FLOATCONST) {
478                 ast_value *val = parser_const_float(parser, (parser_token(parser)->constval.f));
479                 if (!val)
480                     return false;
481                 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
482                     parseerror(parser, "out of memory");
483                     goto onerr;
484                 }
485             }
486             else if (parser->tok == TOKEN_INTCONST) {
487                 ast_value *val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
488                 if (!val)
489                     return false;
490                 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
491                     parseerror(parser, "out of memory");
492                     goto onerr;
493                 }
494             }
495             else if (parser->tok == '(') {
496                 nextwant = false; /* not expecting an operator next */
497                 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1))) {
498                     parseerror(parser, "out of memory");
499                     goto onerr;
500                 }
501             }
502             else {
503                 /* TODO: prefix operators */
504                 parseerror(parser, "expected statement");
505                 goto onerr;
506             }
507             wantop = nextwant;
508             parser->lex->flags.noops = !wantop;
509         } else {
510             if (parser->tok == '(') {
511                 /* we expected an operator, this is the function-call operator */
512                 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f'))) {
513                     parseerror(parser, "out of memory");
514                     goto onerr;
515                 }
516             }
517             else if (parser->tok == ')') {
518                 /* we do expect an operator next */
519                 /* closing an opening paren */
520                 if (!parser_close_paren(parser, &sy))
521                     goto onerr;
522             }
523             else if (parser->tok != TOKEN_OPERATOR) {
524                 parseerror(parser, "expected operator or end of statement");
525                 goto onerr;
526             }
527             else {
528                 /* classify the operator */
529                 /* TODO: suffix operators */
530                 const oper_info *op;
531                 const oper_info *olast = NULL;
532                 size_t o;
533                 for (o = 0; o < operator_count; ++o) {
534                     if (!(operators[o].flags & OP_PREFIX) &&
535                         !(operators[o].flags & OP_SUFFIX) && /* remove this */
536                         !strcmp(parser_tokval(parser), operators[o].op))
537                     {
538                         break;
539                     }
540                 }
541                 if (o == operator_count) {
542                     /* no operator found... must be the end of the statement */
543                     break;
544                 }
545                 /* found an operator */
546                 op = &operators[o];
547
548                 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
549                     olast = &operators[sy.ops[sy.ops_count-1].etype-1];
550
551                 while (olast && (
552                         (op->prec < olast->prec) ||
553                         (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
554                 {
555                     if (!parser_sy_pop(parser, &sy))
556                         goto onerr;
557                     if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
558                         olast = &operators[sy.ops[sy.ops_count-1].etype-1];
559                 }
560
561                 if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
562                     goto onerr;
563             }
564             wantop = false;
565             parser->lex->flags.noops = true;
566         }
567         if (!parser_next(parser)) {
568             goto onerr;
569         }
570         if (parser->tok == ';') {
571             break;
572         }
573     }
574     if (!parser_next(parser)) {
575         parseerror(parser, "Unexpected end of file");
576         goto onerr;
577     }
578
579     while (sy.ops_count) {
580         if (!parser_sy_pop(parser, &sy))
581             goto onerr;
582     }
583
584     parser->lex->flags.noops = true;
585     if (!sy.out_count) {
586         parseerror(parser, "empty expression");
587         expr = NULL;
588     } else
589         expr = sy.out[0].out;
590     MEM_VECTOR_CLEAR(&sy, out);
591     MEM_VECTOR_CLEAR(&sy, ops);
592     return expr;
593
594 onerr:
595     parser->lex->flags.noops = true;
596     MEM_VECTOR_CLEAR(&sy, out);
597     MEM_VECTOR_CLEAR(&sy, ops);
598     return NULL;
599 }
600
601 static bool parser_variable(parser_t *parser, ast_block *localblock);
602 static bool parser_body_do(parser_t *parser, ast_block *block)
603 {
604     if (parser->tok == TOKEN_TYPENAME)
605     {
606         /* local variable */
607         if (!parser_variable(parser, block))
608             return false;
609         return true;
610     }
611     else if (parser->tok == TOKEN_KEYWORD)
612     {
613         if (!strcmp(parser_tokval(parser), "return"))
614         {
615             ast_expression *exp;
616             ast_return *ret;
617
618             if (!parser_next(parser)) {
619                 parseerror(parser, "expected return expression");
620                 return false;
621             }
622
623             exp = parser_expression(parser);
624             if (!exp)
625                 return false;
626             ret = ast_return_new(exp->expression.node.context, exp);
627             if (!ret) {
628                 ast_delete(exp);
629                 return false;
630             }
631             if (!ast_block_exprs_add(block, (ast_expression*)ret)) {
632                 ast_delete(ret);
633                 return false;
634             }
635             return true;
636         }
637         parseerror(parser, "Unexpected keyword");
638         return false;
639     }
640     else if (parser->tok == '{')
641     {
642         /* a block */
643         parseerror(parser, "TODO: inner blocks: %s", parser_tokval(parser));
644         return false;
645     }
646     else
647     {
648         ast_expression *exp = parser_expression(parser);
649         if (!exp)
650             return false;
651         if (!ast_block_exprs_add(block, exp)) {
652             ast_delete(exp);
653             return false;
654         }
655         return true;
656     }
657 }
658
659 static ast_block* parser_parse_block(parser_t *parser)
660 {
661     size_t oldblocklocal;
662     ast_block *block = NULL;
663
664     oldblocklocal = parser->blocklocal;
665     parser->blocklocal = parser->locals_count;
666
667     if (!parser_next(parser)) { /* skip the '{' */
668         parseerror(parser, "expected function body");
669         goto cleanup;
670     }
671
672     block = ast_block_new(parser_ctx(parser));
673
674     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
675     {
676         if (parser->tok == '}')
677             break;
678
679         if (!parser_body_do(parser, block)) {
680             ast_block_delete(block);
681             block = NULL;
682             goto cleanup;
683         }
684     }
685
686     if (parser->tok != '}') {
687         ast_block_delete(block);
688         block = NULL;
689     } else {
690         (void)parser_next(parser);
691     }
692
693 cleanup:
694     parser->blocklocal = oldblocklocal;
695     return block;
696 }
697
698 static bool parser_variable(parser_t *parser, ast_block *localblock)
699 {
700     bool          isfunc = false;
701     ast_function *func = NULL;
702     lex_ctx       ctx;
703     ast_value    *var;
704
705     int basetype = parser_token(parser)->constval.t;
706
707     while (true)
708     {
709         if (!parser_next(parser)) { /* skip basetype or comma */
710             parseerror(parser, "expected variable declaration");
711             return false;
712         }
713
714         isfunc = false;
715         func = NULL;
716         ctx = parser_ctx(parser);
717         var = parser_parse_type(parser, basetype, &isfunc);
718
719         if (!var)
720             return false;
721
722         if (parser->tok != TOKEN_IDENT) {
723             parseerror(parser, "expected variable name\n");
724             return false;
725         }
726
727         if (!localblock && parser_find_global(parser, parser_tokval(parser))) {
728             ast_value_delete(var);
729             parseerror(parser, "global already exists: %s\n", parser_tokval(parser));
730             return false;
731         }
732
733         if (localblock && parser_find_local(parser, parser_tokval(parser), parser->blocklocal)) {
734             ast_value_delete(var);
735             parseerror(parser, "local variable already exists: %s\n", parser_tokval(parser));
736             return false;
737         }
738
739         if (!ast_value_set_name(var, parser_tokval(parser))) {
740             parseerror(parser, "failed to set variable name\n");
741             ast_value_delete(var);
742             return false;
743         }
744
745         if (isfunc) {
746             /* a function was defined */
747             ast_value *fval;
748
749             /* turn var into a value of TYPE_FUNCTION, with the old var
750              * as return type
751              */
752             fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
753             func = ast_function_new(ctx, var->name, fval);
754             if (!fval || !func) {
755                 ast_value_delete(var);
756                 if (fval) ast_value_delete(fval);
757                 if (func) ast_function_delete(func);
758                 return false;
759             }
760
761             fval->expression.next = (ast_expression*)var;
762             MEM_VECTOR_MOVE(var, params, fval, params);
763
764             if (!parser_t_functions_add(parser, func)) {
765                 ast_value_delete(var);
766                 if (fval) ast_value_delete(fval);
767                 if (func) ast_function_delete(func);
768                 return false;
769             }
770
771             var = fval;
772         }
773
774         if ( (!localblock && !parser_t_globals_add(parser, var)) ||
775              ( localblock && !parser_t_locals_add(parser, var)) )
776         {
777             ast_value_delete(var);
778             return false;
779         }
780         if (localblock && !ast_block_locals_add(localblock, var))
781         {
782             parser->locals_count--;
783             ast_value_delete(var);
784             return false;
785         }
786
787         if (!parser_next(parser)) {
788             ast_value_delete(var);
789             return false;
790         }
791
792         if (parser->tok == ';') {
793             if (!parser_next(parser))
794                 return parser->tok == TOKEN_EOF;
795             return true;
796         }
797
798         if (parser->tok == ',') {
799             /* another var */
800             continue;
801         }
802
803         if (parser->tok != '=') {
804             parseerror(parser, "expected '=' or ';'");
805             return false;
806         }
807
808         if (!parser_next(parser))
809             return false;
810
811         if (parser->tok == '#') {
812             if (localblock) {
813                 parseerror(parser, "cannot declare builtins within functions");
814                 return false;
815             }
816             if (!isfunc || !func) {
817                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
818                 return false;
819             }
820             if (!parser_next(parser)) {
821                 parseerror(parser, "expected builtin number");
822                 return false;
823             }
824             if (parser->tok != TOKEN_INTCONST) {
825                 parseerror(parser, "builtin number must be an integer constant");
826                 return false;
827             }
828             if (parser_token(parser)->constval.i <= 0) {
829                 parseerror(parser, "builtin number must be positive integer greater than zero");
830                 return false;
831             }
832
833             func->builtin = -parser_token(parser)->constval.i;
834         } else if (parser->tok == '{') {
835             /* function body */
836             ast_block *block;
837             ast_function *old = parser->function;
838
839             if (localblock) {
840                 parseerror(parser, "cannot declare functions within functions");
841                 return false;
842             }
843
844             parser->function = func;
845             block = parser_parse_block(parser);
846             parser->function = old;
847
848             if (!block)
849                 return false;
850
851             if (!ast_function_blocks_add(func, block)) {
852                 ast_block_delete(block);
853                 return false;
854             }
855             return true;
856         } else {
857             parseerror(parser, "TODO, const assignment");
858         }
859
860         if (!parser_next(parser))
861             return false;
862
863         if (parser->tok == ',') {
864             /* another */
865             continue;
866         }
867
868         if (parser->tok != ';') {
869             parseerror(parser, "expected semicolon");
870             return false;
871         }
872
873         (void)parser_next(parser);
874
875         return true;
876     }
877 }
878
879 static bool parser_do(parser_t *parser)
880 {
881     if (parser->tok == TOKEN_TYPENAME)
882     {
883         return parser_variable(parser, NULL);
884     }
885     else if (parser->tok == TOKEN_KEYWORD)
886     {
887         /* handle 'var' and 'const' */
888         return false;
889     }
890     else if (parser->tok == '.')
891     {
892         /* entity-member declaration */
893         return false;
894     }
895     else
896     {
897         parseerror(parser, "unexpected token: %s", parser->lex->tok->value);
898         return false;
899     }
900     return true;
901 }
902
903 bool parser_compile(const char *filename)
904 {
905     size_t i;
906     parser_t *parser;
907     ir_builder *ir;
908
909     parser = (parser_t*)mem_a(sizeof(parser_t));
910     if (!parser)
911         return false;
912
913     memset(parser, 0, sizeof(parser));
914
915     MEM_VECTOR_INIT(parser, globals);
916     MEM_VECTOR_INIT(parser, locals);
917     parser->lex = lex_open(filename);
918
919     if (!parser->lex) {
920         printf("failed to open file \"%s\"\n", filename);
921         return false;
922     }
923
924     /* initial lexer/parser state */
925     parser->lex->flags.noops = true;
926
927     if (parser_next(parser))
928     {
929         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
930         {
931             if (!parser_do(parser)) {
932                 if (parser->tok == TOKEN_EOF)
933                     parseerror(parser, "unexpected eof");
934                 else
935                     parseerror(parser, "parse error\n");
936                 lex_close(parser->lex);
937                 mem_d(parser);
938                 return false;
939             }
940         }
941     }
942
943     lex_close(parser->lex);
944
945     ir = ir_builder_new("gmqcc_out");
946     if (!ir) {
947         printf("failed to allocate builder\n");
948         goto cleanup;
949     }
950
951     for (i = 0; i < parser->imm_float_count; ++i) {
952         if (!ast_global_codegen(parser->imm_float[i], ir)) {
953             printf("failed to generate global %s\n", parser->imm_float[i]->name);
954         }
955     }
956     for (i = 0; i < parser->globals_count; ++i) {
957         if (!ast_global_codegen(parser->globals[i], ir)) {
958             printf("failed to generate global %s\n", parser->globals[i]->name);
959         }
960     }
961     for (i = 0; i < parser->functions_count; ++i) {
962         if (!ast_function_codegen(parser->functions[i], ir)) {
963             printf("failed to generate function %s\n", parser->functions[i]->name);
964         }
965         if (!ir_function_finalize(parser->functions[i]->ir_func)) {
966             printf("failed to finalize function %s\n", parser->functions[i]->name);
967         }
968     }
969
970     ir_builder_dump(ir, printf);
971
972 cleanup:
973     for (i = 0; i < parser->globals_count; ++i) {
974         ast_value_delete(parser->globals[i]);
975     }
976     MEM_VECTOR_CLEAR(parser, globals);
977
978     mem_d(parser);
979     return true;
980 }