2 /* $NetBSD: arith.y,v 1.22 2012/03/20 18:42:29 matt Exp $ */
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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
36 #include <sys/cdefs.h>
39 static char sccsid
[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95";
41 __RCSID
("$NetBSD: arith.y,v 1.22 2012/03/20 18:42:29 matt Exp $");
53 typedef
intmax_t YYSTYPE;
54 #define YYSTYPE YYSTYPE
56 intmax_t arith_result
;
57 const char *arith_buf
, *arith_startbuf
;
59 __dead
static void yyerror(const char *);
61 int main
(int , char *[]);
66 %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN
73 %left ARITH_EQ ARITH_NE
74 %left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
75 %left ARITH_LSHIFT ARITH_RSHIFT
76 %left ARITH_ADD ARITH_SUB
77 %left ARITH_MUL ARITH_DIV ARITH_REM
78 %left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT
83 * yyparse() returns int, so we have to save
84 * the desired result elsewhere.
91 expr: ARITH_LPAREN expr ARITH_RPAREN
{ $$
= $2; }
92 | expr ARITH_OR expr
{ $$
= $1 ?
$1 : $3 ?
$3 : 0; }
93 | expr ARITH_AND expr
{ $$
= $1 ?
( $3 ?
$3 : 0 ) : 0; }
94 | expr ARITH_BOR expr
{ $$
= $1 |
$3; }
95 | expr ARITH_BXOR expr
{ $$
= $1 ^
$3; }
96 | expr ARITH_BAND expr
{ $$
= $1 & $3; }
97 | expr ARITH_EQ expr
{ $$
= $1 == $3; }
98 | expr ARITH_GT expr
{ $$
= $1 > $3; }
99 | expr ARITH_GE expr
{ $$
= $1 >= $3; }
100 | expr ARITH_LT expr
{ $$
= $1 < $3; }
101 | expr ARITH_LE expr
{ $$
= $1 <= $3; }
102 | expr ARITH_NE expr
{ $$
= $1 != $3; }
103 | expr ARITH_LSHIFT expr
{ $$
= $1 << $3; }
104 | expr ARITH_RSHIFT expr
{ $$
= $1 >> $3; }
105 | expr ARITH_ADD expr
{ $$
= $1 + $3; }
106 | expr ARITH_SUB expr
{ $$
= $1 - $3; }
107 | expr ARITH_MUL expr
{ $$
= $1 * $3; }
108 | expr ARITH_DIV expr
{
110 yyerror("division by zero");
113 | expr ARITH_REM expr
{
115 yyerror("division by zero");
118 | ARITH_NOT expr
{ $$
= !($2); }
119 | ARITH_BNOT expr
{ $$
= ~
($2); }
120 | ARITH_SUB expr %prec ARITH_UNARYMINUS
{ $$
= -($2); }
121 | ARITH_ADD expr %prec ARITH_UNARYPLUS
{ $$
= $2; }
130 arith_buf
= arith_startbuf
= s
;
134 result
= arith_result
;
135 arith_lex_reset
(); /* reprime lex */
143 * The exp(1) builtin.
146 expcmd
(int argc
, char **argv
)
157 * concatenate arguments
159 STARTSTACKSTR
(concat
);
163 STPUTC
(*p
++, concat
);
164 if
((p
= *ap
++) == NULL
)
168 STPUTC
('\0', concat
);
169 p
= grabstackstr
(concat
);
177 out1fmt
("%"PRIdMAX
"\n", i
);
181 /*************************/
187 printf
("%"PRIdMAX
"\n", exp
(argv
[1]));
192 fprintf
(stderr
, "exp: %s\n", s
);
198 yyerror(const char *s
)
203 arith_lex_reset
(); /* reprime lex */
204 error("arithmetic expression: %s: \"%s\"", s
, arith_startbuf
);