xref: /csrg-svn/bin/sh/arith.y (revision 54332)
1*54332Smarc %token ARITH_OR ARITH_AND ARITH_ADD ARITH_SUBT ARITH_MULT ARITH_DIV ARITH_REM ARITH_EQ ARITH_GT ARITH_GEQ ARITH_LT ARITH_LEQ ARITH_NEQ
2*54332Smarc %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN ARITH_NOT ARITH_UNARYMINUS
3*54332Smarc 
4*54332Smarc %left ARITH_OR
5*54332Smarc %left ARITH_AND
6*54332Smarc %left ARITH_EQ ARITH_NEQ
7*54332Smarc %left ARITH_LT ARITH_GT ARITH_GEQ ARITH_LEQ
8*54332Smarc %left ARITH_ADD ARITH_SUBT
9*54332Smarc %left ARITH_MULT ARITH_DIV ARITH_REM
10*54332Smarc %left ARITH_UNARYMINUS ARITH_NOT
11*54332Smarc %%
12*54332Smarc 
13*54332Smarc exp:	expr = {
14*54332Smarc 			return ($1);
15*54332Smarc 		}
16*54332Smarc 	;
17*54332Smarc 
18*54332Smarc 
19*54332Smarc expr:	ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; }
20*54332Smarc 	| expr ARITH_OR expr   = { $$ = $1 ? $1 : $3 ? $3 : 0; }
21*54332Smarc 	| expr ARITH_AND expr   = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; }
22*54332Smarc 	| expr ARITH_EQ expr   = { $$ = $1 == $3; }
23*54332Smarc 	| expr ARITH_GT expr   = { $$ = $1 > $3; }
24*54332Smarc 	| expr ARITH_GEQ expr   = { $$ = $1 >= $3; }
25*54332Smarc 	| expr ARITH_LT expr   = { $$ = $1 < $3; }
26*54332Smarc 	| expr ARITH_LEQ expr   = { $$ = $1 <= $3; }
27*54332Smarc 	| expr ARITH_NEQ expr   = { $$ = $1 != $3; }
28*54332Smarc 	| expr ARITH_ADD expr   = { $$ = $1 + $3; }
29*54332Smarc 	| expr ARITH_SUBT expr   = { $$ = $1 - $3; }
30*54332Smarc 	| expr ARITH_MULT expr   = { $$ = $1 * $3; }
31*54332Smarc 	| expr ARITH_DIV expr   = {
32*54332Smarc 			if ($3 == 0)
33*54332Smarc 				yyerror("division by zero");
34*54332Smarc 			$$ = $1 / $3;
35*54332Smarc 			}
36*54332Smarc 	| expr ARITH_REM expr   = { $$ = $1 % $3; }
37*54332Smarc 	| ARITH_NOT expr	= { $$ = !($2); }
38*54332Smarc 	| ARITH_UNARYMINUS expr = { $$ = -($2); }
39*54332Smarc 	| ARITH_NUM
40*54332Smarc 	;
41*54332Smarc %%
42*54332Smarc 
43*54332Smarc #include "shell.h"
44*54332Smarc #include "error.h"
45*54332Smarc #include "output.h"
46*54332Smarc #include "memalloc.h"
47*54332Smarc 
48*54332Smarc char *arith_buf, *arith_startbuf;
49*54332Smarc 
50*54332Smarc arith(s)
51*54332Smarc 	char *s;
52*54332Smarc {
53*54332Smarc 	extern arith_wasoper;
54*54332Smarc 	long result;
55*54332Smarc 
56*54332Smarc 	arith_wasoper = 1;
57*54332Smarc 	arith_buf = arith_startbuf = s;
58*54332Smarc 
59*54332Smarc 	INTOFF;
60*54332Smarc 	result = yyparse();
61*54332Smarc 	arith_lex_reset();	/* reprime lex */
62*54332Smarc 	INTON;
63*54332Smarc 
64*54332Smarc 	return (result);
65*54332Smarc }
66*54332Smarc 
67*54332Smarc yyerror(s)
68*54332Smarc 	char *s;
69*54332Smarc {
70*54332Smarc 	extern yytext, yylval;
71*54332Smarc 
72*54332Smarc 	yyerrok;
73*54332Smarc 	yyclearin;
74*54332Smarc 	arith_lex_reset();	/* reprime lex */
75*54332Smarc 	error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
76*54332Smarc }
77*54332Smarc 
78*54332Smarc /*
79*54332Smarc  *  The exp(1) builtin.
80*54332Smarc  */
81*54332Smarc expcmd(argc, argv)
82*54332Smarc 	char **argv;
83*54332Smarc {
84*54332Smarc 	char *p;
85*54332Smarc 	char *concat;
86*54332Smarc 	char **ap;
87*54332Smarc 	long i;
88*54332Smarc 
89*54332Smarc 	if (argc > 1) {
90*54332Smarc 		p = argv[1];
91*54332Smarc 		if (argc > 2) {
92*54332Smarc 			/*
93*54332Smarc 			 * concatenate arguments
94*54332Smarc 			 */
95*54332Smarc 			STARTSTACKSTR(concat);
96*54332Smarc 			ap = argv + 2;
97*54332Smarc 			for (;;) {
98*54332Smarc 				while (*p)
99*54332Smarc 					STPUTC(*p++, concat);
100*54332Smarc 				if ((p = *ap++) == NULL)
101*54332Smarc 					break;
102*54332Smarc 				STPUTC(' ', concat);
103*54332Smarc 			}
104*54332Smarc 			STPUTC('\0', concat);
105*54332Smarc 			p = grabstackstr(concat);
106*54332Smarc 		}
107*54332Smarc 	} else
108*54332Smarc 		p = "";
109*54332Smarc 
110*54332Smarc 	i = arith(p);
111*54332Smarc 
112*54332Smarc 	out1fmt("%d\n", i);
113*54332Smarc 	return (! i);
114*54332Smarc }
115*54332Smarc 
116*54332Smarc /*************************/
117*54332Smarc #ifdef TEST_ARITH
118*54332Smarc #include <stdio.h>
119*54332Smarc main(argc, argv)
120*54332Smarc 	char *argv[];
121*54332Smarc {
122*54332Smarc 	printf("%d\n", exp(argv[1]));
123*54332Smarc }
124*54332Smarc error(s)
125*54332Smarc 	char *s;
126*54332Smarc {
127*54332Smarc 	fprintf(stderr, "exp: %s\n", s);
128*54332Smarc 	exit(1);
129*54332Smarc }
130*54332Smarc #endif
131