Subversion Repositories HelenOS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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