xref: /titanic_51/usr/src/cmd/bc/bc.y (revision b390fe2cba75806c96e503c6b93335182cd98efd)
17c478bd9Sstevel@tonic-gate %{
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate  * CDDL HEADER START
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
67c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
77c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
87c478bd9Sstevel@tonic-gate  * with the License.
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
117c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
127c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
137c478bd9Sstevel@tonic-gate  * and limitations under the License.
147c478bd9Sstevel@tonic-gate  *
157c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
167c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
177c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
187c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
197c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
207c478bd9Sstevel@tonic-gate  *
217c478bd9Sstevel@tonic-gate  * CDDL HEADER END
227c478bd9Sstevel@tonic-gate  */
237c478bd9Sstevel@tonic-gate %}
247c478bd9Sstevel@tonic-gate /*
257c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
267c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
29*b390fe2cSmuffin /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
30*b390fe2cSmuffin /*	  All Rights Reserved  	*/
31*b390fe2cSmuffin 
327c478bd9Sstevel@tonic-gate %{
33*b390fe2cSmuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
347c478bd9Sstevel@tonic-gate %}
357c478bd9Sstevel@tonic-gate %{
367c478bd9Sstevel@tonic-gate #include <stdio.h>
377c478bd9Sstevel@tonic-gate #include <stdarg.h>
387c478bd9Sstevel@tonic-gate #include <limits.h>
397c478bd9Sstevel@tonic-gate #include <libintl.h>
407c478bd9Sstevel@tonic-gate #include <locale.h>
417c478bd9Sstevel@tonic-gate #include <signal.h>
427c478bd9Sstevel@tonic-gate 
43*b390fe2cSmuffin static void getout(int)	__NORETURN;
447c478bd9Sstevel@tonic-gate static int *bundle(int, ...);
457c478bd9Sstevel@tonic-gate static void usage(void);
46*b390fe2cSmuffin 
47*b390fe2cSmuffin int	cpeek(char, int, char, int, char);
48*b390fe2cSmuffin void	yyerror(char *);
49*b390fe2cSmuffin 
507c478bd9Sstevel@tonic-gate %}
517c478bd9Sstevel@tonic-gate %union {
527c478bd9Sstevel@tonic-gate 	int *iptr;
537c478bd9Sstevel@tonic-gate 	char *cptr;
547c478bd9Sstevel@tonic-gate 	int cc;
557c478bd9Sstevel@tonic-gate 	}
567c478bd9Sstevel@tonic-gate %start start;
577c478bd9Sstevel@tonic-gate %type <iptr> stat, def, slist, dlets, e
587c478bd9Sstevel@tonic-gate %type <iptr> slist, re, fprefix, cargs, eora, cons, constant, lora
597c478bd9Sstevel@tonic-gate %right '='
607c478bd9Sstevel@tonic-gate %left '+' '-'
617c478bd9Sstevel@tonic-gate %left '*' '/' '%'
627c478bd9Sstevel@tonic-gate %right '^'
637c478bd9Sstevel@tonic-gate %left UMINUS
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate %token <cptr> LETTER
667c478bd9Sstevel@tonic-gate %type <cptr> EQOP, CRS
677c478bd9Sstevel@tonic-gate %token <cc> DIGIT, SQRT, LENGTH, _IF, FFF, EQ
687c478bd9Sstevel@tonic-gate %token <cc> _WHILE _FOR NE LE GE INCR DECR
697c478bd9Sstevel@tonic-gate %token <cc> _RETURN _BREAK _DEFINE BASE OBASE SCALE
707c478bd9Sstevel@tonic-gate %token <cc> EQPL EQMI EQMUL EQDIV EQREM EQEXP
717c478bd9Sstevel@tonic-gate %token <cptr> _AUTO DOT
727c478bd9Sstevel@tonic-gate %token <cc> QSTR
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate %{
757c478bd9Sstevel@tonic-gate #define	STRING_SIZE	(BC_STRING_MAX + 3)	/* string plus quotes */
767c478bd9Sstevel@tonic-gate 						/* plus NULL */
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate FILE	*in;
797c478bd9Sstevel@tonic-gate char	cary[LINE_MAX+1];
807c478bd9Sstevel@tonic-gate char	*cp = { cary };
817c478bd9Sstevel@tonic-gate char	*cpend = &cary[LINE_MAX];	/* last address (not the null char) */
827c478bd9Sstevel@tonic-gate char	string[STRING_SIZE];
837c478bd9Sstevel@tonic-gate char	*str = { string };
847c478bd9Sstevel@tonic-gate int	crs = '0';
857c478bd9Sstevel@tonic-gate int	rcrs = '0';		/* reset crs */
867c478bd9Sstevel@tonic-gate int	bindx = 0;
877c478bd9Sstevel@tonic-gate int	lev = 0;			/* current scope level */
887c478bd9Sstevel@tonic-gate int	ln;				/* line number of current file */
897c478bd9Sstevel@tonic-gate int	*ttp;
907c478bd9Sstevel@tonic-gate char	*ss;				/* current input source */
917c478bd9Sstevel@tonic-gate int	bstack[10] = { 0 };
927c478bd9Sstevel@tonic-gate char	*numb[15] = {
937c478bd9Sstevel@tonic-gate 	" 0", " 1", " 2", " 3", " 4", " 5",
947c478bd9Sstevel@tonic-gate 	" 6", " 7", " 8", " 9", " 10", " 11",
957c478bd9Sstevel@tonic-gate 	" 12", " 13", " 14"
967c478bd9Sstevel@tonic-gate };
977c478bd9Sstevel@tonic-gate int	*pre, *post;
987c478bd9Sstevel@tonic-gate int	interact = 0;			/* talking to a tty? */
997c478bd9Sstevel@tonic-gate %}
1007c478bd9Sstevel@tonic-gate %%
1017c478bd9Sstevel@tonic-gate start	:
1027c478bd9Sstevel@tonic-gate 	| start stat tail
1037c478bd9Sstevel@tonic-gate 		= {
1047c478bd9Sstevel@tonic-gate 			output($2);
1057c478bd9Sstevel@tonic-gate 		}
1067c478bd9Sstevel@tonic-gate 	| start def dargs ')' '{' dlist slist '}'
1077c478bd9Sstevel@tonic-gate 		= {
1087c478bd9Sstevel@tonic-gate 			ttp = bundle(6, pre, $7, post, "0", numb[lev], "Q");
109*b390fe2cSmuffin 			conout(ttp, (char *)$2);
1107c478bd9Sstevel@tonic-gate 			rcrs = crs;
111*b390fe2cSmuffin 			output((int *)"");
1127c478bd9Sstevel@tonic-gate 			lev = bindx = 0;
1137c478bd9Sstevel@tonic-gate 		}
1147c478bd9Sstevel@tonic-gate 	;
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate dlist	: tail
1177c478bd9Sstevel@tonic-gate 	| dlist _AUTO dlets tail
1187c478bd9Sstevel@tonic-gate 	;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate stat	: e
1217c478bd9Sstevel@tonic-gate 		= bundle(2, $1, "ps.");
1227c478bd9Sstevel@tonic-gate 	|
1237c478bd9Sstevel@tonic-gate 		= bundle(1, "");
1247c478bd9Sstevel@tonic-gate 	| QSTR
1257c478bd9Sstevel@tonic-gate 		= bundle(3, "[", $1, "]P");
1267c478bd9Sstevel@tonic-gate 	| LETTER '=' e
1277c478bd9Sstevel@tonic-gate 		= bundle(3, $3, "s", $1);
1287c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' '=' e
1297c478bd9Sstevel@tonic-gate 		= bundle(4, $6, $3, ":", geta($1));
1307c478bd9Sstevel@tonic-gate 	| LETTER EQOP e
1317c478bd9Sstevel@tonic-gate 		= bundle(6, "l", $1, $3, $2, "s", $1);
1327c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' EQOP e
1337c478bd9Sstevel@tonic-gate 		= bundle(8, $3, ";", geta($1), $6, $5, $3, ":", geta($1));
1347c478bd9Sstevel@tonic-gate 	| _BREAK
1357c478bd9Sstevel@tonic-gate 		= bundle(2, numb[lev-bstack[bindx-1]], "Q");
1367c478bd9Sstevel@tonic-gate 	| _RETURN '(' e ')'
1377c478bd9Sstevel@tonic-gate 		= bundle(4, $3, post, numb[lev], "Q");
1387c478bd9Sstevel@tonic-gate 	| _RETURN '(' ')'
1397c478bd9Sstevel@tonic-gate 		= bundle(4, "0", post, numb[lev], "Q");
1407c478bd9Sstevel@tonic-gate 	| _RETURN
1417c478bd9Sstevel@tonic-gate 		= bundle(4, "0", post, numb[lev], "Q");
1427c478bd9Sstevel@tonic-gate 	| SCALE '=' e
1437c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "k");
1447c478bd9Sstevel@tonic-gate 	| SCALE EQOP e
1457c478bd9Sstevel@tonic-gate 		= bundle(4, "K", $3, $2, "k");
1467c478bd9Sstevel@tonic-gate 	| BASE '=' e
1477c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "i");
1487c478bd9Sstevel@tonic-gate 	| BASE EQOP e
1497c478bd9Sstevel@tonic-gate 		= bundle(4, "I", $3, $2, "i");
1507c478bd9Sstevel@tonic-gate 	| OBASE '=' e
1517c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "o");
1527c478bd9Sstevel@tonic-gate 	| OBASE EQOP e
1537c478bd9Sstevel@tonic-gate 		= bundle(4, "O", $3, $2, "o");
1547c478bd9Sstevel@tonic-gate 	| '{' slist '}'
1557c478bd9Sstevel@tonic-gate 		= {
1567c478bd9Sstevel@tonic-gate 			$$ = $2;
1577c478bd9Sstevel@tonic-gate 		}
1587c478bd9Sstevel@tonic-gate 	| FFF
1597c478bd9Sstevel@tonic-gate 		= bundle(1, "fY");
1607c478bd9Sstevel@tonic-gate 	| error
1617c478bd9Sstevel@tonic-gate 		= bundle(1, "c");
1627c478bd9Sstevel@tonic-gate 	| _IF CRS BLEV '(' re ')' stat
1637c478bd9Sstevel@tonic-gate 		= {
1647c478bd9Sstevel@tonic-gate 			conout($7, $2);
1657c478bd9Sstevel@tonic-gate 			bundle(3, $5, $2, " ");
1667c478bd9Sstevel@tonic-gate 		}
1677c478bd9Sstevel@tonic-gate 	| _WHILE CRS '(' re ')' stat BLEV
1687c478bd9Sstevel@tonic-gate 		= {
1697c478bd9Sstevel@tonic-gate 			bundle(3, $6, $4, $2);
1707c478bd9Sstevel@tonic-gate 			conout($$, $2);
1717c478bd9Sstevel@tonic-gate 			bundle(3, $4, $2, " ");
1727c478bd9Sstevel@tonic-gate 		}
1737c478bd9Sstevel@tonic-gate 	| fprefix CRS re ';' e ')' stat BLEV
1747c478bd9Sstevel@tonic-gate 		= {
1757c478bd9Sstevel@tonic-gate 			bundle(5, $7, $5, "s.", $3, $2);
1767c478bd9Sstevel@tonic-gate 			conout($$, $2);
1777c478bd9Sstevel@tonic-gate 			bundle(5, $1, "s.", $3, $2, " ");
1787c478bd9Sstevel@tonic-gate 		}
1797c478bd9Sstevel@tonic-gate 	| '~' LETTER '=' e
1807c478bd9Sstevel@tonic-gate 		= bundle(3, $4, "S", $2);
1817c478bd9Sstevel@tonic-gate 	;
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate EQOP	: EQPL
1847c478bd9Sstevel@tonic-gate 		= {
1857c478bd9Sstevel@tonic-gate 			$$ = "+";
1867c478bd9Sstevel@tonic-gate 		}
1877c478bd9Sstevel@tonic-gate 	| EQMI
1887c478bd9Sstevel@tonic-gate 		= {
1897c478bd9Sstevel@tonic-gate 			$$ = "-";
1907c478bd9Sstevel@tonic-gate 		}
1917c478bd9Sstevel@tonic-gate 	| EQMUL
1927c478bd9Sstevel@tonic-gate 		= {
1937c478bd9Sstevel@tonic-gate 			$$ = "*";
1947c478bd9Sstevel@tonic-gate 		}
1957c478bd9Sstevel@tonic-gate 	| EQDIV
1967c478bd9Sstevel@tonic-gate 		= {
1977c478bd9Sstevel@tonic-gate 			$$ = "/";
1987c478bd9Sstevel@tonic-gate 		}
1997c478bd9Sstevel@tonic-gate 	| EQREM
2007c478bd9Sstevel@tonic-gate 		= {
2017c478bd9Sstevel@tonic-gate 			$$ = "%%";
2027c478bd9Sstevel@tonic-gate 		}
2037c478bd9Sstevel@tonic-gate 	| EQEXP
2047c478bd9Sstevel@tonic-gate 		= {
2057c478bd9Sstevel@tonic-gate 			$$ = "^";
2067c478bd9Sstevel@tonic-gate 		}
2077c478bd9Sstevel@tonic-gate 	;
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate fprefix	: _FOR '(' e ';'
2107c478bd9Sstevel@tonic-gate 		= {
2117c478bd9Sstevel@tonic-gate 			$$ = $3;
2127c478bd9Sstevel@tonic-gate 		}
2137c478bd9Sstevel@tonic-gate 	;
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate BLEV	:
2167c478bd9Sstevel@tonic-gate 		= --bindx;
2177c478bd9Sstevel@tonic-gate 	;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate slist	: stat
2207c478bd9Sstevel@tonic-gate 	| slist tail stat
2217c478bd9Sstevel@tonic-gate 		= bundle(2, $1, $3);
2227c478bd9Sstevel@tonic-gate 	;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate tail	: '\n'
2257c478bd9Sstevel@tonic-gate 		= {
2267c478bd9Sstevel@tonic-gate 			ln++;
2277c478bd9Sstevel@tonic-gate 		}
2287c478bd9Sstevel@tonic-gate 	| ';'
2297c478bd9Sstevel@tonic-gate 	;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate re	: e EQ e
2327c478bd9Sstevel@tonic-gate 		= {
2337c478bd9Sstevel@tonic-gate 			$$ = bundle(3, $1, $3, "=");
2347c478bd9Sstevel@tonic-gate 		}
2357c478bd9Sstevel@tonic-gate 	| e '<' e
2367c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, ">");
2377c478bd9Sstevel@tonic-gate 	| e '>' e
2387c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "<");
2397c478bd9Sstevel@tonic-gate 	| e NE e
2407c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "!=");
2417c478bd9Sstevel@tonic-gate 	| e GE e
2427c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "!>");
2437c478bd9Sstevel@tonic-gate 	| e LE e
2447c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "!<");
2457c478bd9Sstevel@tonic-gate 	| e
2467c478bd9Sstevel@tonic-gate 		= bundle(2, $1, " 0!=");
2477c478bd9Sstevel@tonic-gate 	;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate e	: e '+' e
2507c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "+");
2517c478bd9Sstevel@tonic-gate 	| e '-' e
2527c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "-");
2537c478bd9Sstevel@tonic-gate 	| '-' e		%prec UMINUS
2547c478bd9Sstevel@tonic-gate 		= bundle(3, " 0", $2, "-");
2557c478bd9Sstevel@tonic-gate 	| e '*' e
2567c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "*");
2577c478bd9Sstevel@tonic-gate 	| e '/' e
2587c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "/");
2597c478bd9Sstevel@tonic-gate 	| e '%' e
2607c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "%%");
2617c478bd9Sstevel@tonic-gate 	| e '^' e
2627c478bd9Sstevel@tonic-gate 		= bundle(3, $1, $3, "^");
2637c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']'
2647c478bd9Sstevel@tonic-gate 		= bundle(3, $3, ";", geta($1));
2657c478bd9Sstevel@tonic-gate 	| LETTER INCR
2667c478bd9Sstevel@tonic-gate 		= bundle(4, "l", $1, "d1+s", $1);
2677c478bd9Sstevel@tonic-gate 	| INCR LETTER
2687c478bd9Sstevel@tonic-gate 		= bundle(4, "l", $2, "1+ds", $2);
2697c478bd9Sstevel@tonic-gate 	| DECR LETTER
2707c478bd9Sstevel@tonic-gate 		= bundle(4, "l", $2, "1-ds", $2);
2717c478bd9Sstevel@tonic-gate 	| LETTER DECR
2727c478bd9Sstevel@tonic-gate 		= bundle(4, "l", $1, "d1-s", $1);
2737c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' INCR
2747c478bd9Sstevel@tonic-gate 		= bundle(7, $3, ";", geta($1), "d1+", $3, ":", geta($1));
2757c478bd9Sstevel@tonic-gate 	| INCR LETTER '[' e ']'
2767c478bd9Sstevel@tonic-gate 		= bundle(7, $4, ";", geta($2), "1+d", $4, ":", geta($2));
2777c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' DECR
2787c478bd9Sstevel@tonic-gate 		= bundle(7, $3, ";", geta($1), "d1-", $3, ":", geta($1));
2797c478bd9Sstevel@tonic-gate 	| DECR LETTER '[' e ']'
2807c478bd9Sstevel@tonic-gate 		= bundle(7, $4, ";", geta($2), "1-d", $4, ":", geta($2));
2817c478bd9Sstevel@tonic-gate 	| SCALE INCR
2827c478bd9Sstevel@tonic-gate 		= bundle(1, "Kd1+k");
2837c478bd9Sstevel@tonic-gate 	| INCR SCALE
2847c478bd9Sstevel@tonic-gate 		= bundle(1, "K1+dk");
2857c478bd9Sstevel@tonic-gate 	| SCALE DECR
2867c478bd9Sstevel@tonic-gate 		= bundle(1, "Kd1-k");
2877c478bd9Sstevel@tonic-gate 	| DECR SCALE
2887c478bd9Sstevel@tonic-gate 		= bundle(1, "K1-dk");
2897c478bd9Sstevel@tonic-gate 	| BASE INCR
2907c478bd9Sstevel@tonic-gate 		= bundle(1, "Id1+i");
2917c478bd9Sstevel@tonic-gate 	| INCR BASE
2927c478bd9Sstevel@tonic-gate 		= bundle(1, "I1+di");
2937c478bd9Sstevel@tonic-gate 	| BASE DECR
2947c478bd9Sstevel@tonic-gate 		= bundle(1, "Id1-i");
2957c478bd9Sstevel@tonic-gate 	| DECR BASE
2967c478bd9Sstevel@tonic-gate 		= bundle(1, "I1-di");
2977c478bd9Sstevel@tonic-gate 	| OBASE INCR
2987c478bd9Sstevel@tonic-gate 		= bundle(1, "Od1+o");
2997c478bd9Sstevel@tonic-gate 	| INCR OBASE
3007c478bd9Sstevel@tonic-gate 		= bundle(1, "O1+do");
3017c478bd9Sstevel@tonic-gate 	| OBASE DECR
3027c478bd9Sstevel@tonic-gate 		= bundle(1, "Od1-o");
3037c478bd9Sstevel@tonic-gate 	| DECR OBASE
3047c478bd9Sstevel@tonic-gate 		= bundle(1, "O1-do");
3057c478bd9Sstevel@tonic-gate 	| LETTER '(' cargs ')'
3067c478bd9Sstevel@tonic-gate 		= bundle(4, $3, "l", getf($1), "x");
3077c478bd9Sstevel@tonic-gate 	| LETTER '(' ')'
3087c478bd9Sstevel@tonic-gate 		= bundle(3, "l", getf($1), "x");
3097c478bd9Sstevel@tonic-gate 	| cons
3107c478bd9Sstevel@tonic-gate 		= bundle(2, " ", $1);
3117c478bd9Sstevel@tonic-gate 	| DOT cons
3127c478bd9Sstevel@tonic-gate 		= bundle(2, " .", $2);
3137c478bd9Sstevel@tonic-gate 	| cons DOT cons
3147c478bd9Sstevel@tonic-gate 		= bundle(4, " ", $1, ".", $3);
3157c478bd9Sstevel@tonic-gate 	| cons DOT
3167c478bd9Sstevel@tonic-gate 		= bundle(3, " ", $1, ".");
3177c478bd9Sstevel@tonic-gate 	| DOT
3187c478bd9Sstevel@tonic-gate 		= {
3197c478bd9Sstevel@tonic-gate 			$<cptr>$ = "l.";
3207c478bd9Sstevel@tonic-gate 		}
3217c478bd9Sstevel@tonic-gate 	| LETTER
3227c478bd9Sstevel@tonic-gate 		= bundle(2, "l", $1);
3237c478bd9Sstevel@tonic-gate 	| LETTER '=' e
3247c478bd9Sstevel@tonic-gate 		= bundle(3, $3, "ds", $1);
3257c478bd9Sstevel@tonic-gate 	| LETTER EQOP e		%prec '='
3267c478bd9Sstevel@tonic-gate 		= bundle(6, "l", $1, $3, $2, "ds", $1);
3277c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' '=' e
3287c478bd9Sstevel@tonic-gate 		= bundle(5, $6, "d", $3, ":", geta($1));
3297c478bd9Sstevel@tonic-gate 	| LETTER '[' e ']' EQOP e
3307c478bd9Sstevel@tonic-gate 		= {
3317c478bd9Sstevel@tonic-gate 			bundle(9, $3, ";", geta($1), $6, $5, "d", $3, ":",
3327c478bd9Sstevel@tonic-gate 			    geta($1));
3337c478bd9Sstevel@tonic-gate 		}
3347c478bd9Sstevel@tonic-gate 	| LENGTH '(' e ')'
3357c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "Z");
3367c478bd9Sstevel@tonic-gate 	| SCALE '(' e ')'
3377c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "X");	/* must be before '(' e ')' */
3387c478bd9Sstevel@tonic-gate 	| '(' e ')'
3397c478bd9Sstevel@tonic-gate 		= {
3407c478bd9Sstevel@tonic-gate 			$$ = $2;
3417c478bd9Sstevel@tonic-gate 		}
3427c478bd9Sstevel@tonic-gate 	| '?'
3437c478bd9Sstevel@tonic-gate 		= bundle(1, "?");
3447c478bd9Sstevel@tonic-gate 	| SQRT '(' e ')'
3457c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "v");
3467c478bd9Sstevel@tonic-gate 	| '~' LETTER
3477c478bd9Sstevel@tonic-gate 		= bundle(2, "L", $2);
3487c478bd9Sstevel@tonic-gate 	| SCALE '=' e
3497c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "dk");
3507c478bd9Sstevel@tonic-gate 	| SCALE EQOP e		%prec '='
3517c478bd9Sstevel@tonic-gate 		= bundle(4, "K", $3, $2, "dk");
3527c478bd9Sstevel@tonic-gate 	| BASE '=' e
3537c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "di");
3547c478bd9Sstevel@tonic-gate 	| BASE EQOP e		%prec '='
3557c478bd9Sstevel@tonic-gate 		= bundle(4, "I", $3, $2, "di");
3567c478bd9Sstevel@tonic-gate 	| OBASE '=' e
3577c478bd9Sstevel@tonic-gate 		= bundle(2, $3, "do");
3587c478bd9Sstevel@tonic-gate 	| OBASE EQOP e		%prec '='
3597c478bd9Sstevel@tonic-gate 		= bundle(4, "O", $3, $2, "do");
3607c478bd9Sstevel@tonic-gate 	| SCALE
3617c478bd9Sstevel@tonic-gate 		= bundle(1, "K");
3627c478bd9Sstevel@tonic-gate 	| BASE
3637c478bd9Sstevel@tonic-gate 		= bundle(1, "I");
3647c478bd9Sstevel@tonic-gate 	| OBASE
3657c478bd9Sstevel@tonic-gate 		= bundle(1, "O");
3667c478bd9Sstevel@tonic-gate 	;
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate cargs	: eora
3697c478bd9Sstevel@tonic-gate 	| cargs ',' eora
3707c478bd9Sstevel@tonic-gate 		= bundle(2, $1, $3);
3717c478bd9Sstevel@tonic-gate 	;
3727c478bd9Sstevel@tonic-gate eora	: e
3737c478bd9Sstevel@tonic-gate 	| LETTER '[' ']'
3747c478bd9Sstevel@tonic-gate 		= bundle(2, "l", geta($1));
3757c478bd9Sstevel@tonic-gate 	;
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate cons	: constant
3787c478bd9Sstevel@tonic-gate 		= {
3797c478bd9Sstevel@tonic-gate 			*cp++ = '\0';
3807c478bd9Sstevel@tonic-gate 		}
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate constant: '_'
3837c478bd9Sstevel@tonic-gate 		= {
3847c478bd9Sstevel@tonic-gate 			checkbuffer();
3857c478bd9Sstevel@tonic-gate 			$<cptr>$ = cp;
3867c478bd9Sstevel@tonic-gate 			*cp++ = '_';
3877c478bd9Sstevel@tonic-gate 		}
3887c478bd9Sstevel@tonic-gate 	| DIGIT
3897c478bd9Sstevel@tonic-gate 		= {
3907c478bd9Sstevel@tonic-gate 			checkbuffer();
3917c478bd9Sstevel@tonic-gate 			$<cptr>$ = cp;
3927c478bd9Sstevel@tonic-gate 			*cp++ = $1;
3937c478bd9Sstevel@tonic-gate 		}
3947c478bd9Sstevel@tonic-gate 	| constant DIGIT
3957c478bd9Sstevel@tonic-gate 		= {
3967c478bd9Sstevel@tonic-gate 			checkbuffer();
3977c478bd9Sstevel@tonic-gate 			*cp++ = $2;
3987c478bd9Sstevel@tonic-gate 		}
3997c478bd9Sstevel@tonic-gate 	;
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate CRS	:
4027c478bd9Sstevel@tonic-gate 		= {
4037c478bd9Sstevel@tonic-gate 			checkbuffer();
4047c478bd9Sstevel@tonic-gate 			$$ = cp;
4057c478bd9Sstevel@tonic-gate 			*cp++ = crs++;
4067c478bd9Sstevel@tonic-gate 			*cp++ = '\0';
4077c478bd9Sstevel@tonic-gate 			if (crs == '[')
4087c478bd9Sstevel@tonic-gate 				crs += 3;
4097c478bd9Sstevel@tonic-gate 			if (crs == 'a')
4107c478bd9Sstevel@tonic-gate 				crs = '{';
4117c478bd9Sstevel@tonic-gate 			if (crs >= 0241) {
4127c478bd9Sstevel@tonic-gate 				yyerror("program too big");
4137c478bd9Sstevel@tonic-gate 				getout(1);
4147c478bd9Sstevel@tonic-gate 			}
4157c478bd9Sstevel@tonic-gate 			bstack[bindx++] = lev++;
4167c478bd9Sstevel@tonic-gate 		}
4177c478bd9Sstevel@tonic-gate 	;
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate def	: _DEFINE LETTER '('
4207c478bd9Sstevel@tonic-gate 		= {
4217c478bd9Sstevel@tonic-gate 			$$ = getf($2);
4227c478bd9Sstevel@tonic-gate 			pre = (int *)"";
4237c478bd9Sstevel@tonic-gate 			post = (int *)"";
4247c478bd9Sstevel@tonic-gate 			lev = 1;
4257c478bd9Sstevel@tonic-gate 			bstack[bindx = 0] = 0;
4267c478bd9Sstevel@tonic-gate 		}
4277c478bd9Sstevel@tonic-gate 	;
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate dargs	:		/* empty */
4307c478bd9Sstevel@tonic-gate 	| lora
4317c478bd9Sstevel@tonic-gate 		= {
4327c478bd9Sstevel@tonic-gate 			pp($1);
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 	| dargs ',' lora
4357c478bd9Sstevel@tonic-gate 		= {
4367c478bd9Sstevel@tonic-gate 			pp($3);
4377c478bd9Sstevel@tonic-gate 		}
4387c478bd9Sstevel@tonic-gate 	;
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate dlets	: lora
4417c478bd9Sstevel@tonic-gate 		= tp($1);
4427c478bd9Sstevel@tonic-gate 	| dlets ',' lora
4437c478bd9Sstevel@tonic-gate 		= tp($3);
4447c478bd9Sstevel@tonic-gate 	;
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate lora	: LETTER
4477c478bd9Sstevel@tonic-gate 		= {
4487c478bd9Sstevel@tonic-gate 			$<cptr>$ = $1;
4497c478bd9Sstevel@tonic-gate 		}
4507c478bd9Sstevel@tonic-gate 	| LETTER '[' ']'
4517c478bd9Sstevel@tonic-gate 		= {
4527c478bd9Sstevel@tonic-gate 			$$ = geta($1);
4537c478bd9Sstevel@tonic-gate 		}
4547c478bd9Sstevel@tonic-gate 	;
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate %%
4577c478bd9Sstevel@tonic-gate #define	error	256
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate int	peekc = -1;
4607c478bd9Sstevel@tonic-gate int	ifile;			/* current index into sargv */
4617c478bd9Sstevel@tonic-gate int	sargc;			/* size of sargv[] */
4627c478bd9Sstevel@tonic-gate char	**sargv;		/* saved arg list without options */
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate char funtab[52] = {
4657c478bd9Sstevel@tonic-gate 	01, 0, 02, 0, 03, 0, 04, 0, 05, 0, 06, 0, 07, 0,
4667c478bd9Sstevel@tonic-gate 	010, 0, 011, 0, 012, 0, 013, 0, 014, 0, 015, 0, 016, 0, 017, 0,
4677c478bd9Sstevel@tonic-gate 	020, 0, 021, 0, 022, 0, 023, 0, 024, 0, 025, 0, 026, 0, 027, 0,
4687c478bd9Sstevel@tonic-gate 	030, 0, 031, 0, 032, 0
4697c478bd9Sstevel@tonic-gate };
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate unsigned char atab[52] = {
4727c478bd9Sstevel@tonic-gate 	0241, 0, 0242, 0, 0243, 0, 0244, 0, 0245, 0, 0246, 0, 0247, 0, 0250, 0,
4737c478bd9Sstevel@tonic-gate 	0251, 0, 0252, 0, 0253, 0, 0254, 0, 0255, 0, 0256, 0, 0257, 0, 0260, 0,
4747c478bd9Sstevel@tonic-gate 	0261, 0, 0262, 0, 0263, 0, 0264, 0, 0265, 0, 0266, 0, 0267, 0, 0270, 0,
4757c478bd9Sstevel@tonic-gate 	0271, 0, 0272, 0
4767c478bd9Sstevel@tonic-gate };
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate char *letr[26] = {
4797c478bd9Sstevel@tonic-gate 	"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
4807c478bd9Sstevel@tonic-gate 	"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
4817c478bd9Sstevel@tonic-gate 	"u", "v", "w", "x", "y", "z"
4827c478bd9Sstevel@tonic-gate };
4837c478bd9Sstevel@tonic-gate 
484*b390fe2cSmuffin int
485*b390fe2cSmuffin yylex(void)
4867c478bd9Sstevel@tonic-gate {
4877c478bd9Sstevel@tonic-gate 	int c, ch;
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate restart:
4907c478bd9Sstevel@tonic-gate 	c = getch();
4917c478bd9Sstevel@tonic-gate 	peekc = -1;
4927c478bd9Sstevel@tonic-gate 	while (c == ' ' || c == '\t')
4937c478bd9Sstevel@tonic-gate 		c = getch();
4947c478bd9Sstevel@tonic-gate 	if (c == '\\') {
4957c478bd9Sstevel@tonic-gate 		(void) getch();
4967c478bd9Sstevel@tonic-gate 		goto restart;
4977c478bd9Sstevel@tonic-gate 	}
4987c478bd9Sstevel@tonic-gate 	if (c <= 'z' && c >= 'a') {
4997c478bd9Sstevel@tonic-gate 		/* look ahead to look for reserved words */
5007c478bd9Sstevel@tonic-gate 		peekc = getch();
5017c478bd9Sstevel@tonic-gate 		if (peekc >= 'a' && peekc <= 'z') {
5027c478bd9Sstevel@tonic-gate 			/* must be reserved word */
5037c478bd9Sstevel@tonic-gate 			if (c == 'i' && peekc == 'f') {
5047c478bd9Sstevel@tonic-gate 				c = _IF;
5057c478bd9Sstevel@tonic-gate 				goto skip;
5067c478bd9Sstevel@tonic-gate 			}
5077c478bd9Sstevel@tonic-gate 			if (c == 'w' && peekc == 'h') {
5087c478bd9Sstevel@tonic-gate 				c = _WHILE;
5097c478bd9Sstevel@tonic-gate 				goto skip;
5107c478bd9Sstevel@tonic-gate 			}
5117c478bd9Sstevel@tonic-gate 			if (c == 'f' && peekc == 'o') {
5127c478bd9Sstevel@tonic-gate 				c = _FOR;
5137c478bd9Sstevel@tonic-gate 				goto skip;
5147c478bd9Sstevel@tonic-gate 			}
5157c478bd9Sstevel@tonic-gate 			if (c == 's' && peekc == 'q') {
5167c478bd9Sstevel@tonic-gate 				c = SQRT;
5177c478bd9Sstevel@tonic-gate 				goto skip;
5187c478bd9Sstevel@tonic-gate 			}
5197c478bd9Sstevel@tonic-gate 			if (c == 'r' && peekc == 'e') {
5207c478bd9Sstevel@tonic-gate 				c = _RETURN;
5217c478bd9Sstevel@tonic-gate 				goto skip;
5227c478bd9Sstevel@tonic-gate 			}
5237c478bd9Sstevel@tonic-gate 			if (c == 'b' && peekc == 'r') {
5247c478bd9Sstevel@tonic-gate 				c = _BREAK;
5257c478bd9Sstevel@tonic-gate 				goto skip;
5267c478bd9Sstevel@tonic-gate 			}
5277c478bd9Sstevel@tonic-gate 			if (c == 'd' && peekc == 'e') {
5287c478bd9Sstevel@tonic-gate 				c = _DEFINE;
5297c478bd9Sstevel@tonic-gate 				goto skip;
5307c478bd9Sstevel@tonic-gate 			}
5317c478bd9Sstevel@tonic-gate 			if (c == 's' && peekc == 'c') {
5327c478bd9Sstevel@tonic-gate 				c = SCALE;
5337c478bd9Sstevel@tonic-gate 				goto skip;
5347c478bd9Sstevel@tonic-gate 			}
5357c478bd9Sstevel@tonic-gate 			if (c == 'b' && peekc == 'a') {
5367c478bd9Sstevel@tonic-gate 				c = BASE;
5377c478bd9Sstevel@tonic-gate 				goto skip;
5387c478bd9Sstevel@tonic-gate 			}
5397c478bd9Sstevel@tonic-gate 			if (c == 'i' && peekc == 'b') {
5407c478bd9Sstevel@tonic-gate 				c = BASE;
5417c478bd9Sstevel@tonic-gate 				goto skip;
5427c478bd9Sstevel@tonic-gate 			}
5437c478bd9Sstevel@tonic-gate 			if (c == 'o' && peekc == 'b') {
5447c478bd9Sstevel@tonic-gate 				c = OBASE;
5457c478bd9Sstevel@tonic-gate 				goto skip;
5467c478bd9Sstevel@tonic-gate 			}
5477c478bd9Sstevel@tonic-gate 			if (c == 'd' && peekc == 'i') {
5487c478bd9Sstevel@tonic-gate 				c = FFF;
5497c478bd9Sstevel@tonic-gate 				goto skip;
5507c478bd9Sstevel@tonic-gate 			}
5517c478bd9Sstevel@tonic-gate 			if (c == 'a' && peekc == 'u') {
5527c478bd9Sstevel@tonic-gate 				c = _AUTO;
5537c478bd9Sstevel@tonic-gate 				goto skip;
5547c478bd9Sstevel@tonic-gate 			}
5557c478bd9Sstevel@tonic-gate 			if (c == 'l' && peekc == 'e') {
5567c478bd9Sstevel@tonic-gate 				c = LENGTH;
5577c478bd9Sstevel@tonic-gate 				goto skip;
5587c478bd9Sstevel@tonic-gate 			}
5597c478bd9Sstevel@tonic-gate 			if (c == 'q' && peekc == 'u') {
5607c478bd9Sstevel@tonic-gate 				getout(0);
5617c478bd9Sstevel@tonic-gate 			}
5627c478bd9Sstevel@tonic-gate 			/* could not be found */
5637c478bd9Sstevel@tonic-gate 			return (error);
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate skip:	/* skip over rest of word */
5667c478bd9Sstevel@tonic-gate 			peekc = -1;
5677c478bd9Sstevel@tonic-gate 			while ((ch = getch()) >= 'a' && ch <= 'z')
5687c478bd9Sstevel@tonic-gate 				;
5697c478bd9Sstevel@tonic-gate 			peekc = ch;
5707c478bd9Sstevel@tonic-gate 			return (c);
5717c478bd9Sstevel@tonic-gate 		}
5727c478bd9Sstevel@tonic-gate 
5737c478bd9Sstevel@tonic-gate 		/* usual case; just one single letter */
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 		yylval.cptr = letr[c-'a'];
5767c478bd9Sstevel@tonic-gate 		return (LETTER);
5777c478bd9Sstevel@tonic-gate 	}
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 	if (c >= '0' && c <= '9' || c >= 'A' && c <= 'F') {
5807c478bd9Sstevel@tonic-gate 		yylval.cc = c;
5817c478bd9Sstevel@tonic-gate 		return (DIGIT);
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate 	switch (c) {
5857c478bd9Sstevel@tonic-gate 	case '.':
5867c478bd9Sstevel@tonic-gate 		return (DOT);
5877c478bd9Sstevel@tonic-gate 
5887c478bd9Sstevel@tonic-gate 	case '=':
5897c478bd9Sstevel@tonic-gate 		switch ((peekc = getch())) {
5907c478bd9Sstevel@tonic-gate 		case '=':
5917c478bd9Sstevel@tonic-gate 			c = EQ;
5927c478bd9Sstevel@tonic-gate 			goto gotit;
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate 		case '+':
5957c478bd9Sstevel@tonic-gate 			c = EQPL;
5967c478bd9Sstevel@tonic-gate 			goto gotit;
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate 		case '-':
5997c478bd9Sstevel@tonic-gate 			c = EQMI;
6007c478bd9Sstevel@tonic-gate 			goto gotit;
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 		case '*':
6037c478bd9Sstevel@tonic-gate 			c = EQMUL;
6047c478bd9Sstevel@tonic-gate 			goto gotit;
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 		case '/':
6077c478bd9Sstevel@tonic-gate 			c = EQDIV;
6087c478bd9Sstevel@tonic-gate 			goto gotit;
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate 		case '%':
6117c478bd9Sstevel@tonic-gate 			c = EQREM;
6127c478bd9Sstevel@tonic-gate 			goto gotit;
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate 		case '^':
6157c478bd9Sstevel@tonic-gate 			c = EQEXP;
6167c478bd9Sstevel@tonic-gate 			goto gotit;
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 		default:
6197c478bd9Sstevel@tonic-gate 			return ('=');
6207c478bd9Sstevel@tonic-gate gotit:
6217c478bd9Sstevel@tonic-gate 			peekc = -1;
6227c478bd9Sstevel@tonic-gate 			return (c);
6237c478bd9Sstevel@tonic-gate 		}
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate 	case '+':
6267c478bd9Sstevel@tonic-gate 		return (cpeek('+', INCR, '=', EQPL, '+'));
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 	case '-':
6297c478bd9Sstevel@tonic-gate 		return (cpeek('-', DECR, '=', EQMI, '-'));
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	case '*':
6327c478bd9Sstevel@tonic-gate 		return (cpeek('=', EQMUL, '\0', 0, '*'));
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 	case '%':
6357c478bd9Sstevel@tonic-gate 		return (cpeek('=', EQREM, '\0', 0, '%'));
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate 	case '^':
6387c478bd9Sstevel@tonic-gate 		return (cpeek('=', EQEXP, '\0', 0, '^'));
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 	case '<':
6417c478bd9Sstevel@tonic-gate 		return (cpeek('=', LE, '\0', 0, '<'));
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate 	case '>':
6447c478bd9Sstevel@tonic-gate 		return (cpeek('=', GE, '\0', 0, '>'));
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	case '!':
6477c478bd9Sstevel@tonic-gate 		return (cpeek('=', NE, '\0', 0, '!'));
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 	case '/':
6507c478bd9Sstevel@tonic-gate 		if ((peekc = getch()) == '=') {
6517c478bd9Sstevel@tonic-gate 			peekc = -1;
6527c478bd9Sstevel@tonic-gate 			return (EQDIV);
6537c478bd9Sstevel@tonic-gate 		}
6547c478bd9Sstevel@tonic-gate 		if (peekc == '*') {
6557c478bd9Sstevel@tonic-gate 			peekc = -1;
6567c478bd9Sstevel@tonic-gate 			while ((getch() != '*') || ((peekc = getch()) != '/'))
6577c478bd9Sstevel@tonic-gate 				;
6587c478bd9Sstevel@tonic-gate 			peekc = -1;
6597c478bd9Sstevel@tonic-gate 			goto restart;
6607c478bd9Sstevel@tonic-gate 		}
6617c478bd9Sstevel@tonic-gate 		else
6627c478bd9Sstevel@tonic-gate 			return (c);
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate 	case '"':
6657c478bd9Sstevel@tonic-gate 		yylval.cptr = str;
6667c478bd9Sstevel@tonic-gate 		while ((c = getch()) != '"') {
6677c478bd9Sstevel@tonic-gate 			*str++ = c;
6687c478bd9Sstevel@tonic-gate 			if (str >= &string[STRING_SIZE-1]) {
6697c478bd9Sstevel@tonic-gate 				yyerror("string space exceeded");
6707c478bd9Sstevel@tonic-gate 				getout(1);
6717c478bd9Sstevel@tonic-gate 			}
6727c478bd9Sstevel@tonic-gate 		}
6737c478bd9Sstevel@tonic-gate 		*str++ = '\0';
6747c478bd9Sstevel@tonic-gate 		return (QSTR);
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate 	default:
6777c478bd9Sstevel@tonic-gate 		return (c);
6787c478bd9Sstevel@tonic-gate 	}
6797c478bd9Sstevel@tonic-gate }
6807c478bd9Sstevel@tonic-gate 
681*b390fe2cSmuffin int
682*b390fe2cSmuffin cpeek(char c1, int yes1, char c2, int yes2, char none)
6837c478bd9Sstevel@tonic-gate {
6847c478bd9Sstevel@tonic-gate 	int r;
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	peekc = getch();
6877c478bd9Sstevel@tonic-gate 	if (peekc == c1)
6887c478bd9Sstevel@tonic-gate 		r = yes1;
6897c478bd9Sstevel@tonic-gate 	else if (peekc == c2)
6907c478bd9Sstevel@tonic-gate 		r = yes2;
6917c478bd9Sstevel@tonic-gate 	else
6927c478bd9Sstevel@tonic-gate 		return (none);
6937c478bd9Sstevel@tonic-gate 	peekc = -1;
6947c478bd9Sstevel@tonic-gate 	return (r);
6957c478bd9Sstevel@tonic-gate }
6967c478bd9Sstevel@tonic-gate 
697*b390fe2cSmuffin 
698*b390fe2cSmuffin int
699*b390fe2cSmuffin getch(void)
7007c478bd9Sstevel@tonic-gate {
7017c478bd9Sstevel@tonic-gate 	int ch;
7027c478bd9Sstevel@tonic-gate 	char mbuf[LINE_MAX];
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate loop:
7057c478bd9Sstevel@tonic-gate 	ch = (peekc < 0) ? getc(in) : peekc;
7067c478bd9Sstevel@tonic-gate 	peekc = -1;
7077c478bd9Sstevel@tonic-gate 	if (ch != EOF)
7087c478bd9Sstevel@tonic-gate 		return (ch);
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate 	if (++ifile >= sargc) {
7117c478bd9Sstevel@tonic-gate 		if (ifile >= sargc+1)
7127c478bd9Sstevel@tonic-gate 			getout(0);
7137c478bd9Sstevel@tonic-gate 		in = stdin;
7147c478bd9Sstevel@tonic-gate 		ln = 0;
7157c478bd9Sstevel@tonic-gate 		goto loop;
7167c478bd9Sstevel@tonic-gate 	}
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate 	(void) fclose(in);
7197c478bd9Sstevel@tonic-gate 	if ((in = fopen(sargv[ifile], "r")) != NULL) {
7207c478bd9Sstevel@tonic-gate 		ln = 0;
7217c478bd9Sstevel@tonic-gate 		ss = sargv[ifile];
7227c478bd9Sstevel@tonic-gate 		goto loop;
7237c478bd9Sstevel@tonic-gate 	}
7247c478bd9Sstevel@tonic-gate 	(void) snprintf(mbuf, sizeof (mbuf), "can't open input file %s",
7257c478bd9Sstevel@tonic-gate 		sargv[ifile]);
7267c478bd9Sstevel@tonic-gate 	ln = -1;
7277c478bd9Sstevel@tonic-gate 	ss = "command line";
7287c478bd9Sstevel@tonic-gate 	yyerror(mbuf);
7297c478bd9Sstevel@tonic-gate 	getout(1);
7307c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
7317c478bd9Sstevel@tonic-gate }
7327c478bd9Sstevel@tonic-gate 
7337c478bd9Sstevel@tonic-gate #define	b_sp_max	5000
7347c478bd9Sstevel@tonic-gate int b_space[b_sp_max];
7357c478bd9Sstevel@tonic-gate int *b_sp_nxt = { b_space };
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate int	bdebug = 0;
7387c478bd9Sstevel@tonic-gate 
7397c478bd9Sstevel@tonic-gate static int *
7407c478bd9Sstevel@tonic-gate bundle(int i, ...)
7417c478bd9Sstevel@tonic-gate {
7427c478bd9Sstevel@tonic-gate 	va_list ap;
7437c478bd9Sstevel@tonic-gate 	int *q;
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 	va_start(ap, i);
7467c478bd9Sstevel@tonic-gate 	q = b_sp_nxt;
7477c478bd9Sstevel@tonic-gate 	if (bdebug)
7487c478bd9Sstevel@tonic-gate 		printf("bundle %d elements at %o\n", i, q);
7497c478bd9Sstevel@tonic-gate 	while (i-- > 0) {
7507c478bd9Sstevel@tonic-gate 		if (b_sp_nxt >= & b_space[b_sp_max])
7517c478bd9Sstevel@tonic-gate 			yyerror("bundling space exceeded");
7527c478bd9Sstevel@tonic-gate 		*b_sp_nxt++ = va_arg(ap, int);
7537c478bd9Sstevel@tonic-gate 	}
7547c478bd9Sstevel@tonic-gate 	* b_sp_nxt++ = 0;
7557c478bd9Sstevel@tonic-gate 	yyval.iptr = q;
7567c478bd9Sstevel@tonic-gate 	va_end(ap);
7577c478bd9Sstevel@tonic-gate 	return (q);
7587c478bd9Sstevel@tonic-gate }
7597c478bd9Sstevel@tonic-gate 
760*b390fe2cSmuffin void
761*b390fe2cSmuffin routput(int *p)
7627c478bd9Sstevel@tonic-gate {
7637c478bd9Sstevel@tonic-gate 	if (bdebug) printf("routput(%o)\n", p);
7647c478bd9Sstevel@tonic-gate 	if (p >= &b_space[0] && p < &b_space[b_sp_max]) {
7657c478bd9Sstevel@tonic-gate 		/* part of a bundle */
7667c478bd9Sstevel@tonic-gate 		while (*p != 0)
767*b390fe2cSmuffin 			routput((int *)*p++);
7687c478bd9Sstevel@tonic-gate 	}
7697c478bd9Sstevel@tonic-gate 	else
7707c478bd9Sstevel@tonic-gate 		printf((char *)p);	 /* character string */
7717c478bd9Sstevel@tonic-gate }
7727c478bd9Sstevel@tonic-gate 
773*b390fe2cSmuffin void
774*b390fe2cSmuffin output(int *p)
7757c478bd9Sstevel@tonic-gate {
7767c478bd9Sstevel@tonic-gate 	routput(p);
7777c478bd9Sstevel@tonic-gate 	b_sp_nxt = & b_space[0];
7787c478bd9Sstevel@tonic-gate 	printf("\n");
7797c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
7807c478bd9Sstevel@tonic-gate 	cp = cary;
7817c478bd9Sstevel@tonic-gate 	crs = rcrs;
7827c478bd9Sstevel@tonic-gate }
7837c478bd9Sstevel@tonic-gate 
784*b390fe2cSmuffin void
785*b390fe2cSmuffin conout(int *p, char *s)
7867c478bd9Sstevel@tonic-gate {
7877c478bd9Sstevel@tonic-gate 	printf("[");
7887c478bd9Sstevel@tonic-gate 	routput(p);
7897c478bd9Sstevel@tonic-gate 	printf("]s%s\n", s);
7907c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
7917c478bd9Sstevel@tonic-gate 	lev--;
7927c478bd9Sstevel@tonic-gate }
7937c478bd9Sstevel@tonic-gate 
794*b390fe2cSmuffin void
795*b390fe2cSmuffin yyerror(char *s)
7967c478bd9Sstevel@tonic-gate {
7977c478bd9Sstevel@tonic-gate 	if (ifile >= sargc)
7987c478bd9Sstevel@tonic-gate 		ss = "teletype";
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 	if (ss == 0 || *ss == 0)
8017c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("%s on line %d\n"), s, ln+1);
8027c478bd9Sstevel@tonic-gate 	else
8037c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("%s on line %d, %s\n"),
8047c478bd9Sstevel@tonic-gate 		    s, ln+1, ss);
8057c478bd9Sstevel@tonic-gate 	(void) fflush(stderr);
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	cp = cary;
8087c478bd9Sstevel@tonic-gate 	crs = rcrs;
8097c478bd9Sstevel@tonic-gate 	bindx = 0;
8107c478bd9Sstevel@tonic-gate 	lev = 0;
8117c478bd9Sstevel@tonic-gate 	b_sp_nxt = &b_space[0];
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate 
814*b390fe2cSmuffin void
815*b390fe2cSmuffin checkbuffer(void)
8167c478bd9Sstevel@tonic-gate {
8177c478bd9Sstevel@tonic-gate 	/* Do not exceed the last char in input line buffer */
8187c478bd9Sstevel@tonic-gate 	if (cp >= cpend) {
8197c478bd9Sstevel@tonic-gate 		yyerror("line too long\n");
8207c478bd9Sstevel@tonic-gate 		getout(1);
8217c478bd9Sstevel@tonic-gate 	}
8227c478bd9Sstevel@tonic-gate }
8237c478bd9Sstevel@tonic-gate 
824*b390fe2cSmuffin void
825*b390fe2cSmuffin pp(int *s)
8267c478bd9Sstevel@tonic-gate {
8277c478bd9Sstevel@tonic-gate 	/* puts the relevant stuff on pre and post for the letter s */
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate 	(void) bundle(3, "S", s, pre);
8307c478bd9Sstevel@tonic-gate 	pre = yyval.iptr;
8317c478bd9Sstevel@tonic-gate 	(void) bundle(4, post, "L", s, "s.");
8327c478bd9Sstevel@tonic-gate 	post = yyval.iptr;
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate 
835*b390fe2cSmuffin void
836*b390fe2cSmuffin tp(int *s)
8377c478bd9Sstevel@tonic-gate {		/* same as pp, but for temps */
8387c478bd9Sstevel@tonic-gate 	bundle(3, "0S", s, pre);
8397c478bd9Sstevel@tonic-gate 	pre = yyval.iptr;
8407c478bd9Sstevel@tonic-gate 	bundle(4, post, "L", s, "s.");
8417c478bd9Sstevel@tonic-gate 	post = yyval.iptr;
8427c478bd9Sstevel@tonic-gate }
8437c478bd9Sstevel@tonic-gate 
844*b390fe2cSmuffin void
845*b390fe2cSmuffin yyinit(int argc, char **argv)
8467c478bd9Sstevel@tonic-gate {
8477c478bd9Sstevel@tonic-gate 	char	mbuf[LINE_MAX];
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, SIG_IGN);		/* ignore all interrupts */
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate 	sargv = argv;
8527c478bd9Sstevel@tonic-gate 	sargc = argc;
8537c478bd9Sstevel@tonic-gate 	if (sargc == 0)
8547c478bd9Sstevel@tonic-gate 		in = stdin;
8557c478bd9Sstevel@tonic-gate 	else if ((in = fopen(sargv[0], "r")) == NULL) {
8567c478bd9Sstevel@tonic-gate 		(void) snprintf(mbuf, sizeof (mbuf), "can't open input file %s",
8577c478bd9Sstevel@tonic-gate 			sargv[0]);
8587c478bd9Sstevel@tonic-gate 		ln = -1;
8597c478bd9Sstevel@tonic-gate 		ss = "command line";
8607c478bd9Sstevel@tonic-gate 		yyerror(mbuf);
8617c478bd9Sstevel@tonic-gate 		getout(1);
8627c478bd9Sstevel@tonic-gate 	}
8637c478bd9Sstevel@tonic-gate 	ifile = 0;
8647c478bd9Sstevel@tonic-gate 	ln = 0;
8657c478bd9Sstevel@tonic-gate 	ss = sargv[0];
8667c478bd9Sstevel@tonic-gate }
8677c478bd9Sstevel@tonic-gate 
868*b390fe2cSmuffin static void
869*b390fe2cSmuffin getout(int code)
8707c478bd9Sstevel@tonic-gate {
8717c478bd9Sstevel@tonic-gate 	printf("q");
8727c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
8737c478bd9Sstevel@tonic-gate 	exit(code);
8747c478bd9Sstevel@tonic-gate }
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate int *
877*b390fe2cSmuffin getf(char *p)
8787c478bd9Sstevel@tonic-gate {
8797c478bd9Sstevel@tonic-gate 	return ((int *) &funtab[2*(*p -0141)]);
8807c478bd9Sstevel@tonic-gate }
8817c478bd9Sstevel@tonic-gate 
8827c478bd9Sstevel@tonic-gate int *
883*b390fe2cSmuffin geta(char *p)
8847c478bd9Sstevel@tonic-gate {
8857c478bd9Sstevel@tonic-gate 	return ((int *) &atab[2*(*p - 0141)]);
8867c478bd9Sstevel@tonic-gate }
8877c478bd9Sstevel@tonic-gate 
888*b390fe2cSmuffin int
889*b390fe2cSmuffin main(int argc, char **argv)
8907c478bd9Sstevel@tonic-gate {
8917c478bd9Sstevel@tonic-gate 	int	p[2];
8927c478bd9Sstevel@tonic-gate 	int	cflag = 0;
8937c478bd9Sstevel@tonic-gate 	int	lflag = 0;
8947c478bd9Sstevel@tonic-gate 	int	flag = 0;
8957c478bd9Sstevel@tonic-gate 	char	**av;
8967c478bd9Sstevel@tonic-gate 	int 	filecounter = 0;
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
8997c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)		/* Should be defined by cc -D */
9007c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it weren't */
9017c478bd9Sstevel@tonic-gate #endif
9027c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate 	while ((flag = getopt(argc, argv, "dcl")) != EOF) {
9057c478bd9Sstevel@tonic-gate 		switch (flag) {
9067c478bd9Sstevel@tonic-gate 		case 'd':
9077c478bd9Sstevel@tonic-gate 		case 'c':
9087c478bd9Sstevel@tonic-gate 			cflag++;
9097c478bd9Sstevel@tonic-gate 			break;
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 		case 'l':
9127c478bd9Sstevel@tonic-gate 			lflag++;
9137c478bd9Sstevel@tonic-gate 			break;
9147c478bd9Sstevel@tonic-gate 
9157c478bd9Sstevel@tonic-gate 		default:
9167c478bd9Sstevel@tonic-gate 			fflush(stdout);
9177c478bd9Sstevel@tonic-gate 			usage();
9187c478bd9Sstevel@tonic-gate 			break;
9197c478bd9Sstevel@tonic-gate 		}
9207c478bd9Sstevel@tonic-gate 	}
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 	argc -= optind;
9237c478bd9Sstevel@tonic-gate 	av = &argv[optind];
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate 	/*
9267c478bd9Sstevel@tonic-gate 	* argc is the count of arguments, which should be filenames,
9277c478bd9Sstevel@tonic-gate 	* remaining in argv. av is a pointer to the first of the
9287c478bd9Sstevel@tonic-gate 	* remaining arguments.
9297c478bd9Sstevel@tonic-gate 	*/
9307c478bd9Sstevel@tonic-gate 
9317c478bd9Sstevel@tonic-gate 	for (filecounter = 0; filecounter < argc; filecounter++) {
9327c478bd9Sstevel@tonic-gate 		if ((strlen(av[filecounter])) >= PATH_MAX) {
9337c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
9347c478bd9Sstevel@tonic-gate 			    gettext("File argument too long\n"));
9357c478bd9Sstevel@tonic-gate 			exit(2);
9367c478bd9Sstevel@tonic-gate 		}
9377c478bd9Sstevel@tonic-gate 	}
9387c478bd9Sstevel@tonic-gate 
9397c478bd9Sstevel@tonic-gate 	if (lflag) {
9407c478bd9Sstevel@tonic-gate 		/*
9417c478bd9Sstevel@tonic-gate 		* if the user wants to include the math library, prepend
9427c478bd9Sstevel@tonic-gate 		* the math library filename to the argument list by
9437c478bd9Sstevel@tonic-gate 		* overwriting the last option (there must be at least one
9447c478bd9Sstevel@tonic-gate 		* supplied option if this is being done).
9457c478bd9Sstevel@tonic-gate 		*/
9467c478bd9Sstevel@tonic-gate 		av = &argv[optind-1];
9477c478bd9Sstevel@tonic-gate 		av[0] = "/usr/lib/lib.b";
9487c478bd9Sstevel@tonic-gate 		argc++;
9497c478bd9Sstevel@tonic-gate 	}
9507c478bd9Sstevel@tonic-gate 
9517c478bd9Sstevel@tonic-gate 	if (cflag) {
9527c478bd9Sstevel@tonic-gate 		yyinit(argc, av);
9537c478bd9Sstevel@tonic-gate 		yyparse();
9547c478bd9Sstevel@tonic-gate 		exit(0);
9557c478bd9Sstevel@tonic-gate 	}
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	pipe(p);
9587c478bd9Sstevel@tonic-gate 	if (fork() == 0) {
9597c478bd9Sstevel@tonic-gate 		(void) close(1);
9607c478bd9Sstevel@tonic-gate 		dup(p[1]);
9617c478bd9Sstevel@tonic-gate 		(void) close(p[0]);
9627c478bd9Sstevel@tonic-gate 		(void) close(p[1]);
9637c478bd9Sstevel@tonic-gate 		yyinit(argc, av);
9647c478bd9Sstevel@tonic-gate 		yyparse();
9657c478bd9Sstevel@tonic-gate 		exit(0);
9667c478bd9Sstevel@tonic-gate 	}
9677c478bd9Sstevel@tonic-gate 	(void) close(0);
9687c478bd9Sstevel@tonic-gate 	dup(p[0]);
9697c478bd9Sstevel@tonic-gate 	(void) close(p[0]);
9707c478bd9Sstevel@tonic-gate 	(void) close(p[1]);
9717c478bd9Sstevel@tonic-gate #ifdef XPG6
9727c478bd9Sstevel@tonic-gate 	execl("/usr/xpg6/bin/dc", "dc", "-", 0);
9737c478bd9Sstevel@tonic-gate #else
9747c478bd9Sstevel@tonic-gate 	execl("/usr/bin/dc", "dc", "-", 0);
9757c478bd9Sstevel@tonic-gate #endif
976*b390fe2cSmuffin 
977*b390fe2cSmuffin 	return (1);
9787c478bd9Sstevel@tonic-gate }
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate static void
9817c478bd9Sstevel@tonic-gate usage(void)
9827c478bd9Sstevel@tonic-gate {
9837c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
9847c478bd9Sstevel@tonic-gate 	    "usage: bc [ -c ] [ -l ] [ file ... ]\n"));
9857c478bd9Sstevel@tonic-gate 	exit(2);
9867c478bd9Sstevel@tonic-gate }
987