GCC3.4's (default) unit-at-a-time optimization is incompatible with -mrtd.
[dragonfly.git] / bin / sh / arith.y
1 %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN
2
3 %left ARITH_OR
4 %left ARITH_AND
5 %left ARITH_BOR
6 %left ARITH_BXOR
7 %left ARITH_BAND
8 %left ARITH_EQ ARITH_NE
9 %left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
10 %left ARITH_LSHIFT ARITH_RSHIFT
11 %left ARITH_ADD ARITH_SUB
12 %left ARITH_MUL ARITH_DIV ARITH_REM
13 %left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT
14 %%
15
16 exp:    expr = {
17                         return ($1);
18                 }
19         ;
20
21
22 expr:   ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; }
23         | expr ARITH_OR expr    = { $$ = $1 ? $1 : $3 ? $3 : 0; }
24         | expr ARITH_AND expr   = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; }
25         | expr ARITH_BOR expr   = { $$ = $1 | $3; }
26         | expr ARITH_BXOR expr  = { $$ = $1 ^ $3; }
27         | expr ARITH_BAND expr  = { $$ = $1 & $3; }
28         | expr ARITH_EQ expr    = { $$ = $1 == $3; }
29         | expr ARITH_GT expr    = { $$ = $1 > $3; }
30         | expr ARITH_GE expr    = { $$ = $1 >= $3; }
31         | expr ARITH_LT expr    = { $$ = $1 < $3; }
32         | expr ARITH_LE expr    = { $$ = $1 <= $3; }
33         | expr ARITH_NE expr    = { $$ = $1 != $3; }
34         | expr ARITH_LSHIFT expr = { $$ = $1 << $3; }
35         | expr ARITH_RSHIFT expr = { $$ = $1 >> $3; }
36         | expr ARITH_ADD expr   = { $$ = $1 + $3; }
37         | expr ARITH_SUB expr   = { $$ = $1 - $3; }
38         | expr ARITH_MUL expr   = { $$ = $1 * $3; }
39         | expr ARITH_DIV expr   = {
40                         if ($3 == 0)
41                                 yyerror("division by zero");
42                         $$ = $1 / $3;
43                         }
44         | expr ARITH_REM expr   = {
45                         if ($3 == 0)
46                                 yyerror("division by zero");
47                         $$ = $1 % $3;
48                         }
49         | ARITH_NOT expr        = { $$ = !($2); }
50         | ARITH_BNOT expr       = { $$ = ~($2); }
51         | ARITH_SUB expr %prec ARITH_UNARYMINUS = { $$ = -($2); }
52         | ARITH_ADD expr %prec ARITH_UNARYPLUS = { $$ = $2; }
53         | ARITH_NUM
54         ;
55 %%
56 /*-
57  * Copyright (c) 1993
58  *      The Regents of the University of California.  All rights reserved.
59  *
60  * This code is derived from software contributed to Berkeley by
61  * Kenneth Almquist.
62  *
63  * Redistribution and use in source and binary forms, with or without
64  * modification, are permitted provided that the following conditions
65  * are met:
66  * 1. Redistributions of source code must retain the above copyright
67  *    notice, this list of conditions and the following disclaimer.
68  * 2. Redistributions in binary form must reproduce the above copyright
69  *    notice, this list of conditions and the following disclaimer in the
70  *    documentation and/or other materials provided with the distribution.
71  * 3. All advertising materials mentioning features or use of this software
72  *    must display the following acknowledgement:
73  *      This product includes software developed by the University of
74  *      California, Berkeley and its contributors.
75  * 4. Neither the name of the University nor the names of its contributors
76  *    may be used to endorse or promote products derived from this software
77  *    without specific prior written permission.
78  *
79  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
80  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
81  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
83  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
84  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
87  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
88  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
89  * SUCH DAMAGE.
90  *
91  * @(#)arith.y  8.3 (Berkeley) 5/4/95
92  * $FreeBSD: src/bin/sh/arith.y,v 1.10.2.2 2002/07/19 04:38:51 tjr Exp $
93  * $DragonFly: src/bin/sh/arith.y,v 1.3 2004/03/19 18:39:40 cpressey Exp $
94  */
95
96 #include "shell.h"
97 #include "error.h"
98 #include "output.h"
99 #include "memalloc.h"
100
101 #include "arith.h"
102
103 const char *arith_buf, *arith_startbuf;
104 extern void arith_lex_reset(void);
105
106 int yylex(void);
107 int yyparse(void);
108 void yyerror(const char *s);
109
110 int
111 arith(const char *s)
112 {
113         long result;
114
115         arith_buf = arith_startbuf = s;
116
117         INTOFF;
118         result = yyparse();
119         arith_lex_reset();      /* reprime lex */
120         INTON;
121
122         return (result);
123 }
124
125 void
126 yyerror(const char *s)
127 {
128
129         yyerrok;
130         yyclearin;
131         arith_lex_reset();      /* reprime lex */
132         error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
133 }
134
135 /*
136  *  The exp(1) builtin.
137  */
138 int
139 expcmd(int argc, 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>
176 main(int argc, char *argv[])
177 {
178         printf("%d\n", exp(argv[1]));
179 }
180
181 error(char *s)
182 {
183         fprintf(stderr, "exp: %s\n", s);
184         exit(1);
185 }
186 #endif