xref: /csrg-svn/bin/sh/arith.y (revision 69273)
168929Sbostic %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN
254332Smarc 
354332Smarc %left ARITH_OR
454332Smarc %left ARITH_AND
568929Sbostic %left ARITH_BOR
668929Sbostic %left ARITH_BXOR
768929Sbostic %left ARITH_BAND
868929Sbostic %left ARITH_EQ ARITH_NE
968929Sbostic %left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
1068929Sbostic %left ARITH_LSHIFT ARITH_RSHIFT
1168929Sbostic %left ARITH_ADD ARITH_SUB
1268929Sbostic %left ARITH_MUL ARITH_DIV ARITH_REM
1368929Sbostic %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; }
2368929Sbostic 	| expr ARITH_OR expr	= { $$ = $1 ? $1 : $3 ? $3 : 0; }
2468929Sbostic 	| expr ARITH_AND expr	= { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; }
2568929Sbostic 	| expr ARITH_BOR expr	= { $$ = $1 | $3; }
2668929Sbostic 	| expr ARITH_BXOR expr	= { $$ = $1 ^ $3; }
2768929Sbostic 	| expr ARITH_BAND expr	= { $$ = $1 & $3; }
2868929Sbostic 	| expr ARITH_EQ expr	= { $$ = $1 == $3; }
2968929Sbostic 	| expr ARITH_GT expr	= { $$ = $1 > $3; }
3068929Sbostic 	| expr ARITH_GE expr	= { $$ = $1 >= $3; }
3168929Sbostic 	| expr ARITH_LT expr	= { $$ = $1 < $3; }
3268929Sbostic 	| expr ARITH_LE expr	= { $$ = $1 <= $3; }
3368929Sbostic 	| expr ARITH_NE expr	= { $$ = $1 != $3; }
3468929Sbostic 	| expr ARITH_LSHIFT expr = { $$ = $1 << $3; }
3568929Sbostic 	| expr ARITH_RSHIFT expr = { $$ = $1 >> $3; }
3668929Sbostic 	| expr ARITH_ADD expr	= { $$ = $1 + $3; }
3768929Sbostic 	| expr ARITH_SUB expr	= { $$ = $1 - $3; }
3868929Sbostic 	| expr ARITH_MUL expr	= { $$ = $1 * $3; }
3968929Sbostic 	| expr ARITH_DIV expr	= {
4054332Smarc 			if ($3 == 0)
4154332Smarc 				yyerror("division by zero");
4254332Smarc 			$$ = $1 / $3;
4354332Smarc 			}
4468929Sbostic 	| expr ARITH_REM expr   = {
4568929Sbostic 			if ($3 == 0)
4668929Sbostic 				yyerror("division by zero");
4768929Sbostic 			$$ = $1 % $3;
4868929Sbostic 			}
4954332Smarc 	| ARITH_NOT expr	= { $$ = !($2); }
5068929Sbostic 	| ARITH_BNOT expr	= { $$ = ~($2); }
5168929Sbostic 	| ARITH_SUB expr %prec ARITH_UNARYMINUS = { $$ = -($2); }
5268929Sbostic 	| 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*69273Schristos static char sccsid[] = "@(#)arith.y	8.3 (Berkeley) 05/04/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 
77*69273Schristos int
arith(s)7854332Smarc arith(s)
7954332Smarc 	char *s;
8054332Smarc {
8154332Smarc 	long result;
8254332Smarc 
8354332Smarc 	arith_buf = arith_startbuf = s;
8454332Smarc 
8554332Smarc 	INTOFF;
8654332Smarc 	result = yyparse();
8754332Smarc 	arith_lex_reset();	/* reprime lex */
8854332Smarc 	INTON;
8954332Smarc 
9054332Smarc 	return (result);
9154332Smarc }
9254332Smarc 
93*69273Schristos void
yyerror(s)9454332Smarc yyerror(s)
9554332Smarc 	char *s;
9654332Smarc {
9754332Smarc 
9854332Smarc 	yyerrok;
9954332Smarc 	yyclearin;
10054332Smarc 	arith_lex_reset();	/* reprime lex */
10154332Smarc 	error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
10254332Smarc }
10354332Smarc 
10454332Smarc /*
10554332Smarc  *  The exp(1) builtin.
10654332Smarc  */
107*69273Schristos int
expcmd(argc,argv)10854332Smarc expcmd(argc, argv)
109*69273Schristos 	int argc;
11054332Smarc 	char **argv;
11154332Smarc {
11254332Smarc 	char *p;
11354332Smarc 	char *concat;
11454332Smarc 	char **ap;
11554332Smarc 	long i;
11654332Smarc 
11754332Smarc 	if (argc > 1) {
11854332Smarc 		p = argv[1];
11954332Smarc 		if (argc > 2) {
12054332Smarc 			/*
12154332Smarc 			 * concatenate arguments
12254332Smarc 			 */
12354332Smarc 			STARTSTACKSTR(concat);
12454332Smarc 			ap = argv + 2;
12554332Smarc 			for (;;) {
12654332Smarc 				while (*p)
12754332Smarc 					STPUTC(*p++, concat);
12854332Smarc 				if ((p = *ap++) == NULL)
12954332Smarc 					break;
13054332Smarc 				STPUTC(' ', concat);
13154332Smarc 			}
13254332Smarc 			STPUTC('\0', concat);
13354332Smarc 			p = grabstackstr(concat);
13454332Smarc 		}
13554332Smarc 	} else
13654332Smarc 		p = "";
13754332Smarc 
13854332Smarc 	i = arith(p);
13954332Smarc 
14054332Smarc 	out1fmt("%d\n", i);
14154332Smarc 	return (! i);
14254332Smarc }
14354332Smarc 
14454332Smarc /*************************/
14554332Smarc #ifdef TEST_ARITH
14654332Smarc #include <stdio.h>
main(argc,argv)14754332Smarc main(argc, argv)
14854332Smarc 	char *argv[];
14954332Smarc {
15054332Smarc 	printf("%d\n", exp(argv[1]));
15154332Smarc }
error(s)15254332Smarc error(s)
15354332Smarc 	char *s;
15454332Smarc {
15554332Smarc 	fprintf(stderr, "exp: %s\n", s);
15654332Smarc 	exit(1);
15754332Smarc }
15854332Smarc #endif
159