• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 %{
2 /*	$NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $	*/
3 
4 /*-
5  * Copyright (c) 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Kenneth Almquist.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)arith.y	8.3 (Berkeley) 5/4/95";
40 #else
41 __RCSID("$NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $");
42 #endif
43 #endif /* not lint */
44 
45 #include <stdlib.h>
46 #include "expand.h"
47 #include "shell.h"
48 #include "error.h"
49 #include "output.h"
50 #include "memalloc.h"
51 
52 const char *arith_buf, *arith_startbuf;
53 
54 void yyerror(const char *);
55 #ifdef TESTARITH
56 int main(int , char *[]);
57 int error(char *);
58 #endif
59 
60 %}
61 %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN
62 
63 %left ARITH_OR
64 %left ARITH_AND
65 %left ARITH_BOR
66 %left ARITH_BXOR
67 %left ARITH_BAND
68 %left ARITH_EQ ARITH_NE
69 %left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
70 %left ARITH_LSHIFT ARITH_RSHIFT
71 %left ARITH_ADD ARITH_SUB
72 %left ARITH_MUL ARITH_DIV ARITH_REM
73 %left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT
74 %%
75 
76 exp:	expr {
77 			return ($1);
78 		}
79 	;
80 
81 
82 expr:	ARITH_LPAREN expr ARITH_RPAREN { $$ = $2; }
83 	| expr ARITH_OR expr	{ $$ = $1 ? $1 : $3 ? $3 : 0; }
84 	| expr ARITH_AND expr	{ $$ = $1 ? ( $3 ? $3 : 0 ) : 0; }
85 	| expr ARITH_BOR expr	{ $$ = $1 | $3; }
86 	| expr ARITH_BXOR expr	{ $$ = $1 ^ $3; }
87 	| expr ARITH_BAND expr	{ $$ = $1 & $3; }
88 	| expr ARITH_EQ expr	{ $$ = $1 == $3; }
89 	| expr ARITH_GT expr	{ $$ = $1 > $3; }
90 	| expr ARITH_GE expr	{ $$ = $1 >= $3; }
91 	| expr ARITH_LT expr	{ $$ = $1 < $3; }
92 	| expr ARITH_LE expr	{ $$ = $1 <= $3; }
93 	| expr ARITH_NE expr	{ $$ = $1 != $3; }
94 	| expr ARITH_LSHIFT expr { $$ = $1 << $3; }
95 	| expr ARITH_RSHIFT expr { $$ = $1 >> $3; }
96 	| expr ARITH_ADD expr	{ $$ = $1 + $3; }
97 	| expr ARITH_SUB expr	{ $$ = $1 - $3; }
98 	| expr ARITH_MUL expr	{ $$ = $1 * $3; }
99 	| expr ARITH_DIV expr	{
100 			if ($3 == 0)
101 				yyerror("division by zero");
102 			$$ = $1 / $3;
103 			}
104 	| expr ARITH_REM expr   {
105 			if ($3 == 0)
106 				yyerror("division by zero");
107 			$$ = $1 % $3;
108 			}
109 	| ARITH_NOT expr	{ $$ = !($2); }
110 	| ARITH_BNOT expr	{ $$ = ~($2); }
111 	| ARITH_SUB expr %prec ARITH_UNARYMINUS { $$ = -($2); }
112 	| ARITH_ADD expr %prec ARITH_UNARYPLUS { $$ = $2; }
113 	| ARITH_NUM
114 	;
115 %%
116 int
arith(s)117 arith(s)
118 	const char *s;
119 {
120 	long result;
121 
122 	arith_buf = arith_startbuf = s;
123 
124 	INTOFF;
125 	result = yyparse();
126 	arith_lex_reset();	/* reprime lex */
127 	INTON;
128 
129 	return (result);
130 }
131 
132 
133 /*
134  *  The exp(1) builtin.
135  */
136 int
expcmd(argc,argv)137 expcmd(argc, argv)
138 	int argc;
139 	char **argv;
140 {
141 	const char *p;
142 	char *concat;
143 	char **ap;
144 	long i;
145 
146 	if (argc > 1) {
147 		p = argv[1];
148 		if (argc > 2) {
149 			/*
150 			 * concatenate arguments
151 			 */
152 			STARTSTACKSTR(concat);
153 			ap = argv + 2;
154 			for (;;) {
155 				while (*p)
156 					STPUTC(*p++, concat);
157 				if ((p = *ap++) == NULL)
158 					break;
159 				STPUTC(' ', concat);
160 			}
161 			STPUTC('\0', concat);
162 			p = grabstackstr(concat);
163 		}
164 	} else
165 		p = "";
166 
167 	i = arith(p);
168 
169 	out1fmt("%ld\n", i);
170 	return (! i);
171 }
172 
173 /*************************/
174 #ifdef TEST_ARITH
175 #include <stdio.h>
main(argc,argv)176 main(argc, argv)
177 	char *argv[];
178 {
179 	printf("%d\n", exp(argv[1]));
180 }
error(s)181 error(s)
182 	char *s;
183 {
184 	fprintf(stderr, "exp: %s\n", s);
185 	exit(1);
186 }
187 #endif
188 
189 void
yyerror(s)190 yyerror(s)
191 	const char *s;
192 {
193 
194 //	yyerrok;
195 	yyclearin;
196 	arith_lex_reset();	/* reprime lex */
197 	error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
198 	/* NOTREACHED */
199 }
200