xref: /titanic_53/usr/src/cmd/bc/bc.y (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate %{
2*7c478bd9Sstevel@tonic-gate /*
3*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
4*7c478bd9Sstevel@tonic-gate  *
5*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
6*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
7*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
8*7c478bd9Sstevel@tonic-gate  * with the License.
9*7c478bd9Sstevel@tonic-gate  *
10*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
12*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
13*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
14*7c478bd9Sstevel@tonic-gate  *
15*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
16*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
18*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
19*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
20*7c478bd9Sstevel@tonic-gate  *
21*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
22*7c478bd9Sstevel@tonic-gate  */
23*7c478bd9Sstevel@tonic-gate %}
24*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
25*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate /*
29*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
30*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
31*7c478bd9Sstevel@tonic-gate  */
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate %{
34*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.9	*/
35*7c478bd9Sstevel@tonic-gate %}
36*7c478bd9Sstevel@tonic-gate %{
37*7c478bd9Sstevel@tonic-gate #include <stdio.h>
38*7c478bd9Sstevel@tonic-gate #include <stdarg.h>
39*7c478bd9Sstevel@tonic-gate #include <limits.h>
40*7c478bd9Sstevel@tonic-gate #include <libintl.h>
41*7c478bd9Sstevel@tonic-gate #include <locale.h>
42*7c478bd9Sstevel@tonic-gate #include <signal.h>
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate static int *getout(int);
45*7c478bd9Sstevel@tonic-gate static int *bundle(int, ...);
46*7c478bd9Sstevel@tonic-gate static void usage(void);
47*7c478bd9Sstevel@tonic-gate %}
48*7c478bd9Sstevel@tonic-gate %union {
49*7c478bd9Sstevel@tonic-gate 	int *iptr;
50*7c478bd9Sstevel@tonic-gate 	char *cptr;
51*7c478bd9Sstevel@tonic-gate 	int cc;
52*7c478bd9Sstevel@tonic-gate 	}
53*7c478bd9Sstevel@tonic-gate %start start;
54*7c478bd9Sstevel@tonic-gate %type <iptr> stat, def, slist, dlets, e
55*7c478bd9Sstevel@tonic-gate %type <iptr> slist, re, fprefix, cargs, eora, cons, constant, lora
56*7c478bd9Sstevel@tonic-gate %right '='
57*7c478bd9Sstevel@tonic-gate %left '+' '-'
58*7c478bd9Sstevel@tonic-gate %left '*' '/' '%'
59*7c478bd9Sstevel@tonic-gate %right '^'
60*7c478bd9Sstevel@tonic-gate %left UMINUS
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate %token <cptr> LETTER
63*7c478bd9Sstevel@tonic-gate %type <cptr> EQOP, CRS
64*7c478bd9Sstevel@tonic-gate %token <cc> DIGIT, SQRT, LENGTH, _IF, FFF, EQ
65*7c478bd9Sstevel@tonic-gate %token <cc> _WHILE _FOR NE LE GE INCR DECR
66*7c478bd9Sstevel@tonic-gate %token <cc> _RETURN _BREAK _DEFINE BASE OBASE SCALE
67*7c478bd9Sstevel@tonic-gate %token <cc> EQPL EQMI EQMUL EQDIV EQREM EQEXP
68*7c478bd9Sstevel@tonic-gate %token <cptr> _AUTO DOT
69*7c478bd9Sstevel@tonic-gate %token <cc> QSTR
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate %{
72*7c478bd9Sstevel@tonic-gate #define	STRING_SIZE	(BC_STRING_MAX + 3)	/* string plus quotes */
73*7c478bd9Sstevel@tonic-gate 						/* plus NULL */
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate FILE	*in;
76*7c478bd9Sstevel@tonic-gate char	cary[LINE_MAX+1];
77*7c478bd9Sstevel@tonic-gate char	*cp = { cary };
78*7c478bd9Sstevel@tonic-gate char	*cpend = &cary[LINE_MAX];	/* last address (not the null char) */
79*7c478bd9Sstevel@tonic-gate char	string[STRING_SIZE];
80*7c478bd9Sstevel@tonic-gate char	*str = { string };
81*7c478bd9Sstevel@tonic-gate int	crs = '0';
82*7c478bd9Sstevel@tonic-gate int	rcrs = '0';		/* reset crs */
83*7c478bd9Sstevel@tonic-gate int	bindx = 0;
84*7c478bd9Sstevel@tonic-gate int	lev = 0;			/* current scope level */
85*7c478bd9Sstevel@tonic-gate int	ln;				/* line number of current file */
86*7c478bd9Sstevel@tonic-gate int	*ttp;
87*7c478bd9Sstevel@tonic-gate char	*ss;				/* current input source */
88*7c478bd9Sstevel@tonic-gate int	bstack[10] = { 0 };
89*7c478bd9Sstevel@tonic-gate char	*numb[15] = {
90*7c478bd9Sstevel@tonic-gate 	" 0", " 1", " 2", " 3", " 4", " 5",
91*7c478bd9Sstevel@tonic-gate 	" 6", " 7", " 8", " 9", " 10", " 11",
92*7c478bd9Sstevel@tonic-gate 	" 12", " 13", " 14"
93*7c478bd9Sstevel@tonic-gate };
94*7c478bd9Sstevel@tonic-gate int	*pre, *post;
95*7c478bd9Sstevel@tonic-gate int	interact = 0;			/* talking to a tty? */
96*7c478bd9Sstevel@tonic-gate %}
97*7c478bd9Sstevel@tonic-gate %%
98*7c478bd9Sstevel@tonic-gate start	:
99*7c478bd9Sstevel@tonic-gate 	| start stat tail
100*7c478bd9Sstevel@tonic-gate 		= {
101*7c478bd9Sstevel@tonic-gate 			output($2);
102*7c478bd9Sstevel@tonic-gate 		}
103*7c478bd9Sstevel@tonic-gate 	| start def dargs ')' '{' dlist slist '}'
104*7c478bd9Sstevel@tonic-gate 		= {
105*7c478bd9Sstevel@tonic-gate 			ttp = bundle(6, pre, $7, post, "0", numb[lev], "Q");
106*7c478bd9Sstevel@tonic-gate 			conout(ttp, $2);
107*7c478bd9Sstevel@tonic-gate 			rcrs = crs;
108*7c478bd9Sstevel@tonic-gate 			output("");
109*7c478bd9Sstevel@tonic-gate 			lev = bindx = 0;
110*7c478bd9Sstevel@tonic-gate 		}
111*7c478bd9Sstevel@tonic-gate 	;
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate dlist	: tail
114*7c478bd9Sstevel@tonic-gate 	| dlist _AUTO dlets tail
115*7c478bd9Sstevel@tonic-gate 	;
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate stat	: e
118*7c478bd9Sstevel@tonic-gate 		= bundle(2, $1, "ps.");
119*7c478bd9Sstevel@tonic-gate 	|
120*7c478bd9Sstevel@tonic-gate 		= bundle(1, "");
121*7c478bd9Sstevel@tonic-gate 	| QSTR
122*7c478bd9Sstevel@tonic-gate 		= bundle(3, "[", $1, "]P");
123*7c478bd9Sstevel@tonic-gate 	| LETTER '=' e
124*7c478bd9Sstevel@tonic-gate 		= bundle(3, $3, "s", $1);
125*7c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' '=' e
126*7c478bd9Sstevel@tonic-gate 		= bundle(4, $6, $3, ":", geta($1));
127*7c478bd9Sstevel@tonic-gate 	| LETTER EQOP e
128*7c478bd9Sstevel@tonic-gate 		= bundle(6, "l", $1, $3, $2, "s", $1);
129*7c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' EQOP e
130*7c478bd9Sstevel@tonic-gate 		= bundle(8, $3, ";", geta($1), $6, $5, $3, ":", geta($1));
131*7c478bd9Sstevel@tonic-gate 	| _BREAK
132*7c478bd9Sstevel@tonic-gate 		= bundle(2, numb[lev-bstack[bindx-1]], "Q");
133*7c478bd9Sstevel@tonic-gate 	| _RETURN '(' e ')'
134*7c478bd9Sstevel@tonic-gate 		= bundle(4, $3, post, numb[lev], "Q");
135*7c478bd9Sstevel@tonic-gate 	| _RETURN '(' ')'
136*7c478bd9Sstevel@tonic-gate 		= bundle(4, "0", post, numb[lev], "Q");
137*7c478bd9Sstevel@tonic-gate 	| _RETURN
138*7c478bd9Sstevel@tonic-gate 		= bundle(4, "0", post, numb[lev], "Q");
139*7c478bd9Sstevel@tonic-gate 	| SCALE '=' e
140*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "k");
141*7c478bd9Sstevel@tonic-gate 	| SCALE EQOP e
142*7c478bd9Sstevel@tonic-gate 		= bundle(4, "K", $3, $2, "k");
143*7c478bd9Sstevel@tonic-gate 	| BASE '=' e
144*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "i");
145*7c478bd9Sstevel@tonic-gate 	| BASE EQOP e
146*7c478bd9Sstevel@tonic-gate 		= bundle(4, "I", $3, $2, "i");
147*7c478bd9Sstevel@tonic-gate 	| OBASE '=' e
148*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "o");
149*7c478bd9Sstevel@tonic-gate 	| OBASE EQOP e
150*7c478bd9Sstevel@tonic-gate 		= bundle(4, "O", $3, $2, "o");
151*7c478bd9Sstevel@tonic-gate 	| '{' slist '}'
152*7c478bd9Sstevel@tonic-gate 		= {
153*7c478bd9Sstevel@tonic-gate 			$$ = $2;
154*7c478bd9Sstevel@tonic-gate 		}
155*7c478bd9Sstevel@tonic-gate 	| FFF
156*7c478bd9Sstevel@tonic-gate 		= bundle(1, "fY");
157*7c478bd9Sstevel@tonic-gate 	| error
158*7c478bd9Sstevel@tonic-gate 		= bundle(1, "c");
159*7c478bd9Sstevel@tonic-gate 	| _IF CRS BLEV '(' re ')' stat
160*7c478bd9Sstevel@tonic-gate 		= {
161*7c478bd9Sstevel@tonic-gate 			conout($7, $2);
162*7c478bd9Sstevel@tonic-gate 			bundle(3, $5, $2, " ");
163*7c478bd9Sstevel@tonic-gate 		}
164*7c478bd9Sstevel@tonic-gate 	| _WHILE CRS '(' re ')' stat BLEV
165*7c478bd9Sstevel@tonic-gate 		= {
166*7c478bd9Sstevel@tonic-gate 			bundle(3, $6, $4, $2);
167*7c478bd9Sstevel@tonic-gate 			conout($$, $2);
168*7c478bd9Sstevel@tonic-gate 			bundle(3, $4, $2, " ");
169*7c478bd9Sstevel@tonic-gate 		}
170*7c478bd9Sstevel@tonic-gate 	| fprefix CRS re ';' e ')' stat BLEV
171*7c478bd9Sstevel@tonic-gate 		= {
172*7c478bd9Sstevel@tonic-gate 			bundle(5, $7, $5, "s.", $3, $2);
173*7c478bd9Sstevel@tonic-gate 			conout($$, $2);
174*7c478bd9Sstevel@tonic-gate 			bundle(5, $1, "s.", $3, $2, " ");
175*7c478bd9Sstevel@tonic-gate 		}
176*7c478bd9Sstevel@tonic-gate 	| '~' LETTER '=' e
177*7c478bd9Sstevel@tonic-gate 		= bundle(3, $4, "S", $2);
178*7c478bd9Sstevel@tonic-gate 	;
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate EQOP	: EQPL
181*7c478bd9Sstevel@tonic-gate 		= {
182*7c478bd9Sstevel@tonic-gate 			$$ = "+";
183*7c478bd9Sstevel@tonic-gate 		}
184*7c478bd9Sstevel@tonic-gate 	| EQMI
185*7c478bd9Sstevel@tonic-gate 		= {
186*7c478bd9Sstevel@tonic-gate 			$$ = "-";
187*7c478bd9Sstevel@tonic-gate 		}
188*7c478bd9Sstevel@tonic-gate 	| EQMUL
189*7c478bd9Sstevel@tonic-gate 		= {
190*7c478bd9Sstevel@tonic-gate 			$$ = "*";
191*7c478bd9Sstevel@tonic-gate 		}
192*7c478bd9Sstevel@tonic-gate 	| EQDIV
193*7c478bd9Sstevel@tonic-gate 		= {
194*7c478bd9Sstevel@tonic-gate 			$$ = "/";
195*7c478bd9Sstevel@tonic-gate 		}
196*7c478bd9Sstevel@tonic-gate 	| EQREM
197*7c478bd9Sstevel@tonic-gate 		= {
198*7c478bd9Sstevel@tonic-gate 			$$ = "%%";
199*7c478bd9Sstevel@tonic-gate 		}
200*7c478bd9Sstevel@tonic-gate 	| EQEXP
201*7c478bd9Sstevel@tonic-gate 		= {
202*7c478bd9Sstevel@tonic-gate 			$$ = "^";
203*7c478bd9Sstevel@tonic-gate 		}
204*7c478bd9Sstevel@tonic-gate 	;
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate fprefix	: _FOR '(' e ';'
207*7c478bd9Sstevel@tonic-gate 		= {
208*7c478bd9Sstevel@tonic-gate 			$$ = $3;
209*7c478bd9Sstevel@tonic-gate 		}
210*7c478bd9Sstevel@tonic-gate 	;
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate BLEV	:
213*7c478bd9Sstevel@tonic-gate 		= --bindx;
214*7c478bd9Sstevel@tonic-gate 	;
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate slist	: stat
217*7c478bd9Sstevel@tonic-gate 	| slist tail stat
218*7c478bd9Sstevel@tonic-gate 		= bundle(2, $1, $3);
219*7c478bd9Sstevel@tonic-gate 	;
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate tail	: '\n'
222*7c478bd9Sstevel@tonic-gate 		= {
223*7c478bd9Sstevel@tonic-gate 			ln++;
224*7c478bd9Sstevel@tonic-gate 		}
225*7c478bd9Sstevel@tonic-gate 	| ';'
226*7c478bd9Sstevel@tonic-gate 	;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate re	: e EQ e
229*7c478bd9Sstevel@tonic-gate 		= {
230*7c478bd9Sstevel@tonic-gate 			$$ = bundle(3, $1, $3, "=");
231*7c478bd9Sstevel@tonic-gate 		}
232*7c478bd9Sstevel@tonic-gate 	| e '<' e
233*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, ">");
234*7c478bd9Sstevel@tonic-gate 	| e '>' e
235*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "<");
236*7c478bd9Sstevel@tonic-gate 	| e NE e
237*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "!=");
238*7c478bd9Sstevel@tonic-gate 	| e GE e
239*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "!>");
240*7c478bd9Sstevel@tonic-gate 	| e LE e
241*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "!<");
242*7c478bd9Sstevel@tonic-gate 	| e
243*7c478bd9Sstevel@tonic-gate 		= bundle(2, $1, " 0!=");
244*7c478bd9Sstevel@tonic-gate 	;
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate e	: e '+' e
247*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "+");
248*7c478bd9Sstevel@tonic-gate 	| e '-' e
249*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "-");
250*7c478bd9Sstevel@tonic-gate 	| '-' e		%prec UMINUS
251*7c478bd9Sstevel@tonic-gate 		= bundle(3, " 0", $2, "-");
252*7c478bd9Sstevel@tonic-gate 	| e '*' e
253*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "*");
254*7c478bd9Sstevel@tonic-gate 	| e '/' e
255*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "/");
256*7c478bd9Sstevel@tonic-gate 	| e '%' e
257*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "%%");
258*7c478bd9Sstevel@tonic-gate 	| e '^' e
259*7c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "^");
260*7c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']'
261*7c478bd9Sstevel@tonic-gate 		= bundle(3, $3, ";", geta($1));
262*7c478bd9Sstevel@tonic-gate 	| LETTER INCR
263*7c478bd9Sstevel@tonic-gate 		= bundle(4, "l", $1, "d1+s", $1);
264*7c478bd9Sstevel@tonic-gate 	| INCR LETTER
265*7c478bd9Sstevel@tonic-gate 		= bundle(4, "l", $2, "1+ds", $2);
266*7c478bd9Sstevel@tonic-gate 	| DECR LETTER
267*7c478bd9Sstevel@tonic-gate 		= bundle(4, "l", $2, "1-ds", $2);
268*7c478bd9Sstevel@tonic-gate 	| LETTER DECR
269*7c478bd9Sstevel@tonic-gate 		= bundle(4, "l", $1, "d1-s", $1);
270*7c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' INCR
271*7c478bd9Sstevel@tonic-gate 		= bundle(7, $3, ";", geta($1), "d1+", $3, ":", geta($1));
272*7c478bd9Sstevel@tonic-gate 	| INCR LETTER '[' e ']'
273*7c478bd9Sstevel@tonic-gate 		= bundle(7, $4, ";", geta($2), "1+d", $4, ":", geta($2));
274*7c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' DECR
275*7c478bd9Sstevel@tonic-gate 		= bundle(7, $3, ";", geta($1), "d1-", $3, ":", geta($1));
276*7c478bd9Sstevel@tonic-gate 	| DECR LETTER '[' e ']'
277*7c478bd9Sstevel@tonic-gate 		= bundle(7, $4, ";", geta($2), "1-d", $4, ":", geta($2));
278*7c478bd9Sstevel@tonic-gate 	| SCALE INCR
279*7c478bd9Sstevel@tonic-gate 		= bundle(1, "Kd1+k");
280*7c478bd9Sstevel@tonic-gate 	| INCR SCALE
281*7c478bd9Sstevel@tonic-gate 		= bundle(1, "K1+dk");
282*7c478bd9Sstevel@tonic-gate 	| SCALE DECR
283*7c478bd9Sstevel@tonic-gate 		= bundle(1, "Kd1-k");
284*7c478bd9Sstevel@tonic-gate 	| DECR SCALE
285*7c478bd9Sstevel@tonic-gate 		= bundle(1, "K1-dk");
286*7c478bd9Sstevel@tonic-gate 	| BASE INCR
287*7c478bd9Sstevel@tonic-gate 		= bundle(1, "Id1+i");
288*7c478bd9Sstevel@tonic-gate 	| INCR BASE
289*7c478bd9Sstevel@tonic-gate 		= bundle(1, "I1+di");
290*7c478bd9Sstevel@tonic-gate 	| BASE DECR
291*7c478bd9Sstevel@tonic-gate 		= bundle(1, "Id1-i");
292*7c478bd9Sstevel@tonic-gate 	| DECR BASE
293*7c478bd9Sstevel@tonic-gate 		= bundle(1, "I1-di");
294*7c478bd9Sstevel@tonic-gate 	| OBASE INCR
295*7c478bd9Sstevel@tonic-gate 		= bundle(1, "Od1+o");
296*7c478bd9Sstevel@tonic-gate 	| INCR OBASE
297*7c478bd9Sstevel@tonic-gate 		= bundle(1, "O1+do");
298*7c478bd9Sstevel@tonic-gate 	| OBASE DECR
299*7c478bd9Sstevel@tonic-gate 		= bundle(1, "Od1-o");
300*7c478bd9Sstevel@tonic-gate 	| DECR OBASE
301*7c478bd9Sstevel@tonic-gate 		= bundle(1, "O1-do");
302*7c478bd9Sstevel@tonic-gate 	| LETTER '(' cargs ')'
303*7c478bd9Sstevel@tonic-gate 		= bundle(4, $3, "l", getf($1), "x");
304*7c478bd9Sstevel@tonic-gate 	| LETTER '(' ')'
305*7c478bd9Sstevel@tonic-gate 		= bundle(3, "l", getf($1), "x");
306*7c478bd9Sstevel@tonic-gate 	| cons
307*7c478bd9Sstevel@tonic-gate 		= bundle(2, " ", $1);
308*7c478bd9Sstevel@tonic-gate 	| DOT cons
309*7c478bd9Sstevel@tonic-gate 		= bundle(2, " .", $2);
310*7c478bd9Sstevel@tonic-gate 	| cons DOT cons
311*7c478bd9Sstevel@tonic-gate 		= bundle(4, " ", $1, ".", $3);
312*7c478bd9Sstevel@tonic-gate 	| cons DOT
313*7c478bd9Sstevel@tonic-gate 		= bundle(3, " ", $1, ".");
314*7c478bd9Sstevel@tonic-gate 	| DOT
315*7c478bd9Sstevel@tonic-gate 		= {
316*7c478bd9Sstevel@tonic-gate 			$<cptr>$ = "l.";
317*7c478bd9Sstevel@tonic-gate 		}
318*7c478bd9Sstevel@tonic-gate 	| LETTER
319*7c478bd9Sstevel@tonic-gate 		= bundle(2, "l", $1);
320*7c478bd9Sstevel@tonic-gate 	| LETTER '=' e
321*7c478bd9Sstevel@tonic-gate 		= bundle(3, $3, "ds", $1);
322*7c478bd9Sstevel@tonic-gate 	| LETTER EQOP e		%prec '='
323*7c478bd9Sstevel@tonic-gate 		= bundle(6, "l", $1, $3, $2, "ds", $1);
324*7c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' '=' e
325*7c478bd9Sstevel@tonic-gate 		= bundle(5, $6, "d", $3, ":", geta($1));
326*7c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' EQOP e
327*7c478bd9Sstevel@tonic-gate 		= {
328*7c478bd9Sstevel@tonic-gate 			bundle(9, $3, ";", geta($1), $6, $5, "d", $3, ":",
329*7c478bd9Sstevel@tonic-gate 			    geta($1));
330*7c478bd9Sstevel@tonic-gate 		}
331*7c478bd9Sstevel@tonic-gate 	| LENGTH '(' e ')'
332*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "Z");
333*7c478bd9Sstevel@tonic-gate 	| SCALE '(' e ')'
334*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "X");	/* must be before '(' e ')' */
335*7c478bd9Sstevel@tonic-gate 	| '(' e ')'
336*7c478bd9Sstevel@tonic-gate 		= {
337*7c478bd9Sstevel@tonic-gate 			$$ = $2;
338*7c478bd9Sstevel@tonic-gate 		}
339*7c478bd9Sstevel@tonic-gate 	| '?'
340*7c478bd9Sstevel@tonic-gate 		= bundle(1, "?");
341*7c478bd9Sstevel@tonic-gate 	| SQRT '(' e ')'
342*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "v");
343*7c478bd9Sstevel@tonic-gate 	| '~' LETTER
344*7c478bd9Sstevel@tonic-gate 		= bundle(2, "L", $2);
345*7c478bd9Sstevel@tonic-gate 	| SCALE '=' e
346*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "dk");
347*7c478bd9Sstevel@tonic-gate 	| SCALE EQOP e		%prec '='
348*7c478bd9Sstevel@tonic-gate 		= bundle(4, "K", $3, $2, "dk");
349*7c478bd9Sstevel@tonic-gate 	| BASE '=' e
350*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "di");
351*7c478bd9Sstevel@tonic-gate 	| BASE EQOP e		%prec '='
352*7c478bd9Sstevel@tonic-gate 		= bundle(4, "I", $3, $2, "di");
353*7c478bd9Sstevel@tonic-gate 	| OBASE '=' e
354*7c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "do");
355*7c478bd9Sstevel@tonic-gate 	| OBASE EQOP e		%prec '='
356*7c478bd9Sstevel@tonic-gate 		= bundle(4, "O", $3, $2, "do");
357*7c478bd9Sstevel@tonic-gate 	| SCALE
358*7c478bd9Sstevel@tonic-gate 		= bundle(1, "K");
359*7c478bd9Sstevel@tonic-gate 	| BASE
360*7c478bd9Sstevel@tonic-gate 		= bundle(1, "I");
361*7c478bd9Sstevel@tonic-gate 	| OBASE
362*7c478bd9Sstevel@tonic-gate 		= bundle(1, "O");
363*7c478bd9Sstevel@tonic-gate 	;
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate cargs	: eora
366*7c478bd9Sstevel@tonic-gate 	| cargs ',' eora
367*7c478bd9Sstevel@tonic-gate 		= bundle(2, $1, $3);
368*7c478bd9Sstevel@tonic-gate 	;
369*7c478bd9Sstevel@tonic-gate eora	: e
370*7c478bd9Sstevel@tonic-gate 	| LETTER '[' ']'
371*7c478bd9Sstevel@tonic-gate 		= bundle(2, "l", geta($1));
372*7c478bd9Sstevel@tonic-gate 	;
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate cons	: constant
375*7c478bd9Sstevel@tonic-gate 		= {
376*7c478bd9Sstevel@tonic-gate 			*cp++ = '\0';
377*7c478bd9Sstevel@tonic-gate 		}
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate constant: '_'
380*7c478bd9Sstevel@tonic-gate 		= {
381*7c478bd9Sstevel@tonic-gate 			checkbuffer();
382*7c478bd9Sstevel@tonic-gate 			$<cptr>$ = cp;
383*7c478bd9Sstevel@tonic-gate 			*cp++ = '_';
384*7c478bd9Sstevel@tonic-gate 		}
385*7c478bd9Sstevel@tonic-gate 	| DIGIT
386*7c478bd9Sstevel@tonic-gate 		= {
387*7c478bd9Sstevel@tonic-gate 			checkbuffer();
388*7c478bd9Sstevel@tonic-gate 			$<cptr>$ = cp;
389*7c478bd9Sstevel@tonic-gate 			*cp++ = $1;
390*7c478bd9Sstevel@tonic-gate 		}
391*7c478bd9Sstevel@tonic-gate 	| constant DIGIT
392*7c478bd9Sstevel@tonic-gate 		= {
393*7c478bd9Sstevel@tonic-gate 			checkbuffer();
394*7c478bd9Sstevel@tonic-gate 			*cp++ = $2;
395*7c478bd9Sstevel@tonic-gate 		}
396*7c478bd9Sstevel@tonic-gate 	;
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate CRS	:
399*7c478bd9Sstevel@tonic-gate 		= {
400*7c478bd9Sstevel@tonic-gate 			checkbuffer();
401*7c478bd9Sstevel@tonic-gate 			$$ = cp;
402*7c478bd9Sstevel@tonic-gate 			*cp++ = crs++;
403*7c478bd9Sstevel@tonic-gate 			*cp++ = '\0';
404*7c478bd9Sstevel@tonic-gate 			if (crs == '[')
405*7c478bd9Sstevel@tonic-gate 				crs += 3;
406*7c478bd9Sstevel@tonic-gate 			if (crs == 'a')
407*7c478bd9Sstevel@tonic-gate 				crs = '{';
408*7c478bd9Sstevel@tonic-gate 			if (crs >= 0241) {
409*7c478bd9Sstevel@tonic-gate 				yyerror("program too big");
410*7c478bd9Sstevel@tonic-gate 				getout(1);
411*7c478bd9Sstevel@tonic-gate 			}
412*7c478bd9Sstevel@tonic-gate 			bstack[bindx++] = lev++;
413*7c478bd9Sstevel@tonic-gate 		}
414*7c478bd9Sstevel@tonic-gate 	;
415*7c478bd9Sstevel@tonic-gate 
416*7c478bd9Sstevel@tonic-gate def	: _DEFINE LETTER '('
417*7c478bd9Sstevel@tonic-gate 		= {
418*7c478bd9Sstevel@tonic-gate 			$$ = getf($2);
419*7c478bd9Sstevel@tonic-gate 			pre = (int *)"";
420*7c478bd9Sstevel@tonic-gate 			post = (int *)"";
421*7c478bd9Sstevel@tonic-gate 			lev = 1;
422*7c478bd9Sstevel@tonic-gate 			bstack[bindx = 0] = 0;
423*7c478bd9Sstevel@tonic-gate 		}
424*7c478bd9Sstevel@tonic-gate 	;
425*7c478bd9Sstevel@tonic-gate 
426*7c478bd9Sstevel@tonic-gate dargs	:		/* empty */
427*7c478bd9Sstevel@tonic-gate 	| lora
428*7c478bd9Sstevel@tonic-gate 		= {
429*7c478bd9Sstevel@tonic-gate 			pp($1);
430*7c478bd9Sstevel@tonic-gate 		}
431*7c478bd9Sstevel@tonic-gate 	| dargs ',' lora
432*7c478bd9Sstevel@tonic-gate 		= {
433*7c478bd9Sstevel@tonic-gate 			pp($3);
434*7c478bd9Sstevel@tonic-gate 		}
435*7c478bd9Sstevel@tonic-gate 	;
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate dlets	: lora
438*7c478bd9Sstevel@tonic-gate 		= tp($1);
439*7c478bd9Sstevel@tonic-gate 	| dlets ',' lora
440*7c478bd9Sstevel@tonic-gate 		= tp($3);
441*7c478bd9Sstevel@tonic-gate 	;
442*7c478bd9Sstevel@tonic-gate 
443*7c478bd9Sstevel@tonic-gate lora	: LETTER
444*7c478bd9Sstevel@tonic-gate 		= {
445*7c478bd9Sstevel@tonic-gate 			$<cptr>$ = $1;
446*7c478bd9Sstevel@tonic-gate 		}
447*7c478bd9Sstevel@tonic-gate 	| LETTER '[' ']'
448*7c478bd9Sstevel@tonic-gate 		= {
449*7c478bd9Sstevel@tonic-gate 			$$ = geta($1);
450*7c478bd9Sstevel@tonic-gate 		}
451*7c478bd9Sstevel@tonic-gate 	;
452*7c478bd9Sstevel@tonic-gate 
453*7c478bd9Sstevel@tonic-gate %%
454*7c478bd9Sstevel@tonic-gate #define	error	256
455*7c478bd9Sstevel@tonic-gate 
456*7c478bd9Sstevel@tonic-gate int	peekc = -1;
457*7c478bd9Sstevel@tonic-gate int	ifile;			/* current index into sargv */
458*7c478bd9Sstevel@tonic-gate int	sargc;			/* size of sargv[] */
459*7c478bd9Sstevel@tonic-gate char	**sargv;		/* saved arg list without options */
460*7c478bd9Sstevel@tonic-gate 
461*7c478bd9Sstevel@tonic-gate char funtab[52] = {
462*7c478bd9Sstevel@tonic-gate 	01, 0, 02, 0, 03, 0, 04, 0, 05, 0, 06, 0, 07, 0,
463*7c478bd9Sstevel@tonic-gate 	010, 0, 011, 0, 012, 0, 013, 0, 014, 0, 015, 0, 016, 0, 017, 0,
464*7c478bd9Sstevel@tonic-gate 	020, 0, 021, 0, 022, 0, 023, 0, 024, 0, 025, 0, 026, 0, 027, 0,
465*7c478bd9Sstevel@tonic-gate 	030, 0, 031, 0, 032, 0
466*7c478bd9Sstevel@tonic-gate };
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate unsigned char atab[52] = {
469*7c478bd9Sstevel@tonic-gate 	0241, 0, 0242, 0, 0243, 0, 0244, 0, 0245, 0, 0246, 0, 0247, 0, 0250, 0,
470*7c478bd9Sstevel@tonic-gate 	0251, 0, 0252, 0, 0253, 0, 0254, 0, 0255, 0, 0256, 0, 0257, 0, 0260, 0,
471*7c478bd9Sstevel@tonic-gate 	0261, 0, 0262, 0, 0263, 0, 0264, 0, 0265, 0, 0266, 0, 0267, 0, 0270, 0,
472*7c478bd9Sstevel@tonic-gate 	0271, 0, 0272, 0
473*7c478bd9Sstevel@tonic-gate };
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate char *letr[26] = {
476*7c478bd9Sstevel@tonic-gate 	"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
477*7c478bd9Sstevel@tonic-gate 	"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
478*7c478bd9Sstevel@tonic-gate 	"u", "v", "w", "x", "y", "z"
479*7c478bd9Sstevel@tonic-gate };
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate yylex()
482*7c478bd9Sstevel@tonic-gate {
483*7c478bd9Sstevel@tonic-gate 	int c, ch;
484*7c478bd9Sstevel@tonic-gate 
485*7c478bd9Sstevel@tonic-gate restart:
486*7c478bd9Sstevel@tonic-gate 	c = getch();
487*7c478bd9Sstevel@tonic-gate 	peekc = -1;
488*7c478bd9Sstevel@tonic-gate 	while (c == ' ' || c == '\t')
489*7c478bd9Sstevel@tonic-gate 		c = getch();
490*7c478bd9Sstevel@tonic-gate 	if (c == '\\') {
491*7c478bd9Sstevel@tonic-gate 		(void) getch();
492*7c478bd9Sstevel@tonic-gate 		goto restart;
493*7c478bd9Sstevel@tonic-gate 	}
494*7c478bd9Sstevel@tonic-gate 	if (c <= 'z' && c >= 'a') {
495*7c478bd9Sstevel@tonic-gate 		/* look ahead to look for reserved words */
496*7c478bd9Sstevel@tonic-gate 		peekc = getch();
497*7c478bd9Sstevel@tonic-gate 		if (peekc >= 'a' && peekc <= 'z') {
498*7c478bd9Sstevel@tonic-gate 			/* must be reserved word */
499*7c478bd9Sstevel@tonic-gate 			if (c == 'i' && peekc == 'f') {
500*7c478bd9Sstevel@tonic-gate 				c = _IF;
501*7c478bd9Sstevel@tonic-gate 				goto skip;
502*7c478bd9Sstevel@tonic-gate 			}
503*7c478bd9Sstevel@tonic-gate 			if (c == 'w' && peekc == 'h') {
504*7c478bd9Sstevel@tonic-gate 				c = _WHILE;
505*7c478bd9Sstevel@tonic-gate 				goto skip;
506*7c478bd9Sstevel@tonic-gate 			}
507*7c478bd9Sstevel@tonic-gate 			if (c == 'f' && peekc == 'o') {
508*7c478bd9Sstevel@tonic-gate 				c = _FOR;
509*7c478bd9Sstevel@tonic-gate 				goto skip;
510*7c478bd9Sstevel@tonic-gate 			}
511*7c478bd9Sstevel@tonic-gate 			if (c == 's' && peekc == 'q') {
512*7c478bd9Sstevel@tonic-gate 				c = SQRT;
513*7c478bd9Sstevel@tonic-gate 				goto skip;
514*7c478bd9Sstevel@tonic-gate 			}
515*7c478bd9Sstevel@tonic-gate 			if (c == 'r' && peekc == 'e') {
516*7c478bd9Sstevel@tonic-gate 				c = _RETURN;
517*7c478bd9Sstevel@tonic-gate 				goto skip;
518*7c478bd9Sstevel@tonic-gate 			}
519*7c478bd9Sstevel@tonic-gate 			if (c == 'b' && peekc == 'r') {
520*7c478bd9Sstevel@tonic-gate 				c = _BREAK;
521*7c478bd9Sstevel@tonic-gate 				goto skip;
522*7c478bd9Sstevel@tonic-gate 			}
523*7c478bd9Sstevel@tonic-gate 			if (c == 'd' && peekc == 'e') {
524*7c478bd9Sstevel@tonic-gate 				c = _DEFINE;
525*7c478bd9Sstevel@tonic-gate 				goto skip;
526*7c478bd9Sstevel@tonic-gate 			}
527*7c478bd9Sstevel@tonic-gate 			if (c == 's' && peekc == 'c') {
528*7c478bd9Sstevel@tonic-gate 				c = SCALE;
529*7c478bd9Sstevel@tonic-gate 				goto skip;
530*7c478bd9Sstevel@tonic-gate 			}
531*7c478bd9Sstevel@tonic-gate 			if (c == 'b' && peekc == 'a') {
532*7c478bd9Sstevel@tonic-gate 				c = BASE;
533*7c478bd9Sstevel@tonic-gate 				goto skip;
534*7c478bd9Sstevel@tonic-gate 			}
535*7c478bd9Sstevel@tonic-gate 			if (c == 'i' && peekc == 'b') {
536*7c478bd9Sstevel@tonic-gate 				c = BASE;
537*7c478bd9Sstevel@tonic-gate 				goto skip;
538*7c478bd9Sstevel@tonic-gate 			}
539*7c478bd9Sstevel@tonic-gate 			if (c == 'o' && peekc == 'b') {
540*7c478bd9Sstevel@tonic-gate 				c = OBASE;
541*7c478bd9Sstevel@tonic-gate 				goto skip;
542*7c478bd9Sstevel@tonic-gate 			}
543*7c478bd9Sstevel@tonic-gate 			if (c == 'd' && peekc == 'i') {
544*7c478bd9Sstevel@tonic-gate 				c = FFF;
545*7c478bd9Sstevel@tonic-gate 				goto skip;
546*7c478bd9Sstevel@tonic-gate 			}
547*7c478bd9Sstevel@tonic-gate 			if (c == 'a' && peekc == 'u') {
548*7c478bd9Sstevel@tonic-gate 				c = _AUTO;
549*7c478bd9Sstevel@tonic-gate 				goto skip;
550*7c478bd9Sstevel@tonic-gate 			}
551*7c478bd9Sstevel@tonic-gate 			if (c == 'l' && peekc == 'e') {
552*7c478bd9Sstevel@tonic-gate 				c = LENGTH;
553*7c478bd9Sstevel@tonic-gate 				goto skip;
554*7c478bd9Sstevel@tonic-gate 			}
555*7c478bd9Sstevel@tonic-gate 			if (c == 'q' && peekc == 'u') {
556*7c478bd9Sstevel@tonic-gate 				getout(0);
557*7c478bd9Sstevel@tonic-gate 			}
558*7c478bd9Sstevel@tonic-gate 			/* could not be found */
559*7c478bd9Sstevel@tonic-gate 			return (error);
560*7c478bd9Sstevel@tonic-gate 
561*7c478bd9Sstevel@tonic-gate skip:	/* skip over rest of word */
562*7c478bd9Sstevel@tonic-gate 			peekc = -1;
563*7c478bd9Sstevel@tonic-gate 			while ((ch = getch()) >= 'a' && ch <= 'z')
564*7c478bd9Sstevel@tonic-gate 				;
565*7c478bd9Sstevel@tonic-gate 			peekc = ch;
566*7c478bd9Sstevel@tonic-gate 			return (c);
567*7c478bd9Sstevel@tonic-gate 		}
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate 		/* usual case; just one single letter */
570*7c478bd9Sstevel@tonic-gate 
571*7c478bd9Sstevel@tonic-gate 		yylval.cptr = letr[c-'a'];
572*7c478bd9Sstevel@tonic-gate 		return (LETTER);
573*7c478bd9Sstevel@tonic-gate 	}
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate 	if (c >= '0' && c <= '9' || c >= 'A' && c <= 'F') {
576*7c478bd9Sstevel@tonic-gate 		yylval.cc = c;
577*7c478bd9Sstevel@tonic-gate 		return (DIGIT);
578*7c478bd9Sstevel@tonic-gate 	}
579*7c478bd9Sstevel@tonic-gate 
580*7c478bd9Sstevel@tonic-gate 	switch (c) {
581*7c478bd9Sstevel@tonic-gate 	case '.':
582*7c478bd9Sstevel@tonic-gate 		return (DOT);
583*7c478bd9Sstevel@tonic-gate 
584*7c478bd9Sstevel@tonic-gate 	case '=':
585*7c478bd9Sstevel@tonic-gate 		switch ((peekc = getch())) {
586*7c478bd9Sstevel@tonic-gate 		case '=':
587*7c478bd9Sstevel@tonic-gate 			c = EQ;
588*7c478bd9Sstevel@tonic-gate 			goto gotit;
589*7c478bd9Sstevel@tonic-gate 
590*7c478bd9Sstevel@tonic-gate 		case '+':
591*7c478bd9Sstevel@tonic-gate 			c = EQPL;
592*7c478bd9Sstevel@tonic-gate 			goto gotit;
593*7c478bd9Sstevel@tonic-gate 
594*7c478bd9Sstevel@tonic-gate 		case '-':
595*7c478bd9Sstevel@tonic-gate 			c = EQMI;
596*7c478bd9Sstevel@tonic-gate 			goto gotit;
597*7c478bd9Sstevel@tonic-gate 
598*7c478bd9Sstevel@tonic-gate 		case '*':
599*7c478bd9Sstevel@tonic-gate 			c = EQMUL;
600*7c478bd9Sstevel@tonic-gate 			goto gotit;
601*7c478bd9Sstevel@tonic-gate 
602*7c478bd9Sstevel@tonic-gate 		case '/':
603*7c478bd9Sstevel@tonic-gate 			c = EQDIV;
604*7c478bd9Sstevel@tonic-gate 			goto gotit;
605*7c478bd9Sstevel@tonic-gate 
606*7c478bd9Sstevel@tonic-gate 		case '%':
607*7c478bd9Sstevel@tonic-gate 			c = EQREM;
608*7c478bd9Sstevel@tonic-gate 			goto gotit;
609*7c478bd9Sstevel@tonic-gate 
610*7c478bd9Sstevel@tonic-gate 		case '^':
611*7c478bd9Sstevel@tonic-gate 			c = EQEXP;
612*7c478bd9Sstevel@tonic-gate 			goto gotit;
613*7c478bd9Sstevel@tonic-gate 
614*7c478bd9Sstevel@tonic-gate 		default:
615*7c478bd9Sstevel@tonic-gate 			return ('=');
616*7c478bd9Sstevel@tonic-gate gotit:
617*7c478bd9Sstevel@tonic-gate 			peekc = -1;
618*7c478bd9Sstevel@tonic-gate 			return (c);
619*7c478bd9Sstevel@tonic-gate 		}
620*7c478bd9Sstevel@tonic-gate 
621*7c478bd9Sstevel@tonic-gate 	case '+':
622*7c478bd9Sstevel@tonic-gate 		return (cpeek('+', INCR, '=', EQPL, '+'));
623*7c478bd9Sstevel@tonic-gate 
624*7c478bd9Sstevel@tonic-gate 	case '-':
625*7c478bd9Sstevel@tonic-gate 		return (cpeek('-', DECR, '=', EQMI, '-'));
626*7c478bd9Sstevel@tonic-gate 
627*7c478bd9Sstevel@tonic-gate 	case '*':
628*7c478bd9Sstevel@tonic-gate 		return (cpeek('=', EQMUL, '\0', 0, '*'));
629*7c478bd9Sstevel@tonic-gate 
630*7c478bd9Sstevel@tonic-gate 	case '%':
631*7c478bd9Sstevel@tonic-gate 		return (cpeek('=', EQREM, '\0', 0, '%'));
632*7c478bd9Sstevel@tonic-gate 
633*7c478bd9Sstevel@tonic-gate 	case '^':
634*7c478bd9Sstevel@tonic-gate 		return (cpeek('=', EQEXP, '\0', 0, '^'));
635*7c478bd9Sstevel@tonic-gate 
636*7c478bd9Sstevel@tonic-gate 	case '<':
637*7c478bd9Sstevel@tonic-gate 		return (cpeek('=', LE, '\0', 0, '<'));
638*7c478bd9Sstevel@tonic-gate 
639*7c478bd9Sstevel@tonic-gate 	case '>':
640*7c478bd9Sstevel@tonic-gate 		return (cpeek('=', GE, '\0', 0, '>'));
641*7c478bd9Sstevel@tonic-gate 
642*7c478bd9Sstevel@tonic-gate 	case '!':
643*7c478bd9Sstevel@tonic-gate 		return (cpeek('=', NE, '\0', 0, '!'));
644*7c478bd9Sstevel@tonic-gate 
645*7c478bd9Sstevel@tonic-gate 	case '/':
646*7c478bd9Sstevel@tonic-gate 		if ((peekc = getch()) == '=') {
647*7c478bd9Sstevel@tonic-gate 			peekc = -1;
648*7c478bd9Sstevel@tonic-gate 			return (EQDIV);
649*7c478bd9Sstevel@tonic-gate 		}
650*7c478bd9Sstevel@tonic-gate 		if (peekc == '*') {
651*7c478bd9Sstevel@tonic-gate 			peekc = -1;
652*7c478bd9Sstevel@tonic-gate 			while ((getch() != '*') || ((peekc = getch()) != '/'))
653*7c478bd9Sstevel@tonic-gate 				;
654*7c478bd9Sstevel@tonic-gate 			peekc = -1;
655*7c478bd9Sstevel@tonic-gate 			goto restart;
656*7c478bd9Sstevel@tonic-gate 		}
657*7c478bd9Sstevel@tonic-gate 		else
658*7c478bd9Sstevel@tonic-gate 			return (c);
659*7c478bd9Sstevel@tonic-gate 
660*7c478bd9Sstevel@tonic-gate 	case '"':
661*7c478bd9Sstevel@tonic-gate 		yylval.cptr = str;
662*7c478bd9Sstevel@tonic-gate 		while ((c = getch()) != '"') {
663*7c478bd9Sstevel@tonic-gate 			*str++ = c;
664*7c478bd9Sstevel@tonic-gate 			if (str >= &string[STRING_SIZE-1]) {
665*7c478bd9Sstevel@tonic-gate 				yyerror("string space exceeded");
666*7c478bd9Sstevel@tonic-gate 				getout(1);
667*7c478bd9Sstevel@tonic-gate 			}
668*7c478bd9Sstevel@tonic-gate 		}
669*7c478bd9Sstevel@tonic-gate 		*str++ = '\0';
670*7c478bd9Sstevel@tonic-gate 		return (QSTR);
671*7c478bd9Sstevel@tonic-gate 
672*7c478bd9Sstevel@tonic-gate 	default:
673*7c478bd9Sstevel@tonic-gate 		return (c);
674*7c478bd9Sstevel@tonic-gate 	}
675*7c478bd9Sstevel@tonic-gate }
676*7c478bd9Sstevel@tonic-gate 
677*7c478bd9Sstevel@tonic-gate cpeek(c1, yes1, c2, yes2, none)
678*7c478bd9Sstevel@tonic-gate char c1, c2, none;
679*7c478bd9Sstevel@tonic-gate {
680*7c478bd9Sstevel@tonic-gate 	int r;
681*7c478bd9Sstevel@tonic-gate 
682*7c478bd9Sstevel@tonic-gate 	peekc = getch();
683*7c478bd9Sstevel@tonic-gate 	if (peekc == c1)
684*7c478bd9Sstevel@tonic-gate 		r = yes1;
685*7c478bd9Sstevel@tonic-gate 	else if (peekc == c2)
686*7c478bd9Sstevel@tonic-gate 		r = yes2;
687*7c478bd9Sstevel@tonic-gate 	else
688*7c478bd9Sstevel@tonic-gate 		return (none);
689*7c478bd9Sstevel@tonic-gate 	peekc = -1;
690*7c478bd9Sstevel@tonic-gate 	return (r);
691*7c478bd9Sstevel@tonic-gate }
692*7c478bd9Sstevel@tonic-gate 
693*7c478bd9Sstevel@tonic-gate getch()
694*7c478bd9Sstevel@tonic-gate {
695*7c478bd9Sstevel@tonic-gate 	int ch;
696*7c478bd9Sstevel@tonic-gate 	char mbuf[LINE_MAX];
697*7c478bd9Sstevel@tonic-gate 
698*7c478bd9Sstevel@tonic-gate loop:
699*7c478bd9Sstevel@tonic-gate 	ch = (peekc < 0) ? getc(in) : peekc;
700*7c478bd9Sstevel@tonic-gate 	peekc = -1;
701*7c478bd9Sstevel@tonic-gate 	if (ch != EOF)
702*7c478bd9Sstevel@tonic-gate 		return (ch);
703*7c478bd9Sstevel@tonic-gate 
704*7c478bd9Sstevel@tonic-gate 	if (++ifile >= sargc) {
705*7c478bd9Sstevel@tonic-gate 		if (ifile >= sargc+1)
706*7c478bd9Sstevel@tonic-gate 			getout(0);
707*7c478bd9Sstevel@tonic-gate 		in = stdin;
708*7c478bd9Sstevel@tonic-gate 		ln = 0;
709*7c478bd9Sstevel@tonic-gate 		goto loop;
710*7c478bd9Sstevel@tonic-gate 	}
711*7c478bd9Sstevel@tonic-gate 
712*7c478bd9Sstevel@tonic-gate 	(void) fclose(in);
713*7c478bd9Sstevel@tonic-gate 	if ((in = fopen(sargv[ifile], "r")) != NULL) {
714*7c478bd9Sstevel@tonic-gate 		ln = 0;
715*7c478bd9Sstevel@tonic-gate 		ss = sargv[ifile];
716*7c478bd9Sstevel@tonic-gate 		goto loop;
717*7c478bd9Sstevel@tonic-gate 	}
718*7c478bd9Sstevel@tonic-gate 	(void) snprintf(mbuf, sizeof (mbuf), "can't open input file %s",
719*7c478bd9Sstevel@tonic-gate 		sargv[ifile]);
720*7c478bd9Sstevel@tonic-gate 	ln = -1;
721*7c478bd9Sstevel@tonic-gate 	ss = "command line";
722*7c478bd9Sstevel@tonic-gate 	yyerror(mbuf);
723*7c478bd9Sstevel@tonic-gate 	getout(1);
724*7c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
725*7c478bd9Sstevel@tonic-gate }
726*7c478bd9Sstevel@tonic-gate 
727*7c478bd9Sstevel@tonic-gate #define	b_sp_max	5000
728*7c478bd9Sstevel@tonic-gate int b_space[b_sp_max];
729*7c478bd9Sstevel@tonic-gate int *b_sp_nxt = { b_space };
730*7c478bd9Sstevel@tonic-gate 
731*7c478bd9Sstevel@tonic-gate int	bdebug = 0;
732*7c478bd9Sstevel@tonic-gate 
733*7c478bd9Sstevel@tonic-gate static int *
734*7c478bd9Sstevel@tonic-gate bundle(int i, ...)
735*7c478bd9Sstevel@tonic-gate {
736*7c478bd9Sstevel@tonic-gate 	va_list ap;
737*7c478bd9Sstevel@tonic-gate 	int *q;
738*7c478bd9Sstevel@tonic-gate 
739*7c478bd9Sstevel@tonic-gate 	va_start(ap, i);
740*7c478bd9Sstevel@tonic-gate 	q = b_sp_nxt;
741*7c478bd9Sstevel@tonic-gate 	if (bdebug)
742*7c478bd9Sstevel@tonic-gate 		printf("bundle %d elements at %o\n", i, q);
743*7c478bd9Sstevel@tonic-gate 	while (i-- > 0) {
744*7c478bd9Sstevel@tonic-gate 		if (b_sp_nxt >= & b_space[b_sp_max])
745*7c478bd9Sstevel@tonic-gate 			yyerror("bundling space exceeded");
746*7c478bd9Sstevel@tonic-gate 		*b_sp_nxt++ = va_arg(ap, int);
747*7c478bd9Sstevel@tonic-gate 	}
748*7c478bd9Sstevel@tonic-gate 	* b_sp_nxt++ = 0;
749*7c478bd9Sstevel@tonic-gate 	yyval.iptr = q;
750*7c478bd9Sstevel@tonic-gate 	va_end(ap);
751*7c478bd9Sstevel@tonic-gate 	return (q);
752*7c478bd9Sstevel@tonic-gate }
753*7c478bd9Sstevel@tonic-gate 
754*7c478bd9Sstevel@tonic-gate routput(p)
755*7c478bd9Sstevel@tonic-gate int *p;
756*7c478bd9Sstevel@tonic-gate {
757*7c478bd9Sstevel@tonic-gate 	if (bdebug) printf("routput(%o)\n", p);
758*7c478bd9Sstevel@tonic-gate 	if (p >= &b_space[0] && p < &b_space[b_sp_max]) {
759*7c478bd9Sstevel@tonic-gate 		/* part of a bundle */
760*7c478bd9Sstevel@tonic-gate 		while (*p != 0)
761*7c478bd9Sstevel@tonic-gate 			routput(*p++);
762*7c478bd9Sstevel@tonic-gate 	}
763*7c478bd9Sstevel@tonic-gate 	else
764*7c478bd9Sstevel@tonic-gate 		printf((char *)p);	 /* character string */
765*7c478bd9Sstevel@tonic-gate }
766*7c478bd9Sstevel@tonic-gate 
767*7c478bd9Sstevel@tonic-gate output(p)
768*7c478bd9Sstevel@tonic-gate int *p;
769*7c478bd9Sstevel@tonic-gate {
770*7c478bd9Sstevel@tonic-gate 	routput(p);
771*7c478bd9Sstevel@tonic-gate 	b_sp_nxt = & b_space[0];
772*7c478bd9Sstevel@tonic-gate 	printf("\n");
773*7c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
774*7c478bd9Sstevel@tonic-gate 	cp = cary;
775*7c478bd9Sstevel@tonic-gate 	crs = rcrs;
776*7c478bd9Sstevel@tonic-gate }
777*7c478bd9Sstevel@tonic-gate 
778*7c478bd9Sstevel@tonic-gate conout(p, s)
779*7c478bd9Sstevel@tonic-gate int *p;
780*7c478bd9Sstevel@tonic-gate char *s;
781*7c478bd9Sstevel@tonic-gate {
782*7c478bd9Sstevel@tonic-gate 	printf("[");
783*7c478bd9Sstevel@tonic-gate 	routput(p);
784*7c478bd9Sstevel@tonic-gate 	printf("]s%s\n", s);
785*7c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
786*7c478bd9Sstevel@tonic-gate 	lev--;
787*7c478bd9Sstevel@tonic-gate }
788*7c478bd9Sstevel@tonic-gate 
789*7c478bd9Sstevel@tonic-gate yyerror(s)
790*7c478bd9Sstevel@tonic-gate char *s;
791*7c478bd9Sstevel@tonic-gate {
792*7c478bd9Sstevel@tonic-gate 	if (ifile >= sargc)
793*7c478bd9Sstevel@tonic-gate 		ss = "teletype";
794*7c478bd9Sstevel@tonic-gate 
795*7c478bd9Sstevel@tonic-gate 	if (ss == 0 || *ss == 0)
796*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("%s on line %d\n"), s, ln+1);
797*7c478bd9Sstevel@tonic-gate 	else
798*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("%s on line %d, %s\n"),
799*7c478bd9Sstevel@tonic-gate 		    s, ln+1, ss);
800*7c478bd9Sstevel@tonic-gate 	(void) fflush(stderr);
801*7c478bd9Sstevel@tonic-gate 
802*7c478bd9Sstevel@tonic-gate 	cp = cary;
803*7c478bd9Sstevel@tonic-gate 	crs = rcrs;
804*7c478bd9Sstevel@tonic-gate 	bindx = 0;
805*7c478bd9Sstevel@tonic-gate 	lev = 0;
806*7c478bd9Sstevel@tonic-gate 	b_sp_nxt = &b_space[0];
807*7c478bd9Sstevel@tonic-gate }
808*7c478bd9Sstevel@tonic-gate 
809*7c478bd9Sstevel@tonic-gate checkbuffer()
810*7c478bd9Sstevel@tonic-gate {
811*7c478bd9Sstevel@tonic-gate 	/* Do not exceed the last char in input line buffer */
812*7c478bd9Sstevel@tonic-gate 	if (cp >= cpend) {
813*7c478bd9Sstevel@tonic-gate 		yyerror("line too long\n");
814*7c478bd9Sstevel@tonic-gate 		getout(1);
815*7c478bd9Sstevel@tonic-gate 	}
816*7c478bd9Sstevel@tonic-gate }
817*7c478bd9Sstevel@tonic-gate 
818*7c478bd9Sstevel@tonic-gate pp(s)
819*7c478bd9Sstevel@tonic-gate int *s;
820*7c478bd9Sstevel@tonic-gate {
821*7c478bd9Sstevel@tonic-gate 	/* puts the relevant stuff on pre and post for the letter s */
822*7c478bd9Sstevel@tonic-gate 
823*7c478bd9Sstevel@tonic-gate 	(void) bundle(3, "S", s, pre);
824*7c478bd9Sstevel@tonic-gate 	pre = yyval.iptr;
825*7c478bd9Sstevel@tonic-gate 	(void) bundle(4, post, "L", s, "s.");
826*7c478bd9Sstevel@tonic-gate 	post = yyval.iptr;
827*7c478bd9Sstevel@tonic-gate }
828*7c478bd9Sstevel@tonic-gate 
829*7c478bd9Sstevel@tonic-gate tp(s)
830*7c478bd9Sstevel@tonic-gate int *s;
831*7c478bd9Sstevel@tonic-gate {		/* same as pp, but for temps */
832*7c478bd9Sstevel@tonic-gate 	bundle(3, "0S", s, pre);
833*7c478bd9Sstevel@tonic-gate 	pre = yyval.iptr;
834*7c478bd9Sstevel@tonic-gate 	bundle(4, post, "L", s, "s.");
835*7c478bd9Sstevel@tonic-gate 	post = yyval.iptr;
836*7c478bd9Sstevel@tonic-gate }
837*7c478bd9Sstevel@tonic-gate 
838*7c478bd9Sstevel@tonic-gate yyinit(argc, argv)
839*7c478bd9Sstevel@tonic-gate int argc;
840*7c478bd9Sstevel@tonic-gate char *argv[];
841*7c478bd9Sstevel@tonic-gate {
842*7c478bd9Sstevel@tonic-gate 	char	mbuf[LINE_MAX];
843*7c478bd9Sstevel@tonic-gate 
844*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, SIG_IGN);		/* ignore all interrupts */
845*7c478bd9Sstevel@tonic-gate 
846*7c478bd9Sstevel@tonic-gate 	sargv = argv;
847*7c478bd9Sstevel@tonic-gate 	sargc = argc;
848*7c478bd9Sstevel@tonic-gate 	if (sargc == 0)
849*7c478bd9Sstevel@tonic-gate 		in = stdin;
850*7c478bd9Sstevel@tonic-gate 	else if ((in = fopen(sargv[0], "r")) == NULL) {
851*7c478bd9Sstevel@tonic-gate 		(void) snprintf(mbuf, sizeof (mbuf), "can't open input file %s",
852*7c478bd9Sstevel@tonic-gate 			sargv[0]);
853*7c478bd9Sstevel@tonic-gate 		ln = -1;
854*7c478bd9Sstevel@tonic-gate 		ss = "command line";
855*7c478bd9Sstevel@tonic-gate 		yyerror(mbuf);
856*7c478bd9Sstevel@tonic-gate 		getout(1);
857*7c478bd9Sstevel@tonic-gate 	}
858*7c478bd9Sstevel@tonic-gate 	ifile = 0;
859*7c478bd9Sstevel@tonic-gate 	ln = 0;
860*7c478bd9Sstevel@tonic-gate 	ss = sargv[0];
861*7c478bd9Sstevel@tonic-gate }
862*7c478bd9Sstevel@tonic-gate 
863*7c478bd9Sstevel@tonic-gate static int *
864*7c478bd9Sstevel@tonic-gate getout(code)
865*7c478bd9Sstevel@tonic-gate int code;
866*7c478bd9Sstevel@tonic-gate {
867*7c478bd9Sstevel@tonic-gate 	printf("q");
868*7c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
869*7c478bd9Sstevel@tonic-gate 	exit(code);
870*7c478bd9Sstevel@tonic-gate }
871*7c478bd9Sstevel@tonic-gate 
872*7c478bd9Sstevel@tonic-gate int *
873*7c478bd9Sstevel@tonic-gate getf(p)
874*7c478bd9Sstevel@tonic-gate char *p;
875*7c478bd9Sstevel@tonic-gate {
876*7c478bd9Sstevel@tonic-gate 	return ((int *) &funtab[2*(*p -0141)]);
877*7c478bd9Sstevel@tonic-gate }
878*7c478bd9Sstevel@tonic-gate 
879*7c478bd9Sstevel@tonic-gate int *
880*7c478bd9Sstevel@tonic-gate geta(p)
881*7c478bd9Sstevel@tonic-gate char *p;
882*7c478bd9Sstevel@tonic-gate {
883*7c478bd9Sstevel@tonic-gate 	return ((int *) &atab[2*(*p - 0141)]);
884*7c478bd9Sstevel@tonic-gate }
885*7c478bd9Sstevel@tonic-gate 
886*7c478bd9Sstevel@tonic-gate main(argc, argv)
887*7c478bd9Sstevel@tonic-gate int argc;
888*7c478bd9Sstevel@tonic-gate char *argv[];
889*7c478bd9Sstevel@tonic-gate {
890*7c478bd9Sstevel@tonic-gate 	int	p[2];
891*7c478bd9Sstevel@tonic-gate 	int	cflag = 0;
892*7c478bd9Sstevel@tonic-gate 	int	lflag = 0;
893*7c478bd9Sstevel@tonic-gate 	int	flag = 0;
894*7c478bd9Sstevel@tonic-gate 	char	**av;
895*7c478bd9Sstevel@tonic-gate 	int 	filecounter = 0;
896*7c478bd9Sstevel@tonic-gate 
897*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
898*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)		/* Should be defined by cc -D */
899*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it weren't */
900*7c478bd9Sstevel@tonic-gate #endif
901*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
902*7c478bd9Sstevel@tonic-gate 
903*7c478bd9Sstevel@tonic-gate 	while ((flag = getopt(argc, argv, "dcl")) != EOF) {
904*7c478bd9Sstevel@tonic-gate 		switch (flag) {
905*7c478bd9Sstevel@tonic-gate 		case 'd':
906*7c478bd9Sstevel@tonic-gate 		case 'c':
907*7c478bd9Sstevel@tonic-gate 			cflag++;
908*7c478bd9Sstevel@tonic-gate 			break;
909*7c478bd9Sstevel@tonic-gate 
910*7c478bd9Sstevel@tonic-gate 		case 'l':
911*7c478bd9Sstevel@tonic-gate 			lflag++;
912*7c478bd9Sstevel@tonic-gate 			break;
913*7c478bd9Sstevel@tonic-gate 
914*7c478bd9Sstevel@tonic-gate 		default:
915*7c478bd9Sstevel@tonic-gate 			fflush(stdout);
916*7c478bd9Sstevel@tonic-gate 			usage();
917*7c478bd9Sstevel@tonic-gate 			break;
918*7c478bd9Sstevel@tonic-gate 		}
919*7c478bd9Sstevel@tonic-gate 	}
920*7c478bd9Sstevel@tonic-gate 
921*7c478bd9Sstevel@tonic-gate 	argc -= optind;
922*7c478bd9Sstevel@tonic-gate 	av = &argv[optind];
923*7c478bd9Sstevel@tonic-gate 
924*7c478bd9Sstevel@tonic-gate 	/*
925*7c478bd9Sstevel@tonic-gate 	* argc is the count of arguments, which should be filenames,
926*7c478bd9Sstevel@tonic-gate 	* remaining in argv. av is a pointer to the first of the
927*7c478bd9Sstevel@tonic-gate 	* remaining arguments.
928*7c478bd9Sstevel@tonic-gate 	*/
929*7c478bd9Sstevel@tonic-gate 
930*7c478bd9Sstevel@tonic-gate 	for (filecounter = 0; filecounter < argc; filecounter++) {
931*7c478bd9Sstevel@tonic-gate 		if ((strlen(av[filecounter])) >= PATH_MAX) {
932*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
933*7c478bd9Sstevel@tonic-gate 			    gettext("File argument too long\n"));
934*7c478bd9Sstevel@tonic-gate 			exit(2);
935*7c478bd9Sstevel@tonic-gate 		}
936*7c478bd9Sstevel@tonic-gate 	}
937*7c478bd9Sstevel@tonic-gate 
938*7c478bd9Sstevel@tonic-gate 	if (lflag) {
939*7c478bd9Sstevel@tonic-gate 		/*
940*7c478bd9Sstevel@tonic-gate 		* if the user wants to include the math library, prepend
941*7c478bd9Sstevel@tonic-gate 		* the math library filename to the argument list by
942*7c478bd9Sstevel@tonic-gate 		* overwriting the last option (there must be at least one
943*7c478bd9Sstevel@tonic-gate 		* supplied option if this is being done).
944*7c478bd9Sstevel@tonic-gate 		*/
945*7c478bd9Sstevel@tonic-gate 		av = &argv[optind-1];
946*7c478bd9Sstevel@tonic-gate 		av[0] = "/usr/lib/lib.b";
947*7c478bd9Sstevel@tonic-gate 		argc++;
948*7c478bd9Sstevel@tonic-gate 	}
949*7c478bd9Sstevel@tonic-gate 
950*7c478bd9Sstevel@tonic-gate 	if (cflag) {
951*7c478bd9Sstevel@tonic-gate 		yyinit(argc, av);
952*7c478bd9Sstevel@tonic-gate 		yyparse();
953*7c478bd9Sstevel@tonic-gate 		exit(0);
954*7c478bd9Sstevel@tonic-gate 	}
955*7c478bd9Sstevel@tonic-gate 
956*7c478bd9Sstevel@tonic-gate 	pipe(p);
957*7c478bd9Sstevel@tonic-gate 	if (fork() == 0) {
958*7c478bd9Sstevel@tonic-gate 		(void) close(1);
959*7c478bd9Sstevel@tonic-gate 		dup(p[1]);
960*7c478bd9Sstevel@tonic-gate 		(void) close(p[0]);
961*7c478bd9Sstevel@tonic-gate 		(void) close(p[1]);
962*7c478bd9Sstevel@tonic-gate 		yyinit(argc, av);
963*7c478bd9Sstevel@tonic-gate 		yyparse();
964*7c478bd9Sstevel@tonic-gate 		exit(0);
965*7c478bd9Sstevel@tonic-gate 	}
966*7c478bd9Sstevel@tonic-gate 	(void) close(0);
967*7c478bd9Sstevel@tonic-gate 	dup(p[0]);
968*7c478bd9Sstevel@tonic-gate 	(void) close(p[0]);
969*7c478bd9Sstevel@tonic-gate 	(void) close(p[1]);
970*7c478bd9Sstevel@tonic-gate #ifdef XPG6
971*7c478bd9Sstevel@tonic-gate 	execl("/usr/xpg6/bin/dc", "dc", "-", 0);
972*7c478bd9Sstevel@tonic-gate #else
973*7c478bd9Sstevel@tonic-gate 	execl("/usr/bin/dc", "dc", "-", 0);
974*7c478bd9Sstevel@tonic-gate #endif
975*7c478bd9Sstevel@tonic-gate }
976*7c478bd9Sstevel@tonic-gate 
977*7c478bd9Sstevel@tonic-gate static void
978*7c478bd9Sstevel@tonic-gate usage(void)
979*7c478bd9Sstevel@tonic-gate {
980*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
981*7c478bd9Sstevel@tonic-gate 	    "usage: bc [ -c ] [ -l ] [ file ... ]\n"));
982*7c478bd9Sstevel@tonic-gate 	exit(2);
983*7c478bd9Sstevel@tonic-gate }
984