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