2 /* sbc.y: A POSIX bc processor written for minix with no extensions. */
4 /* This file is part of bc written for MINIX.
5 Copyright (C) 1991, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA.
21 You may contact the author by:
22 e-mail: phil@cs.wwu.edu
23 us-mail: Philip A. Nelson
24 Computer Science Department, 9062
25 Western Washington University
26 Bellingham, WA 98226-9062
28 *************************************************************************/
31 #include "global.h" /* To get the global variables. */
44 %token
<i_value
> NEWLINE AND OR NOT
45 %token
<s_value
> STRING NAME NUMBER
46 /* '-', '+' are tokens themselves */
47 %token
<c_value
> MUL_OP
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 NEWLINE
103 semicolon_list
: /* empty */
106 | semicolon_list
';' statement_or_error
109 statement_list
: /* empty */
112 | statement_list NEWLINE
113 | statement_list NEWLINE 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 NEWLINE opt_auto_define_list
221 check_params
($4,$8);
222 sprintf
(genstr
, "F%d,%s.%s[", lookup
($2,FUNCT
),
223 arg_str
($4,TRUE
), arg_str
($8,TRUE
));
230 statement_list NEWLINE
'}'
236 opt_parameter_list
: /* empty */
240 parameter_list
: NAME
241 { $$
= nextarg
(NULL
, lookup
($1,SIMPLE
)); }
242 | define_list
',' NAME
243 { $$
= nextarg
($1, lookup
($3,SIMPLE
)); }
245 opt_auto_define_list
: /* empty */
247 | Auto define_list NEWLINE
249 | Auto define_list
';'
253 { $$
= nextarg
(NULL
, lookup
($1,SIMPLE
)); }
255 { $$
= nextarg
(NULL
, lookup
($1,ARRAY
)); }
256 | define_list
',' NAME
257 { $$
= nextarg
($1, lookup
($3,SIMPLE
)); }
258 | define_list
',' NAME
'[' ']'
259 { $$
= nextarg
($1, lookup
($3,ARRAY
)); }
261 opt_argument_list
: /* empty */
265 argument_list
: expression
266 { $$
= nextarg
(NULL
,0); }
267 | argument_list
',' expression
268 { $$
= nextarg
($1,0); }
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 MUL_OP 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
); }