xref: /csrg-svn/bin/sh/arith.y (revision 68929)
1*68929Sbostic %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN
254332Smarc 
354332Smarc %left ARITH_OR
454332Smarc %left ARITH_AND
5*68929Sbostic %left ARITH_BOR
6*68929Sbostic %left ARITH_BXOR
7*68929Sbostic %left ARITH_BAND
8*68929Sbostic %left ARITH_EQ ARITH_NE
9*68929Sbostic %left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
10*68929Sbostic %left ARITH_LSHIFT ARITH_RSHIFT
11*68929Sbostic %left ARITH_ADD ARITH_SUB
12*68929Sbostic %left ARITH_MUL ARITH_DIV ARITH_REM
13*68929Sbostic %left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT
1454332Smarc %%
1554332Smarc 
1654332Smarc exp:	expr = {
1754332Smarc 			return ($1);
1854332Smarc 		}
1954332Smarc 	;
2054332Smarc 
2154332Smarc 
2254332Smarc expr:	ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; }
23*68929Sbostic 	| expr ARITH_OR expr	= { $$ = $1 ? $1 : $3 ? $3 : 0; }
24*68929Sbostic 	| expr ARITH_AND expr	= { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; }
25*68929Sbostic 	| expr ARITH_BOR expr	= { $$ = $1 | $3; }
26*68929Sbostic 	| expr ARITH_BXOR expr	= { $$ = $1 ^ $3; }
27*68929Sbostic 	| expr ARITH_BAND expr	= { $$ = $1 & $3; }
28*68929Sbostic 	| expr ARITH_EQ expr	= { $$ = $1 == $3; }
29*68929Sbostic 	| expr ARITH_GT expr	= { $$ = $1 > $3; }
30*68929Sbostic 	| expr ARITH_GE expr	= { $$ = $1 >= $3; }
31*68929Sbostic 	| expr ARITH_LT expr	= { $$ = $1 < $3; }
32*68929Sbostic 	| expr ARITH_LE expr	= { $$ = $1 <= $3; }
33*68929Sbostic 	| expr ARITH_NE expr	= { $$ = $1 != $3; }
34*68929Sbostic 	| expr ARITH_LSHIFT expr = { $$ = $1 << $3; }
35*68929Sbostic 	| expr ARITH_RSHIFT expr = { $$ = $1 >> $3; }
36*68929Sbostic 	| expr ARITH_ADD expr	= { $$ = $1 + $3; }
37*68929Sbostic 	| expr ARITH_SUB expr	= { $$ = $1 - $3; }
38*68929Sbostic 	| expr ARITH_MUL expr	= { $$ = $1 * $3; }
39*68929Sbostic 	| expr ARITH_DIV expr	= {
4054332Smarc 			if ($3 == 0)
4154332Smarc 				yyerror("division by zero");
4254332Smarc 			$$ = $1 / $3;
4354332Smarc 			}
44*68929Sbostic 	| expr ARITH_REM expr   = {
45*68929Sbostic 			if ($3 == 0)
46*68929Sbostic 				yyerror("division by zero");
47*68929Sbostic 			$$ = $1 % $3;
48*68929Sbostic 			}
4954332Smarc 	| ARITH_NOT expr	= { $$ = !($2); }
50*68929Sbostic 	| ARITH_BNOT expr	= { $$ = ~($2); }
51*68929Sbostic 	| ARITH_SUB expr %prec ARITH_UNARYMINUS = { $$ = -($2); }
52*68929Sbostic 	| ARITH_ADD expr %prec ARITH_UNARYPLUS = { $$ = $2; }
5354332Smarc 	| ARITH_NUM
5454332Smarc 	;
5554332Smarc %%
5660701Sbostic /*-
5760701Sbostic  * Copyright (c) 1993
5860701Sbostic  *	The Regents of the University of California.  All rights reserved.
5960701Sbostic  *
6060701Sbostic  * This code is derived from software contributed to Berkeley by
6160701Sbostic  * Kenneth Almquist.
6260701Sbostic  *
6360701Sbostic  * %sccs.include.redist.c%
6460701Sbostic  */
6554332Smarc 
6660701Sbostic #ifndef lint
67*68929Sbostic static char sccsid[] = "@(#)arith.y	8.2 (Berkeley) 04/27/95";
6860701Sbostic #endif /* not lint */
6960701Sbostic 
7054332Smarc #include "shell.h"
7154332Smarc #include "error.h"
7254332Smarc #include "output.h"
7354332Smarc #include "memalloc.h"
7454332Smarc 
7554332Smarc char *arith_buf, *arith_startbuf;
7654332Smarc 
7754332Smarc arith(s)
7854332Smarc 	char *s;
7954332Smarc {
8054332Smarc 	long result;
8154332Smarc 
8254332Smarc 	arith_buf = arith_startbuf = s;
8354332Smarc 
8454332Smarc 	INTOFF;
8554332Smarc 	result = yyparse();
8654332Smarc 	arith_lex_reset();	/* reprime lex */
8754332Smarc 	INTON;
8854332Smarc 
8954332Smarc 	return (result);
9054332Smarc }
9154332Smarc 
9254332Smarc yyerror(s)
9354332Smarc 	char *s;
9454332Smarc {
9554332Smarc 	extern yytext, yylval;
9654332Smarc 
9754332Smarc 	yyerrok;
9854332Smarc 	yyclearin;
9954332Smarc 	arith_lex_reset();	/* reprime lex */
10054332Smarc 	error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
10154332Smarc }
10254332Smarc 
10354332Smarc /*
10454332Smarc  *  The exp(1) builtin.
10554332Smarc  */
10654332Smarc expcmd(argc, argv)
10754332Smarc 	char **argv;
10854332Smarc {
10954332Smarc 	char *p;
11054332Smarc 	char *concat;
11154332Smarc 	char **ap;
11254332Smarc 	long i;
11354332Smarc 
11454332Smarc 	if (argc > 1) {
11554332Smarc 		p = argv[1];
11654332Smarc 		if (argc > 2) {
11754332Smarc 			/*
11854332Smarc 			 * concatenate arguments
11954332Smarc 			 */
12054332Smarc 			STARTSTACKSTR(concat);
12154332Smarc 			ap = argv + 2;
12254332Smarc 			for (;;) {
12354332Smarc 				while (*p)
12454332Smarc 					STPUTC(*p++, concat);
12554332Smarc 				if ((p = *ap++) == NULL)
12654332Smarc 					break;
12754332Smarc 				STPUTC(' ', concat);
12854332Smarc 			}
12954332Smarc 			STPUTC('\0', concat);
13054332Smarc 			p = grabstackstr(concat);
13154332Smarc 		}
13254332Smarc 	} else
13354332Smarc 		p = "";
13454332Smarc 
13554332Smarc 	i = arith(p);
13654332Smarc 
13754332Smarc 	out1fmt("%d\n", i);
13854332Smarc 	return (! i);
13954332Smarc }
14054332Smarc 
14154332Smarc /*************************/
14254332Smarc #ifdef TEST_ARITH
14354332Smarc #include <stdio.h>
14454332Smarc main(argc, argv)
14554332Smarc 	char *argv[];
14654332Smarc {
14754332Smarc 	printf("%d\n", exp(argv[1]));
14854332Smarc }
14954332Smarc error(s)
15054332Smarc 	char *s;
15154332Smarc {
15254332Smarc 	fprintf(stderr, "exp: %s\n", s);
15354332Smarc 	exit(1);
15454332Smarc }
15554332Smarc #endif
156