Expand PMF_FN_* macros.
[netbsd-mini2440.git] / bin / sh / arith.y
blobc69d3623b7aed7e301ea966eac38f17b744743a5
1 %{
2 /* $NetBSD: arith.y,v 1.18 2007/03/25 06:29:26 apb Exp $ */
4 /*-
5 * Copyright (c) 1993
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Kenneth Almquist.
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.
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.
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.18 2007/03/25 06:29:26 apb Exp $");
42 #endif
43 #endif /* not lint */
45 #include <stdlib.h>
46 #include "expand.h"
47 #include "shell.h"
48 #include "error.h"
49 #include "output.h"
50 #include "memalloc.h"
52 typedef intmax_t YYSTYPE;
53 #define YYSTYPE YYSTYPE
55 intmax_t arith_result;
56 const char *arith_buf, *arith_startbuf;
58 void yyerror(const char *);
59 #ifdef TESTARITH
60 int main(int , char *[]);
61 int error(char *);
62 #endif
65 %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN
67 %left ARITH_OR
68 %left ARITH_AND
69 %left ARITH_BOR
70 %left ARITH_BXOR
71 %left ARITH_BAND
72 %left ARITH_EQ ARITH_NE
73 %left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
74 %left ARITH_LSHIFT ARITH_RSHIFT
75 %left ARITH_ADD ARITH_SUB
76 %left ARITH_MUL ARITH_DIV ARITH_REM
77 %left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT
80 exp: expr {
82 * yyparse() returns int, so we have to save
83 * the desired result elsewhere.
85 arith_result = $1;
90 expr: ARITH_LPAREN expr ARITH_RPAREN { $$ = $2; }
91 | expr ARITH_OR expr { $$ = $1 ? $1 : $3 ? $3 : 0; }
92 | expr ARITH_AND expr { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; }
93 | expr ARITH_BOR expr { $$ = $1 | $3; }
94 | expr ARITH_BXOR expr { $$ = $1 ^ $3; }
95 | expr ARITH_BAND expr { $$ = $1 & $3; }
96 | expr ARITH_EQ expr { $$ = $1 == $3; }
97 | expr ARITH_GT expr { $$ = $1 > $3; }
98 | expr ARITH_GE expr { $$ = $1 >= $3; }
99 | expr ARITH_LT expr { $$ = $1 < $3; }
100 | expr ARITH_LE expr { $$ = $1 <= $3; }
101 | expr ARITH_NE expr { $$ = $1 != $3; }
102 | expr ARITH_LSHIFT expr { $$ = $1 << $3; }
103 | expr ARITH_RSHIFT expr { $$ = $1 >> $3; }
104 | expr ARITH_ADD expr { $$ = $1 + $3; }
105 | expr ARITH_SUB expr { $$ = $1 - $3; }
106 | expr ARITH_MUL expr { $$ = $1 * $3; }
107 | expr ARITH_DIV expr {
108 if ($3 == 0)
109 yyerror("division by zero");
110 $$ = $1 / $3;
112 | expr ARITH_REM expr {
113 if ($3 == 0)
114 yyerror("division by zero");
115 $$ = $1 % $3;
117 | ARITH_NOT expr { $$ = !($2); }
118 | ARITH_BNOT expr { $$ = ~($2); }
119 | ARITH_SUB expr %prec ARITH_UNARYMINUS { $$ = -($2); }
120 | ARITH_ADD expr %prec ARITH_UNARYPLUS { $$ = $2; }
121 | ARITH_NUM
124 intmax_t
125 arith(s)
126 const char *s;
128 intmax_t result;
130 arith_buf = arith_startbuf = s;
132 INTOFF;
133 (void) yyparse();
134 result = arith_result;
135 arith_lex_reset(); /* reprime lex */
136 INTON;
138 return (result);
143 * The exp(1) builtin.
146 expcmd(argc, argv)
147 int argc;
148 char **argv;
150 const char *p;
151 char *concat;
152 char **ap;
153 intmax_t i;
155 if (argc > 1) {
156 p = argv[1];
157 if (argc > 2) {
159 * concatenate arguments
161 STARTSTACKSTR(concat);
162 ap = argv + 2;
163 for (;;) {
164 while (*p)
165 STPUTC(*p++, concat);
166 if ((p = *ap++) == NULL)
167 break;
168 STPUTC(' ', concat);
170 STPUTC('\0', concat);
171 p = grabstackstr(concat);
173 } else
174 p = "";
176 (void)arith(p);
177 i = arith_result;
179 out1fmt("%"PRIdMAX"\n", i);
180 return (! i);
183 /*************************/
184 #ifdef TEST_ARITH
185 #include <stdio.h>
186 main(argc, argv)
187 char *argv[];
189 printf("%"PRIdMAX"\n", exp(argv[1]));
191 error(s)
192 char *s;
194 fprintf(stderr, "exp: %s\n", s);
195 exit(1);
197 #endif
199 void
200 yyerror(s)
201 const char *s;
204 yyerrok;
205 yyclearin;
206 arith_lex_reset(); /* reprime lex */
207 error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
208 /* NOTREACHED */