OSDN Git Service

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