2 /* sbc.y: A POSIX bc processor written for minix with no extensions. */
4 /* This file is part of GNU bc.
5 Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License , or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING. If not, write to
19 The Free Software Foundation, Inc.
20 59 Temple Place, Suite 330
23 You may contact the author by:
24 e-mail: philnelson@acm.org
25 us-mail: Philip A. Nelson
26 Computer Science Department, 9062
27 Western Washington University
28 Bellingham, WA 98226-9062
30 *************************************************************************/
33 #include "global.h" /* To get the global variables. */
46 %token <i_value> ENDOFLINE AND OR NOT
47 %token <s_value> STRING NAME NUMBER
48 /* '-', '+' are tokens themselves */
49 %token <c_value> ASSIGN_OP
50 /* '=', '+=', '-=', '*=', '/=', '%=', '^=' */
51 %token <s_value> REL_OP
52 /* '==', '<=', '>=', '!=', '<', '>' */
53 %token <c_value> INCR_DECR
55 %token <i_value> Define Break Quit Length
56 /* 'define', 'break', 'quit', 'length' */
57 %token <i_value> Return For If While Sqrt Else
58 /* 'return', 'for', 'if', 'while', 'sqrt', 'else' */
59 %token <i_value> Scale Ibase Obase Auto Read
60 /* 'scale', 'ibase', 'obase', 'auto', 'read' */
61 %token <i_value> Warranty, Halt, Last, Continue, Print, Limits
62 /* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */
64 /* The types of all other non-terminals. */
65 %type <i_value> expression named_expression return_expression
66 %type <a_value> opt_parameter_list parameter_list opt_auto_define_list
67 %type <a_value> define_list opt_argument_list argument_list
68 %type <i_value> program input_item semicolon_list statement_list
69 %type <i_value> statement_or_error statement function relational_expression
87 printf ("s%s\n", BC_VERSION);
93 input_item : semicolon_list ENDOFLINE
103 semicolon_list : /* empty */
106 | semicolon_list ';' statement_or_error
109 statement_list : /* empty */
112 | statement_list ENDOFLINE
113 | statement_list ENDOFLINE statement
115 | statement_list ';' statement
117 statement_or_error : statement
139 if (break_label == 0)
140 yyerror ("Break outside a for/while");
143 sprintf (genstr, "J%1d:", break_label);
151 | Return '(' return_expression ')'
156 break_label = next_label++;
161 sprintf (genstr, "pN%1d:", $4);
164 relational_expression ';'
167 sprintf (genstr, "B%1d:J%1d:", $7, break_label);
169 $<i_value>$ = next_label++;
170 sprintf (genstr, "N%1d:", $<i_value>$);
175 sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
180 sprintf (genstr, "J%1d:N%1d:", $<i_value>9,
185 | If '(' relational_expression ')'
188 sprintf (genstr, "Z%1d:", $3);
193 sprintf (genstr, "N%1d:", $3);
199 sprintf (genstr, "N%1d:", $1);
202 '(' relational_expression
205 break_label = next_label++;
206 sprintf (genstr, "Z%1d:", break_label);
211 sprintf (genstr, "J%1d:N%1d:", $1, break_label);
215 | '{' statement_list '}'
218 function : Define NAME '(' opt_parameter_list ')' '{'
219 ENDOFLINE opt_auto_define_list
221 check_params ($4,$8);
222 sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT),
223 arg_str ($4), arg_str ($8));
230 statement_list ENDOFLINE '}'
236 opt_parameter_list : /* empty */
240 parameter_list : NAME
241 { $$ = nextarg (NULL, lookup($1,SIMPLE), FALSE); }
242 | define_list ',' NAME
243 { $$ = nextarg ($1, lookup($3,SIMPLE), FALSE); }
245 opt_auto_define_list : /* empty */
247 | Auto define_list ENDOFLINE
249 | Auto define_list ';'
253 { $$ = nextarg (NULL, lookup($1,SIMPLE), FALSE); }
255 { $$ = nextarg (NULL, lookup($1,ARRAY), FALSE); }
256 | define_list ',' NAME
257 { $$ = nextarg ($1, lookup($3,SIMPLE), FALSE); }
258 | define_list ',' NAME '[' ']'
259 { $$ = nextarg ($1, lookup($3,ARRAY), FALSE); }
261 opt_argument_list : /* empty */
265 argument_list : expression
266 { $$ = nextarg (NULL,0, FALSE); }
267 | argument_list ',' expression
268 { $$ = nextarg ($1,0, FALSE); }
270 relational_expression : expression
272 | expression REL_OP expression
298 return_expression : /* empty */
305 expression : named_expression ASSIGN_OP
310 sprintf (genstr, "DL%d:", -$1);
312 sprintf (genstr, "l%d:", $1);
321 sprintf (genstr, "%c", $2);
325 sprintf (genstr, "S%d:", -$1);
327 sprintf (genstr, "s%d:", $1);
330 | expression '+' expression
332 | expression '-' expression
334 | expression '*' expression
336 | expression '/' expression
338 | expression '%' expression
340 | expression '^' expression
342 | '-' expression %prec UNARY_MINUS
343 { generate ("n"); $$ = 1;}
348 sprintf (genstr, "L%d:", -$1);
350 sprintf (genstr, "l%d:", $1);
355 int len = strlen($1);
357 if (len == 1 && *$1 == '0')
361 if (len == 1 && *$1 == '1')
374 | NAME '(' opt_argument_list ')'
379 sprintf (genstr, "C%d,%s:", lookup($1,FUNCT),
384 sprintf (genstr, "C%d:", lookup($1,FUNCT));
387 | INCR_DECR named_expression
393 sprintf (genstr, "DA%d:L%d:", -$2, -$2);
395 sprintf (genstr, "DM%d:L%d:", -$2, -$2);
400 sprintf (genstr, "i%d:l%d:", $2, $2);
402 sprintf (genstr, "d%d:l%d:", $2, $2);
406 | named_expression INCR_DECR
411 sprintf (genstr, "DL%d:x", -$1);
414 sprintf (genstr, "A%d:", -$1);
416 sprintf (genstr, "M%d:", -$1);
420 sprintf (genstr, "l%d:", $1);
423 sprintf (genstr, "i%d:", $1);
425 sprintf (genstr, "d%d:", $1);
429 | Length '(' expression ')'
430 { generate ("cL"); $$ = 1;}
431 | Sqrt '(' expression ')'
432 { generate ("cR"); $$ = 1;}
433 | Scale '(' expression ')'
434 { generate ("cS"); $$ = 1;}
436 named_expression : NAME
437 { $$ = lookup($1,SIMPLE); }
438 | NAME '[' expression ']'
439 { $$ = lookup($1,ARRAY); }