]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/treelang/parse.y
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / treelang / parse.y
CommitLineData
6cfea11b
TJ
1%{ /* -*- c -*- emacs mode c */
2 /*
3
4 TREELANG Compiler parser.
5
6 ---------------------------------------------------------------------
7
8 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
13 later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.
24
25 In other words, you are welcome to use, share and improve this program.
26 You are forbidden to forbid anyone else to use, share and improve
27 what you give them. Help stamp out software-hoarding!
28
29 ---------------------------------------------------------------------
30
31 Written by Tim Josling 1999-2001, based in part on other parts of
32 the GCC compiler.
33
34 */
35
36 /*
37
38 Grammar Conflicts
39 *****************
40
41 There are no conflicts in this grammar. Please keep it that way.
42
43 */
44
6cfea11b
TJ
45#include "config.h"
46#include "system.h"
4977bab6
ZW
47#include "coretypes.h"
48#include "tm.h"
6cfea11b
TJ
49#include "diagnostic.h"
50
51#include "treelang.h"
52#include "treetree.h"
53
54#define YYDEBUG 1
55#define YYPRINT(file, type, value) print_token (file, type, value)
56#define YYERROR_VERBOSE YES
57
58
59extern int option_parser_trace;
60
61/* Local prototypes. */
62
63static void yyerror (const char *error_message);
64int yylex (void);
65int yyparse (void);
66void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value);
96e3ac4f
TJ
67static struct prod_token_parm_item *reverse_prod_list (struct prod_token_parm_item *old_first);
68static void ensure_not_void (unsigned int type, struct prod_token_parm_item* name);
69static int check_type_match (int type_num, struct prod_token_parm_item *exp);
70static int get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2);
71static struct prod_token_parm_item *make_integer_constant (struct prod_token_parm_item* value);
72static void set_storage (struct prod_token_parm_item *prod);
6cfea11b
TJ
73
74/* File global variables. */
75
96e3ac4f 76static struct prod_token_parm_item *current_function=NULL;
6cfea11b
TJ
77
78%}
79
80/* Not %raw - seems to have bugs. */
81%token_table
82
83/* Punctuation. */
84%token RIGHT_BRACE
85%token LEFT_BRACE
86%token RIGHT_SQUARE_BRACKET
87%token LEFT_SQUARE_BRACKET
88%token RIGHT_PARENTHESIS
89%token LEFT_PARENTHESIS
90%token SEMICOLON
91%token ASTERISK
92%token COMMA
93%right EQUALS
94%right ASSIGN
95%left PLUS
96%left MINUS
97
98/* Literals. */
99%token INTEGER
100
101/* Keywords. */
102%token IF
103%token ELSE
104%token RETURN
105%token CHAR
106%token INT
107%token UNSIGNED
108%token VOID
109%token TYPEDEF
110%token NAME
111%token STATIC
112%token AUTOMATIC
113%token EXTERNAL_DEFINITION
114%token EXTERNAL_REFERENCE
115
116/* Tokens not passed to parser. */
117%token WHITESPACE
118%token COMMENT
119
120/* Pseudo tokens - productions. */
121%token PROD_VARIABLE_NAME
122%token PROD_TYPE_NAME
123%token PROD_FUNCTION_NAME
124%token PROD_INTEGER_CONSTANT
125%token PROD_PLUS_EXPRESSION
126%token PROD_MINUS_EXPRESSION
127%token PROD_ASSIGN_EXPRESSION
128%token PROD_VARIABLE_REFERENCE_EXPRESSION
129%token PROD_PARAMETER
130%token PROD_FUNCTION_INVOCATION
131%expect 0
132%%
133
134file:
135/* Nil. */ {
136 /* Nothing to do. */
137}
138|declarations {
139 /* Nothing to do. */
140}
141;
142
143
144declarations:
145declaration {
146 /* Nothing to do. */
147}
148| declarations declaration {
149 /* Nothing to do. */
150}
151;
152
153declaration:
154variable_def {
155 /* Nothing to do. */
156}
157|function_prototype {
158 /* Nothing to do. */
159}
160|function {
161 /* Nothing to do. */
162}
163;
164
165variable_def:
166storage typename NAME init_opt SEMICOLON {
96e3ac4f
TJ
167 struct prod_token_parm_item* tok;
168 struct prod_token_parm_item *prod;
6cfea11b
TJ
169 tok = $3;
170 prod = make_production (PROD_VARIABLE_NAME, tok);
171 SYMBOL_TABLE_NAME (prod) = tok;
172 EXPRESSION_TYPE (prod) = $2;
173 VAR_INIT (prod) = $4;
96e3ac4f 174 NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
6cfea11b
TJ
175 ensure_not_void (NUMERIC_TYPE (prod), tok);
176 if (insert_tree_name (prod))
177 {
178 YYERROR;
179 }
180 STORAGE_CLASS_TOKEN (prod) = $1;
181 set_storage (prod);
182
183 if (VAR_INIT (prod))
184 {
96e3ac4f 185 if (! ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code)
6cfea11b
TJ
186 abort ();
187 if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
188 {
189 fprintf (stderr, "%s:%i:%i: External reference variables may not have initial value\n", in_fname,
96e3ac4f 190 tok->tp.tok.lineno, tok->tp.tok.charno);
6cfea11b
TJ
191 print_token (stderr, 0, tok);
192 errorcount++;
193 YYERROR;
194 }
195 }
96e3ac4f 196 prod->tp.pro.code = tree_code_create_variable
6cfea11b 197 (STORAGE_CLASS (prod),
96e3ac4f
TJ
198 ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
199 ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
6cfea11b 200 NUMERIC_TYPE (prod),
96e3ac4f 201 VAR_INIT (prod)? ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code:NULL,
6cfea11b 202 in_fname,
96e3ac4f
TJ
203 tok->tp.tok.lineno);
204 if (!prod->tp.pro.code)
6cfea11b
TJ
205 abort ();
206}
207;
208
209storage:
210STATIC
211|AUTOMATIC
212|EXTERNAL_DEFINITION
213|EXTERNAL_REFERENCE
214;
215
216parameter:
217typename NAME {
96e3ac4f
TJ
218 struct prod_token_parm_item* tok;
219 struct prod_token_parm_item *prod;
220 struct prod_token_parm_item *prod2;
6cfea11b
TJ
221 tok = $2;
222 prod = make_production (PROD_VARIABLE_NAME, tok);
223 SYMBOL_TABLE_NAME (prod) = $2;
224 EXPRESSION_TYPE (prod) = $1;
96e3ac4f 225 NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
6cfea11b
TJ
226 ensure_not_void (NUMERIC_TYPE (prod), tok);
227 if (insert_tree_name (prod))
228 {
229 YYERROR;
230 }
231 prod2 = make_production (PROD_PARAMETER, tok);
232 VARIABLE (prod2) = prod;
233 $$ = prod2;
234}
235;
236
237function_prototype:
238storage typename NAME LEFT_PARENTHESIS parameters RIGHT_PARENTHESIS SEMICOLON {
96e3ac4f
TJ
239 struct prod_token_parm_item* tok;
240 struct prod_token_parm_item *prod;
241 struct prod_token_parm_item *type;
242 struct prod_token_parm_item* first_parms;
243 struct prod_token_parm_item* last_parms;
244 struct prod_token_parm_item* this_parms;
245 struct prod_token_parm_item *this_parm;
246 struct prod_token_parm_item *this_parm_var;
6cfea11b
TJ
247 tok = $3;
248 prod = make_production (PROD_FUNCTION_NAME, $3);
249 SYMBOL_TABLE_NAME (prod) = $3;
250 EXPRESSION_TYPE (prod) = $2;
96e3ac4f 251 NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
6cfea11b
TJ
252 PARAMETERS (prod) = reverse_prod_list ($5);
253 insert_tree_name (prod);
254 STORAGE_CLASS_TOKEN (prod) = $1;
255 set_storage (prod);
256 switch (STORAGE_CLASS (prod))
257 {
258 case STATIC_STORAGE:
259 case EXTERNAL_DEFINITION_STORAGE:
260 break;
261
262 case AUTOMATIC_STORAGE:
263 fprintf (stderr, "%s:%i:%i: A function cannot be automatic\n", in_fname,
96e3ac4f 264 tok->tp.tok.lineno, tok->tp.tok.charno);
6cfea11b
TJ
265 print_token (stderr, 0, tok);
266 errorcount++;
267 YYERROR;
268 break;
269
270 default:
271 abort ();
272 }
273 type = EXPRESSION_TYPE (prod);
274 /* Create a parameter list in a non-front end specific format. */
275 for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
276 this_parm;
96e3ac4f 277 this_parm = this_parm->tp.pro.next)
6cfea11b
TJ
278 {
279 if (this_parm->category != production_category)
280 abort ();
281 this_parm_var = VARIABLE (this_parm);
282 if (!this_parm_var)
283 abort ();
284 if (this_parm_var->category != production_category)
285 abort ();
96e3ac4f
TJ
286 this_parms = my_malloc (sizeof (struct prod_token_parm_item));
287 if (!this_parm_var->tp.pro.main_token)
6cfea11b 288 abort ();
96e3ac4f
TJ
289 this_parms->tp.par.variable_name = this_parm_var->tp.pro.main_token->tp.tok.chars;
290 this_parms->type = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
6cfea11b
TJ
291 if (last_parms)
292 {
96e3ac4f 293 last_parms->tp.par.next = this_parms;
6cfea11b
TJ
294 last_parms = this_parms;
295 }
296 else
297 {
298 first_parms = this_parms;
299 last_parms = this_parms;
300 }
96e3ac4f
TJ
301 this_parms->tp.par.where_to_put_var_tree =
302 & (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
6cfea11b
TJ
303 }
304 FIRST_PARMS (prod) = first_parms;
305
96e3ac4f
TJ
306 prod->tp.pro.code = tree_code_create_function_prototype
307 (tok->tp.tok.chars, STORAGE_CLASS (prod), NUMERIC_TYPE (type),
308 first_parms, in_fname, tok->tp.tok.lineno);
6cfea11b
TJ
309
310}
311;
312
313function:
314NAME LEFT_BRACE {
96e3ac4f
TJ
315 struct prod_token_parm_item *proto;
316 struct prod_token_parm_item search_prod;
317 struct prod_token_parm_item* tok;
318 struct prod_token_parm_item *this_parm;
6cfea11b
TJ
319 tok = $1;
320 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
321 current_function = proto = lookup_tree_name (&search_prod);
322 if (!proto)
323 {
324 fprintf (stderr, "%s:%i:%i: Function prototype not found\n", in_fname,
96e3ac4f 325 tok->tp.tok.lineno, tok->tp.tok.charno);
6cfea11b
TJ
326 print_token (stderr, 0, tok);
327 errorcount++;
328 YYERROR;
329 }
96e3ac4f 330 if (!proto->tp.pro.code)
6cfea11b
TJ
331 abort ();
332 tree_code_create_function_initial
96e3ac4f 333 (proto->tp.pro.code, in_fname, tok->tp.tok.lineno,
6cfea11b
TJ
334 FIRST_PARMS (current_function));
335
336 /* Check all the parameters have code. */
337 for (this_parm = PARAMETERS (proto);
338 this_parm;
96e3ac4f 339 this_parm = this_parm->tp.pro.next)
6cfea11b 340 {
96e3ac4f 341 if (! (struct prod_token_parm_item*)VARIABLE (this_parm))
6cfea11b 342 abort ();
96e3ac4f 343 if (! (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code))
6cfea11b
TJ
344 abort ();
345 }
346}
347variable_defs_opt statements_opt RIGHT_BRACE {
96e3ac4f 348 struct prod_token_parm_item* tok;
6cfea11b 349 tok = $1;
96e3ac4f 350 tree_code_create_function_wrapup (in_fname, tok->tp.tok.lineno);
6cfea11b
TJ
351 current_function = NULL;
352}
353;
354
355variable_defs_opt:
356/* Nil. */ {
357 $$ = 0;
358}
359|variable_defs {
360 $$ = $1;
361}
362;
363
364statements_opt:
365/* Nil. */ {
366 $$ = 0;
367}
368|statements {
369 $$ = $1;
370}
371;
372
373variable_defs:
374variable_def {
375 /* Nothing to do. */
376}
377|variable_defs variable_def {
378 /* Nothing to do. */
379}
380;
381
382typename:
383INT {
96e3ac4f
TJ
384 struct prod_token_parm_item* tok;
385 struct prod_token_parm_item *prod;
6cfea11b
TJ
386 tok = $1;
387 prod = make_production (PROD_TYPE_NAME, tok);
388 NUMERIC_TYPE (prod) = SIGNED_INT;
96e3ac4f 389 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
6cfea11b
TJ
390 $$ = prod;
391}
392|UNSIGNED INT {
96e3ac4f
TJ
393 struct prod_token_parm_item* tok;
394 struct prod_token_parm_item *prod;
6cfea11b
TJ
395 tok = $1;
396 prod = make_production (PROD_TYPE_NAME, tok);
397 NUMERIC_TYPE (prod) = UNSIGNED_INT;
96e3ac4f 398 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
6cfea11b
TJ
399 $$ = prod;
400}
401|CHAR {
96e3ac4f
TJ
402 struct prod_token_parm_item* tok;
403 struct prod_token_parm_item *prod;
6cfea11b
TJ
404 tok = $1;
405 prod = make_production (PROD_TYPE_NAME, tok);
406 NUMERIC_TYPE (prod) = SIGNED_CHAR;
96e3ac4f 407 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
6cfea11b
TJ
408 $$ = prod;
409}
410|UNSIGNED CHAR {
96e3ac4f
TJ
411 struct prod_token_parm_item* tok;
412 struct prod_token_parm_item *prod;
6cfea11b
TJ
413 tok = $1;
414 prod = make_production (PROD_TYPE_NAME, tok);
415 NUMERIC_TYPE (prod) = UNSIGNED_CHAR;
96e3ac4f 416 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
6cfea11b
TJ
417 $$ = prod;
418}
419|VOID {
96e3ac4f
TJ
420 struct prod_token_parm_item* tok;
421 struct prod_token_parm_item *prod;
6cfea11b
TJ
422 tok = $1;
423 prod = make_production (PROD_TYPE_NAME, tok);
424 NUMERIC_TYPE (prod) = VOID_TYPE;
96e3ac4f 425 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
6cfea11b
TJ
426 $$ = prod;
427}
428;
429
430parameters:
431parameter {
432 /* Nothing to do. */
433 $$ = $1;
434}
435|parameters COMMA parameter {
96e3ac4f 436 struct prod_token_parm_item *prod1;
6cfea11b 437 prod1 = $3;
96e3ac4f 438 prod1->tp.pro.next = $1; /* Insert in reverse order. */
6cfea11b
TJ
439 $$ = prod1;
440}
441;
442
443statements:
444statement {
445 /* Nothing to do. */
446}
447|statements statement {
448 /* Nothing to do. */
449}
450;
451
452statement:
453expression SEMICOLON {
96e3ac4f 454 struct prod_token_parm_item *exp;
6cfea11b 455 exp = $1;
96e3ac4f 456 tree_code_output_expression_statement (exp->tp.pro.code, in_fname, exp->tp.pro.main_token->tp.tok.lineno);
6cfea11b
TJ
457}
458|return SEMICOLON {
459 /* Nothing to do. */
460}
461|if_statement {
462 /* Nothing to do. */
463}
464;
465
466if_statement:
467IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
96e3ac4f
TJ
468 struct prod_token_parm_item* tok;
469 struct prod_token_parm_item *exp;
6cfea11b
TJ
470 tok = $1;
471 exp = $3;
96e3ac4f
TJ
472 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
473 tree_code_if_start (exp->tp.pro.code, in_fname, tok->tp.tok.lineno);
6cfea11b
TJ
474}
475LEFT_BRACE statements_opt RIGHT_BRACE {
476 /* Just let the statements flow. */
477}
478ELSE {
96e3ac4f 479 struct prod_token_parm_item* tok;
6cfea11b 480 tok = $1;
96e3ac4f 481 tree_code_if_else (in_fname, tok->tp.tok.lineno);
6cfea11b
TJ
482}
483LEFT_BRACE statements_opt RIGHT_BRACE {
96e3ac4f 484 struct prod_token_parm_item* tok;
6cfea11b 485 tok = $12;
96e3ac4f 486 tree_code_if_end (in_fname, tok->tp.tok.lineno);
6cfea11b
TJ
487}
488;
489
490
491return:
492RETURN expression_opt {
96e3ac4f
TJ
493 struct prod_token_parm_item *type_prod;
494 struct prod_token_parm_item* ret_tok;
6cfea11b
TJ
495 ret_tok = $1;
496 type_prod = EXPRESSION_TYPE (current_function);
497 if (NUMERIC_TYPE (type_prod) == VOID)
498 if ($2 == NULL)
96e3ac4f 499 tree_code_generate_return (type_prod->tp.pro.code, NULL);
6cfea11b
TJ
500 else
501 {
502 fprintf (stderr, "%s:%i:%i: Redundant expression in return\n", in_fname,
96e3ac4f 503 ret_tok->tp.tok.lineno, ret_tok->tp.tok.charno);
6cfea11b
TJ
504 print_token (stderr, 0, ret_tok);
505 errorcount++;
96e3ac4f 506 tree_code_generate_return (type_prod->tp.pro.code, NULL);
6cfea11b
TJ
507 }
508 else
509 if ($2 == NULL)
510 {
511 fprintf (stderr, "%s:%i:%i: Expression missing in return\n", in_fname,
96e3ac4f 512 ret_tok->tp.tok.lineno, ret_tok->tp.tok.charno);
6cfea11b
TJ
513 print_token (stderr, 0, ret_tok);
514 errorcount++;
515 }
516 else
517 {
96e3ac4f 518 struct prod_token_parm_item *exp;
6cfea11b
TJ
519 exp = $2;
520 /* Check same type. */
521 if (check_type_match (NUMERIC_TYPE (type_prod), $2))
522 {
96e3ac4f 523 if (!type_prod->tp.pro.code)
6cfea11b 524 abort ();
96e3ac4f 525 if (!exp->tp.pro.code)
6cfea11b
TJ
526 abort ();
527 /* Generate the code. */
96e3ac4f 528 tree_code_generate_return (type_prod->tp.pro.code, exp->tp.pro.code);
6cfea11b
TJ
529 }
530 }
531}
532;
533
534expression_opt:
535/* Nil. */ {
536 $$ = 0;
537}
538|expression {
96e3ac4f 539 struct prod_token_parm_item *exp;
6cfea11b 540 exp = $1;
96e3ac4f 541 if (!exp->tp.pro.code)
6cfea11b
TJ
542 abort ();
543
544 $$ = $1;
545}
546;
547
548expression:
549INTEGER {
550 $$ = make_integer_constant ($1);
551}
552|variable_ref {
553 $$ = $1;
554}
555|expression PLUS expression {
96e3ac4f
TJ
556 struct prod_token_parm_item* tok;
557 struct prod_token_parm_item *prod;
558 struct prod_token_parm_item *op1;
559 struct prod_token_parm_item *op2;
6cfea11b
TJ
560 tree type;
561
562 op1 = $1;
563 op2 = $3;
564 tok = $2;
96e3ac4f
TJ
565 ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
566 ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
6cfea11b
TJ
567 prod = make_production (PROD_PLUS_EXPRESSION, tok);
568 NUMERIC_TYPE (prod) = get_common_type (op1, op2);
569 if (!NUMERIC_TYPE (prod))
570 YYERROR;
571 else
572 {
573 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
574 if (!type)
575 abort ();
576 OP1 (prod) = $1;
577 OP2 (prod) = $3;
578
96e3ac4f
TJ
579 prod->tp.pro.code = tree_code_get_expression
580 (EXP_PLUS, type, op1->tp.pro.code, op2->tp.pro.code, NULL);
6cfea11b
TJ
581 }
582 $$ = prod;
583}
584|expression MINUS expression %prec PLUS {
96e3ac4f
TJ
585 struct prod_token_parm_item* tok;
586 struct prod_token_parm_item *prod;
587 struct prod_token_parm_item *op1;
588 struct prod_token_parm_item *op2;
6cfea11b
TJ
589 tree type;
590
591 op1 = $1;
592 op2 = $3;
96e3ac4f
TJ
593 ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
594 ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
6cfea11b
TJ
595 tok = $2;
596 prod = make_production (PROD_PLUS_EXPRESSION, tok);
597 NUMERIC_TYPE (prod) = get_common_type (op1, op2);
598 if (!NUMERIC_TYPE (prod))
599 YYERROR;
600 else
601 {
602 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
603 if (!type)
604 abort ();
605 OP1 (prod) = $1;
606 OP2 (prod) = $3;
607
96e3ac4f
TJ
608 prod->tp.pro.code = tree_code_get_expression (EXP_MINUS,
609 type, op1->tp.pro.code, op2->tp.pro.code, NULL);
6cfea11b
TJ
610 }
611 $$ = prod;
612}
613|expression EQUALS expression {
96e3ac4f
TJ
614 struct prod_token_parm_item* tok;
615 struct prod_token_parm_item *prod;
616 struct prod_token_parm_item *op1;
617 struct prod_token_parm_item *op2;
6cfea11b
TJ
618 tree type;
619
620 op1 = $1;
621 op2 = $3;
96e3ac4f
TJ
622 ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
623 ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
6cfea11b
TJ
624 tok = $2;
625 prod = make_production (PROD_PLUS_EXPRESSION, tok);
626 NUMERIC_TYPE (prod) = SIGNED_INT;
627 if (!NUMERIC_TYPE (prod))
628 YYERROR;
629 else
630 {
631 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
632 if (!type)
633 abort ();
634 OP1 (prod) = $1;
635 OP2 (prod) = $3;
636
96e3ac4f
TJ
637 prod->tp.pro.code = tree_code_get_expression (EXP_EQUALS,
638 type, op1->tp.pro.code, op2->tp.pro.code, NULL);
6cfea11b
TJ
639 }
640 $$ = prod;
641}
642|variable_ref ASSIGN expression {
96e3ac4f
TJ
643 struct prod_token_parm_item* tok;
644 struct prod_token_parm_item *prod;
645 struct prod_token_parm_item *op1;
646 struct prod_token_parm_item *op2;
6cfea11b
TJ
647 tree type;
648
649 op1 = $1;
650 op2 = $3;
651 tok = $2;
96e3ac4f 652 ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
6cfea11b
TJ
653 prod = make_production (PROD_ASSIGN_EXPRESSION, tok);
654 NUMERIC_TYPE (prod) = NUMERIC_TYPE (op1);
655 if (!NUMERIC_TYPE (prod))
656 YYERROR;
657 else
658 {
659 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
660 if (!type)
661 abort ();
662 OP1 (prod) = $1;
663 OP2 (prod) = $3;
96e3ac4f
TJ
664 prod->tp.pro.code = tree_code_get_expression (EXP_ASSIGN,
665 type, op1->tp.pro.code, op2->tp.pro.code, NULL);
6cfea11b
TJ
666 }
667 $$ = prod;
668}
669|function_invocation {
670 $$ = $1;
671}
672;
673
674function_invocation:
675NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
96e3ac4f
TJ
676 struct prod_token_parm_item *prod;
677 struct prod_token_parm_item* tok;
678 struct prod_token_parm_item search_prod;
679 struct prod_token_parm_item *proto;
680 struct prod_token_parm_item *exp;
681 struct prod_token_parm_item *exp_proto;
682 struct prod_token_parm_item *var;
6cfea11b
TJ
683 int exp_proto_count;
684 int exp_count;
685 tree parms;
686 tree type;
687
688 tok = $1;
689 prod = make_production (PROD_FUNCTION_INVOCATION, tok);
690 SYMBOL_TABLE_NAME (prod) = tok;
691 PARAMETERS (prod) = reverse_prod_list ($3);
692 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
693 proto = lookup_tree_name (&search_prod);
694 if (!proto)
695 {
696 fprintf (stderr, "%s:%i:%i: Function prototype not found\n", in_fname,
96e3ac4f 697 tok->tp.tok.lineno, tok->tp.tok.charno);
6cfea11b
TJ
698 print_token (stderr, 0, tok);
699 errorcount++;
700 YYERROR;
701 }
702 EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
703 NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
704 /* Count the expressions and ensure they match the prototype. */
705 for (exp_proto_count = 0, exp_proto = PARAMETERS (proto);
96e3ac4f 706 exp_proto; exp_proto = exp_proto->tp.pro.next)
6cfea11b
TJ
707 exp_proto_count++;
708
96e3ac4f 709 for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
6cfea11b
TJ
710 exp_count++;
711
712 if (exp_count != exp_proto_count)
713 {
714 fprintf (stderr, "%s:%i:%i: expression count mismatch with prototype\n", in_fname,
96e3ac4f 715 tok->tp.tok.lineno, tok->tp.tok.charno);
6cfea11b
TJ
716 print_token (stderr, 0, tok);
717 errorcount++;
718 YYERROR;
719 }
720 parms = tree_code_init_parameters ();
721 for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
722 exp_proto;
96e3ac4f 723 exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
6cfea11b
TJ
724 {
725 if (!exp)
726 abort ();
727 if (!exp_proto)
728 abort ();
96e3ac4f 729 if (!exp->tp.pro.code)
6cfea11b
TJ
730 abort ();
731 var = VARIABLE (exp_proto);
732 if (!var)
733 abort ();
96e3ac4f 734 if (!var->tp.pro.code)
6cfea11b 735 abort ();
96e3ac4f 736 parms = tree_code_add_parameter (parms, var->tp.pro.code, exp->tp.pro.code);
6cfea11b
TJ
737 }
738 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
96e3ac4f
TJ
739 prod->tp.pro.code = tree_code_get_expression
740 (EXP_FUNCTION_INVOCATION, type, proto->tp.pro.code, parms, NULL);
6cfea11b
TJ
741 $$ = prod;
742}
743;
744
745expressions_with_commas:
746expression {
96e3ac4f 747 struct prod_token_parm_item *exp;
6cfea11b 748 exp = $1;
96e3ac4f 749 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
6cfea11b
TJ
750 $$ = $1;
751}
752|expressions_with_commas COMMA expression {
96e3ac4f 753 struct prod_token_parm_item *exp;
6cfea11b 754 exp = $3;
96e3ac4f
TJ
755 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
756 exp->tp.pro.next = $1; /* Reverse order. */
6cfea11b
TJ
757 $$ = exp;
758}
759;
760
761variable_ref:
762NAME {
96e3ac4f
TJ
763 struct prod_token_parm_item search_prod;
764 struct prod_token_parm_item *prod;
765 struct prod_token_parm_item *symbol_table_entry;
766 struct prod_token_parm_item* tok;
6cfea11b
TJ
767 tree type;
768
769 tok = $1;
770 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
771 symbol_table_entry = lookup_tree_name (&search_prod);
772 if (!symbol_table_entry)
773 {
774 fprintf (stderr, "%s:%i:%i: Variable referred to but not defined\n", in_fname,
96e3ac4f 775 tok->tp.tok.lineno, tok->tp.tok.charno);
6cfea11b
TJ
776 print_token (stderr, 0, tok);
777 errorcount++;
778 YYERROR;
779 }
780
781 prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
782 NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
783 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
784 if (!NUMERIC_TYPE (prod))
785 YYERROR;
786 OP1 (prod) = $1;
787
96e3ac4f
TJ
788 prod->tp.pro.code = tree_code_get_expression (EXP_REFERENCE, type,
789 symbol_table_entry->tp.pro.code, NULL, NULL);
6cfea11b
TJ
790 $$ = prod;
791}
792;
793
794init_opt:
795/* Nil. */ {
796 $$ = 0;
797}
798|init {
799 /* Nothing to do. */
a3b5decf 800};
6cfea11b
TJ
801
802init:
803ASSIGN init_element {
804}
805;
806
807init_element:
808INTEGER {
809 $$ = make_integer_constant ($1);
810}
811;
812
813%%
814
815/* Print a token VALUE to file FILE. Ignore TYPE which is the token
816 type. */
817
818void
819print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
820{
96e3ac4f 821 struct prod_token_parm_item *tok;
6cfea11b
TJ
822 unsigned int ix;
823
824 tok = value;
96e3ac4f
TJ
825 fprintf (file, "%d \"", tok->tp.tok.lineno);
826 for (ix = 0; ix < tok->tp.tok.length; ix++)
827 fprintf (file, "%c", tok->tp.tok.chars[ix]);
6cfea11b
TJ
828 fprintf (file, "\"");
829}
830
831/* Output a message ERROR_MESSAGE from the parser. */
832void
833yyerror (const char *error_message)
834{
96e3ac4f 835 struct prod_token_parm_item *tok;
6cfea11b
TJ
836
837 tok = yylval;
838 if (tok)
839 {
96e3ac4f 840 fprintf (stderr, "%s:%i:%i: %s\n", in_fname, tok->tp.tok.lineno, tok->tp.tok.charno, error_message);
6cfea11b
TJ
841 print_token (stderr, 0, tok);
842 }
843 else
844 fprintf (stderr, "%s\n", error_message);
845
846 errorcount++;
847
848}
849
850/* Reverse the order of a token list, linked by parse_next, old first
851 token is OLD_FIRST. */
852
96e3ac4f
TJ
853static struct prod_token_parm_item*
854reverse_prod_list (struct prod_token_parm_item *old_first)
6cfea11b 855{
96e3ac4f
TJ
856 struct prod_token_parm_item *current;
857 struct prod_token_parm_item *next;
858 struct prod_token_parm_item *prev = NULL;
6cfea11b
TJ
859
860 current = old_first;
861 prev = NULL;
862
863 while (current)
864 {
865 if (current->category != production_category)
866 abort ();
96e3ac4f
TJ
867 next = current->tp.pro.next;
868 current->tp.pro.next = prev;
6cfea11b
TJ
869 prev = current;
870 current = next;
871 }
872 return prev;
873}
874
875/* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
876
877static void
96e3ac4f 878ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
6cfea11b
TJ
879{
880 if (type == VOID)
881 {
882 fprintf (stderr, "%s:%i:%i: Type must not be void in this context\n", in_fname,
96e3ac4f 883 name->tp.tok.lineno, name->tp.tok.charno);
6cfea11b
TJ
884 print_token (stderr, 0, name);
885 errorcount++;
886 }
887}
888
889/* Check TYPE1 and TYPE2 which are integral types. Return the lowest
890 common type (min is signed int). */
891
892static int
96e3ac4f 893get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2)
6cfea11b
TJ
894{
895 if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
896 return UNSIGNED_INT;
897 if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
898 return UNSIGNED_INT;
899
900 return SIGNED_INT;
901}
902
903/* Check type (TYPE_NUM) and expression (EXP) match. Return the 1 if
904 OK else 0. Must be exact match - same name unless it is an
905 integral type. */
906
907static int
96e3ac4f 908check_type_match (int type_num, struct prod_token_parm_item *exp)
6cfea11b
TJ
909{
910 switch (type_num)
911 {
912 case SIGNED_INT:
913 case UNSIGNED_INT:
914 case SIGNED_CHAR:
915 case UNSIGNED_CHAR:
916 switch (NUMERIC_TYPE (exp))
917 {
918 case SIGNED_INT:
919 case UNSIGNED_INT:
920 case SIGNED_CHAR:
921 case UNSIGNED_CHAR:
922 return 1;
923
924 case VOID:
925 abort ();
926
927 default:
928 abort ();
929 }
930 break;
931
932 case VOID:
933 abort ();
934
935 default:
936 abort ();
937
938 }
939}
940
941/* Make a production for an integer constant VALUE. */
942
96e3ac4f
TJ
943static struct prod_token_parm_item *
944make_integer_constant (struct prod_token_parm_item* value)
6cfea11b 945{
96e3ac4f
TJ
946 struct prod_token_parm_item* tok;
947 struct prod_token_parm_item *prod;
6cfea11b
TJ
948 tok = value;
949 prod = make_production (PROD_INTEGER_CONSTANT, tok);
96e3ac4f 950 if ((tok->tp.tok.chars[0] == (unsigned char)'-')|| (tok->tp.tok.chars[0] == (unsigned char)'+'))
6cfea11b
TJ
951 NUMERIC_TYPE (prod) = SIGNED_INT;
952 else
953 NUMERIC_TYPE (prod) = UNSIGNED_INT;
96e3ac4f 954 prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars, tok->tp.tok.length);
6cfea11b
TJ
955 return prod;
956}
957
958/* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
959
960static void
96e3ac4f 961set_storage (struct prod_token_parm_item *prod)
6cfea11b 962{
96e3ac4f 963 struct prod_token_parm_item* stg_class;
6cfea11b
TJ
964 stg_class = STORAGE_CLASS_TOKEN (prod);
965 switch (stg_class->type)
966 {
967 case STATIC:
968 STORAGE_CLASS (prod) = STATIC_STORAGE;
969 break;
970
971 case AUTOMATIC:
972 STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
973 break;
974
975 case EXTERNAL_DEFINITION:
976 STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
977 break;
978
979 case EXTERNAL_REFERENCE:
980 STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
981 break;
982
983 default:
984 abort ();
985 }
986}
987
988/* Set parse trace. */
989
990void
991treelang_debug (void)
992{
993 if (option_parser_trace)
994 yydebug = 1;
995}