annotate eval.c @ 135:eaae8014a94a

Don't assert and leak memory if failing during argument collection. Once you have a -D option or a -include foo option, you need to clean up the arrays those are accumulated in if you die before they're collected and handled.
author David A. Holland
date Tue, 09 Jul 2013 13:35:40 -0400
parents 33954a07d013
children 1d2bad7151f9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
1 /*-
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
2 * Copyright (c) 2010 The NetBSD Foundation, Inc.
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
3 * All rights reserved.
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
4 *
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
5 * This code is derived from software contributed to The NetBSD Foundation
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
6 * by David A. Holland.
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
7 *
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
8 * Redistribution and use in source and binary forms, with or without
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
9 * modification, are permitted provided that the following conditions
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
10 * are met:
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
11 * 1. Redistributions of source code must retain the above copyright
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
12 * notice, this list of conditions and the following disclaimer.
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
13 * 2. Redistributions in binary form must reproduce the above copyright
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
14 * notice, this list of conditions and the following disclaimer in the
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
15 * documentation and/or other materials provided with the distribution.
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
16 *
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
27 * POSSIBILITY OF SUCH DAMAGE.
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
28 */
76c114899f63 copyrights
David A. Holland
parents: 28
diff changeset
29
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
30 #include <stdlib.h>
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
31 #include <string.h>
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
32 #include <limits.h>
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
33 #include <errno.h>
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
34
92
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
35 //#define DEBUG
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
36 #ifdef DEBUG
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
37 #include <stdio.h>
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
38 #endif
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
39
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
40 #include "utils.h"
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
41 #include "array.h"
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
42 #include "mode.h"
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
43 #include "place.h"
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
44 #include "eval.h"
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
45
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
46 /*
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
47 * e ::=
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
48 * e1 ? e2 : e3
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
49 * e1 || e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
50 * e1 && e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
51 * e1 | e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
52 * e1 ^ e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
53 * e1 & e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
54 * e1 == e2 | e1 != e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
55 * e1 < e2 | e1 <= e2 | e1 > e2 | e1 >= e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
56 * e1 << e2 | e1 >> e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
57 * e1 + e2 | e1 - e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
58 * e1 * e2 | e1 / e2 | e1 % e2
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
59 * !e | ~e | -e | +e
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
60 * ( e ) | ident
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
61 */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
62
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
63 enum tokens {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
64 T_EOF, /* end of input */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
65 T_VAL, /* value */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
66 T_LPAREN, /* parens */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
67 T_RPAREN,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
68 T_PIPEPIPE, /* operators */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
69 T_AMPAMP,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
70 T_EQEQ,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
71 T_BANGEQ,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
72 T_LTEQ,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
73 T_GTEQ,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
74 T_LTLT,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
75 T_GTGT,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
76 T_QUES,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
77 T_COLON,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
78 T_PIPE,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
79 T_CARET,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
80 T_AMP,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
81 T_LT,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
82 T_GT,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
83 T_PLUS,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
84 T_MINUS,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
85 T_STAR,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
86 T_SLASH,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
87 T_PCT,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
88 T_BANG,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
89 T_TILDE,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
90 };
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
91
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
92 static const struct {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
93 char c1, c2;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
94 enum tokens tok;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
95 } tokens_2[] = {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
96 { '|', '|', T_PIPEPIPE },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
97 { '&', '&', T_AMPAMP },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
98 { '=', '=', T_EQEQ },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
99 { '!', '=', T_BANGEQ },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
100 { '<', '=', T_LTEQ },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
101 { '>', '=', T_GTEQ },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
102 { '<', '<', T_LTLT },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
103 { '>', '>', T_GTGT },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
104 };
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
105 static const unsigned num_tokens_2 = HOWMANY(tokens_2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
106
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
107 static const struct {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
108 char c1;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
109 enum tokens tok;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
110 } tokens_1[] = {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
111 { '?', T_QUES },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
112 { ':', T_COLON },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
113 { '|', T_PIPE },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
114 { '^', T_CARET },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
115 { '&', T_AMP },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
116 { '<', T_LT },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
117 { '>', T_GT },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
118 { '+', T_PLUS },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
119 { '-', T_MINUS },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
120 { '*', T_STAR },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
121 { '/', T_SLASH },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
122 { '%', T_PCT },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
123 { '!', T_BANG },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
124 { '~', T_TILDE },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
125 { '(', T_LPAREN },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
126 { ')', T_RPAREN },
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
127 };
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
128 static const unsigned num_tokens_1 = HOWMANY(tokens_1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
129
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
130 struct token {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
131 struct place place;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
132 enum tokens tok;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
133 int val;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
134 };
107
33954a07d013 __unused -> UNUSED
David A. Holland
parents: 96
diff changeset
135 DECLARRAY(token, static UNUSED);
47
2e25e55dba6b Fix inline usage as per the version in dholland-make2.
David A. Holland
parents: 39
diff changeset
136 DEFARRAY(token, static);
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
137
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
138 static struct tokenarray tokens;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
139
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
140 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
141 struct token *
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
142 token_create(const struct place *p, enum tokens tok, int val)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
143 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
144 struct token *t;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
145
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
146 t = domalloc(sizeof(*t));
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
147 t->place = *p;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
148 t->tok = tok;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
149 t->val = val;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
150 return t;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
151 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
152
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
153 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
154 void
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
155 token_destroy(struct token *t)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
156 {
39
337110e7240a Pass the size to free; it makes debug checking easier.
David A. Holland
parents: 38
diff changeset
157 dofree(t, sizeof(*t));
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
158 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
159
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
160 DESTROYALL_ARRAY(token, );
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
161
92
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
162 #ifdef DEBUG
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
163 static
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
164 void
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
165 printtokens(void)
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
166 {
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
167 unsigned i, num;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
168 struct token *t;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
169
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
170 fprintf(stderr, "tokens:");
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
171 num = tokenarray_num(&tokens);
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
172 for (i=0; i<num; i++) {
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
173 t = tokenarray_get(&tokens, i);
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
174 switch (t->tok) {
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
175 case T_EOF: fprintf(stderr, " <eof>"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
176 case T_VAL: fprintf(stderr, " %d", t->val); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
177 case T_LPAREN: fprintf(stderr, " ("); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
178 case T_RPAREN: fprintf(stderr, " )"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
179 case T_PIPEPIPE: fprintf(stderr, " ||"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
180 case T_AMPAMP: fprintf(stderr, " &&"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
181 case T_EQEQ: fprintf(stderr, " =="); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
182 case T_BANGEQ: fprintf(stderr, " !="); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
183 case T_LTEQ: fprintf(stderr, " <="); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
184 case T_GTEQ: fprintf(stderr, " >="); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
185 case T_LTLT: fprintf(stderr, " <<"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
186 case T_GTGT: fprintf(stderr, " >>"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
187 case T_QUES: fprintf(stderr, " ?"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
188 case T_COLON: fprintf(stderr, " :"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
189 case T_PIPE: fprintf(stderr, " |"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
190 case T_CARET: fprintf(stderr, " ^"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
191 case T_AMP: fprintf(stderr, " &"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
192 case T_LT: fprintf(stderr, " <"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
193 case T_GT: fprintf(stderr, " >"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
194 case T_PLUS: fprintf(stderr, " +"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
195 case T_MINUS: fprintf(stderr, " -"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
196 case T_STAR: fprintf(stderr, " *"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
197 case T_SLASH: fprintf(stderr, " /"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
198 case T_PCT: fprintf(stderr, " %%"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
199 case T_BANG: fprintf(stderr, " !"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
200 case T_TILDE: fprintf(stderr, " ~"); break;
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
201 }
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
202 }
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
203 fprintf(stderr, "\n");
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
204 }
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
205 #endif
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
206
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
207 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
208 bool
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
209 isuop(enum tokens tok)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
210 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
211 switch (tok) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
212 case T_BANG:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
213 case T_TILDE:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
214 case T_MINUS:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
215 case T_PLUS:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
216 return true;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
217 default:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
218 break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
219 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
220 return false;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
221 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
222
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
223 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
224 bool
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
225 isbop(enum tokens tok)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
226 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
227 switch (tok) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
228 case T_EOF:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
229 case T_VAL:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
230 case T_LPAREN:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
231 case T_RPAREN:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
232 case T_COLON:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
233 case T_QUES:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
234 case T_BANG:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
235 case T_TILDE:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
236 return false;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
237 default:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
238 break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
239 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
240 return true;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
241 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
242
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
243 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
244 bool
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
245 isop(enum tokens tok)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
246 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
247 switch (tok) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
248 case T_EOF:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
249 case T_VAL:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
250 case T_LPAREN:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
251 case T_RPAREN:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
252 return false;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
253 default:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
254 break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
255 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
256 return true;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
257 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
258
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
259 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
260 int
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
261 getprec(enum tokens tok)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
262 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
263 switch (tok) {
92
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
264 case T_BANG: case T_TILDE: return -1;
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
265 case T_STAR: case T_SLASH: case T_PCT: return 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
266 case T_PLUS: case T_MINUS: return 1;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
267 case T_LTLT: case T_GTGT: return 2;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
268 case T_LT: case T_LTEQ: case T_GT: case T_GTEQ: return 3;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
269 case T_EQEQ: case T_BANGEQ: return 4;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
270 case T_AMP: return 5;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
271 case T_CARET: return 6;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
272 case T_PIPE: return 7;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
273 case T_AMPAMP: return 8;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
274 case T_PIPEPIPE: return 9;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
275 default: break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
276 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
277 return 10;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
278 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
279
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
280 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
281 bool
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
282 looser(enum tokens t1, enum tokens t2)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
283 {
92
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
284 return getprec(t1) >= getprec(t2);
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
285 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
286
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
287 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
288 int
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
289 eval_uop(enum tokens op, int val)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
290 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
291 switch (op) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
292 case T_BANG: val = !val; break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
293 case T_TILDE: val = (int)~(unsigned)val; break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
294 case T_MINUS: val = -val; break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
295 case T_PLUS: break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
296 default: assert(0); break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
297 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
298 return val;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
299 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
300
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
301 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
302 int
28
8a955e3dda2c two more tests, more fixes
David A. Holland
parents: 16
diff changeset
303 eval_bop(struct place *p, int lv, enum tokens op, int rv)
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
304 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
305 unsigned mask;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
306
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
307 switch (op) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
308 case T_PIPEPIPE: return lv || rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
309 case T_AMPAMP: return lv && rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
310 case T_PIPE: return (int)((unsigned)lv | (unsigned)rv);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
311 case T_CARET: return (int)((unsigned)lv ^ (unsigned)rv);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
312 case T_AMP: return (int)((unsigned)lv & (unsigned)rv);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
313 case T_EQEQ: return lv == rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
314 case T_BANGEQ: return lv != rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
315 case T_LT: return lv < rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
316 case T_GT: return lv > rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
317 case T_LTEQ: return lv <= rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
318 case T_GTEQ: return lv >= rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
319
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
320 case T_LTLT:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
321 case T_GTGT:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
322 if (rv < 0) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
323 complain(p, "Negative bit-shift");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
324 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
325 rv = 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
326 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
327 if ((unsigned)rv >= CHAR_BIT * sizeof(unsigned)) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
328 complain(p, "Bit-shift farther than type width");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
329 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
330 rv = 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
331 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
332 if (op == T_LTLT) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
333 return (int)((unsigned)lv << (unsigned)rv);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
334 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
335 mask = ((unsigned)-1) << (CHAR_BIT * sizeof(unsigned) - rv);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
336 lv = (int)(((unsigned)lv >> (unsigned)rv) | mask);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
337 return lv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
338
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
339 case T_MINUS:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
340 if (rv == INT_MIN) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
341 if (lv == INT_MIN) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
342 return 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
343 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
344 lv--;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
345 rv++;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
346 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
347 rv = -rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
348 /* FALLTHROUGH */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
349 case T_PLUS:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
350 if (rv > 0 && lv > (INT_MAX - rv)) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
351 complain(p, "Integer overflow");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
352 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
353 return INT_MAX;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
354 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
355 if (rv < 0 && lv < (INT_MIN - rv)) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
356 complain(p, "Integer underflow");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
357 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
358 return INT_MIN;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
359 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
360 return lv + rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
361
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
362 case T_STAR:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
363 if (rv == 0) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
364 return 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
365 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
366 if (rv == 1) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
367 return lv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
368 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
369 if (rv == -1 && lv == INT_MIN) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
370 lv++;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
371 lv = -lv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
372 if (lv == INT_MAX) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
373 complain(p, "Integer overflow");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
374 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
375 return INT_MAX;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
376 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
377 lv++;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
378 return lv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
379 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
380 if (lv == INT_MIN && rv < 0) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
381 complain(p, "Integer overflow");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
382 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
383 return INT_MAX;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
384 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
385 if (lv == INT_MIN && rv > 0) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
386 complain(p, "Integer underflow");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
387 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
388 return INT_MIN;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
389 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
390 if (rv < 0) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
391 rv = -rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
392 lv = -lv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
393 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
394 if (lv > 0 && lv > INT_MAX / rv) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
395 complain(p, "Integer overflow");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
396 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
397 return INT_MAX;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
398 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
399 if (lv < 0 && lv < INT_MIN / rv) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
400 complain(p, "Integer underflow");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
401 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
402 return INT_MIN;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
403 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
404 return lv * rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
405
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
406 case T_SLASH:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
407 if (rv == 0) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
408 complain(p, "Division by zero");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
409 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
410 return 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
411 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
412 return lv / rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
413
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
414 case T_PCT:
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
415 if (rv == 0) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
416 complain(p, "Modulus by zero");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
417 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
418 return 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
419 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
420 return lv % rv;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
421
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
422 default: assert(0); break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
423 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
424 return 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
425 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
426
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
427 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
428 void
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
429 tryreduce(void)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
430 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
431 unsigned num;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
432 struct token *t1, *t2, *t3, *t4, *t5, *t6;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
433
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
434 while (1) {
92
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
435 #ifdef DEBUG
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
436 printtokens();
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
437 #endif
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
438 num = tokenarray_num(&tokens);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
439 t1 = (num >= 1) ? tokenarray_get(&tokens, num-1) : NULL;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
440 t2 = (num >= 2) ? tokenarray_get(&tokens, num-2) : NULL;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
441 t3 = (num >= 3) ? tokenarray_get(&tokens, num-3) : NULL;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
442
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
443 if (num >= 3 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
444 t3->tok == T_LPAREN &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
445 t2->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
446 t1->tok == T_RPAREN) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
447 /* (x) -> x */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
448 t2->place = t3->place;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
449 token_destroy(t1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
450 token_destroy(t3);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
451 tokenarray_remove(&tokens, num-1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
452 tokenarray_remove(&tokens, num-3);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
453 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
454 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
455
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
456 if (num >= 2 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
457 (num == 2 || isop(t3->tok) || t3->tok == T_LPAREN) &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
458 isuop(t2->tok) &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
459 t1->tok == T_VAL) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
460 /* unary operator */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
461 t1->val = eval_uop(t2->tok, t1->val);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
462 t1->place = t2->place;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
463 token_destroy(t2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
464 tokenarray_remove(&tokens, num-2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
465 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
466 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
467 if (num >= 2 &&
92
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
468 (num == 2 || isop(t3->tok) || t3->tok == T_LPAREN) &&
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
469 t2->tok != T_LPAREN && t2->tok != T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
470 t1->tok == T_VAL) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
471 complain(&t2->place, "Invalid unary operator");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
472 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
473 token_destroy(t2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
474 tokenarray_remove(&tokens, num-2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
475 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
476 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
477
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
478
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
479 t4 = (num >= 4) ? tokenarray_get(&tokens, num-4) : NULL;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
480
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
481 if (num >= 4 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
482 t4->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
483 isbop(t3->tok) &&
92
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
484 t2->tok == T_VAL) {
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
485 /* binary operator */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
486 if (looser(t1->tok, t3->tok)) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
487 t4->val = eval_bop(&t3->place,
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
488 t4->val, t3->tok, t2->val);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
489 token_destroy(t2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
490 token_destroy(t3);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
491 tokenarray_remove(&tokens, num-2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
492 tokenarray_remove(&tokens, num-3);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
493 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
494 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
495 break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
496 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
497
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
498 t5 = (num >= 5) ? tokenarray_get(&tokens, num-5) : NULL;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
499 t6 = (num >= 6) ? tokenarray_get(&tokens, num-6) : NULL;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
500
91
bd1b7a09da89 Don't expect the eval result to contain EOF *then* a value.
David A. Holland
parents: 63
diff changeset
501 if (num >= 6 &&
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
502 t6->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
503 t5->tok == T_QUES &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
504 t4->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
505 t3->tok == T_COLON &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
506 t2->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
507 !isop(t1->tok)) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
508 /* conditional expression */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
509 t6->val = t6->val ? t4->val : t2->val;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
510 token_destroy(t2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
511 token_destroy(t3);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
512 token_destroy(t4);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
513 token_destroy(t5);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
514 tokenarray_remove(&tokens, num-2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
515 tokenarray_remove(&tokens, num-3);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
516 tokenarray_remove(&tokens, num-4);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
517 tokenarray_remove(&tokens, num-5);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
518 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
519 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
520
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
521 if (num >= 2 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
522 t2->tok == T_LPAREN &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
523 t1->tok == T_RPAREN) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
524 complain(&t1->place, "Value expected within ()");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
525 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
526 t1->tok = T_VAL;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
527 t1->val = 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
528 token_destroy(t1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
529 tokenarray_remove(&tokens, num-1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
530 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
531 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
532
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
533 if (num >= 2 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
534 t2->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
535 t1->tok == T_VAL) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
536 complain(&t1->place, "Operator expected");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
537 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
538 token_destroy(t1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
539 tokenarray_remove(&tokens, num-1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
540 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
541 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
542
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
543 if (num >= 2 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
544 isop(t2->tok) &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
545 t1->tok == T_EOF) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
546 complain(&t1->place, "Value expected after operator");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
547 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
548 token_destroy(t2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
549 tokenarray_remove(&tokens, num-2);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
550 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
551 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
552
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
553 if (num == 2 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
554 t2->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
555 t1->tok == T_RPAREN) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
556 complain(&t1->place, "Excess right parenthesis");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
557 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
558 token_destroy(t1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
559 tokenarray_remove(&tokens, num-1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
560 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
561 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
562
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
563 if (num == 3 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
564 t3->tok == T_LPAREN &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
565 t2->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
566 t1->tok == T_EOF) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
567 complain(&t1->place, "Unclosed left parenthesis");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
568 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
569 token_destroy(t3);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
570 tokenarray_remove(&tokens, num-3);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
571 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
572 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
573
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
574 if (num == 2 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
575 t2->tok == T_VAL &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
576 t1->tok == T_EOF) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
577 /* accepting state */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
578 break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
579 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
580
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
581 if (num >= 1 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
582 t1->tok == T_EOF) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
583 /* any other configuration at eof is an error */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
584 complain(&t1->place, "Parse error");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
585 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
586 break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
587 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
588
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
589 /* otherwise, wait for more input */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
590 break;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
591 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
592 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
593
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
594 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
595 void
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
596 token(struct place *p, enum tokens tok, int val)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
597 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
598 struct token *t;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
599
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
600 t = token_create(p, tok, val);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
601
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
602 tokenarray_add(&tokens, t, NULL);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
603 tryreduce();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
604 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
605
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
606 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
607 int
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
608 wordval(struct place *p, char *word)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
609 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
610 unsigned long val;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
611 char *t;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
612
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
613 if (word[0] >= '0' && word[0] <= '9') {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
614 errno = 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
615 val = strtoul(word, &t, 0);
96
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
616 if (errno) {
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
617 complain(p, "Invalid integer constant");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
618 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
619 return 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
620 }
96
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
621 while (*t == 'U' || *t == 'L') {
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
622 t++;
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
623 }
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
624 if (*t != '\0') {
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
625 complain(p, "Trailing garbage after integer constant");
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
626 complain_fail();
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
627 return 0;
408331be8792 Accept [UL]* after integer constants.
David A. Holland
parents: 92
diff changeset
628 }
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
629 if (val > INT_MAX) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
630 complain(p, "Integer constant too large");
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
631 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
632 return INT_MAX;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
633 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
634 return val;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
635 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
636
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
637 /* if it's a symbol, warn and substitute 0. */
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
638 if (warns.undef) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
639 complain(p, "Warning: value of undefined symbol %s is 0",
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
640 word);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
641 if (mode.werror) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
642 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
643 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
644 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
645 return 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
646 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
647
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
648 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
649 bool
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
650 check_word(struct place *p, char *expr, size_t pos, size_t *len_ret)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
651 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
652 size_t len;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
653 int val;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
654 char tmp;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
655
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
656 if (!strchr(alnum, expr[pos])) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
657 return false;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
658 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
659 len = strspn(expr + pos, alnum);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
660 tmp = expr[pos + len];
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
661 expr[pos + len] = '\0';
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
662 val = wordval(p, expr + pos);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
663 expr[pos + len] = tmp;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
664 token(p, T_VAL, val);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
665 *len_ret = len;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
666 return true;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
667 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
668
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
669 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
670 bool
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
671 check_tokens_2(struct place *p, char *expr, size_t pos)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
672 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
673 unsigned i;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
674
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
675 for (i=0; i<num_tokens_2; i++) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
676 if (expr[pos] == tokens_2[i].c1 &&
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
677 expr[pos+1] == tokens_2[i].c2) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
678 token(p, tokens_2[i].tok, 0);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
679 return true;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
680 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
681 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
682 return false;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
683 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
684
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
685 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
686 bool
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
687 check_tokens_1(struct place *p, char *expr, size_t pos)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
688 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
689 unsigned i;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
690
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
691 for (i=0; i<num_tokens_1; i++) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
692 if (expr[pos] == tokens_1[i].c1) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
693 token(p, tokens_1[i].tok, 0);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
694 return true;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
695 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
696 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
697 return false;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
698 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
699
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
700 static
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
701 void
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
702 tokenize(struct place *p, char *expr)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
703 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
704 size_t pos, len;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
705
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
706 pos = 0;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
707 while (expr[pos] != '\0') {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
708 len = strspn(expr+pos, ws);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
709 pos += len;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
710 p->column += len;
63
5e24746d8335 Assert on trailing whitespace.
David A. Holland
parents: 47
diff changeset
711 /* trailing whitespace is supposed to have been pruned */
5e24746d8335 Assert on trailing whitespace.
David A. Holland
parents: 47
diff changeset
712 assert(expr[pos] != '\0');
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
713 if (check_word(p, expr, pos, &len)) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
714 pos += len;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
715 p->column += len;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
716 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
717 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
718 if (check_tokens_2(p, expr, pos)) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
719 pos += 2;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
720 p->column += 2;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
721 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
722 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
723 if (check_tokens_1(p, expr, pos)) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
724 pos++;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
725 p->column++;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
726 continue;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
727 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
728 complain(p, "Invalid character %u in #if-expression",
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
729 (unsigned char)expr[pos]);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
730 complain_fail();
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
731 pos++;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
732 p->column++;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
733 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
734 token(p, T_EOF, 0);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
735 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
736
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
737 bool
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
738 eval(struct place *p, char *expr)
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
739 {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
740 struct token *t1, *t2;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
741 unsigned num;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
742 bool result;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
743
92
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
744 #ifdef DEBUG
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
745 fprintf(stderr, "eval: %s\n", expr);
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
746 #endif
b127a69061b2 fix some bugs.
David A. Holland
parents: 91
diff changeset
747
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
748 tokenarray_init(&tokens);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
749 tokenize(p, expr);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
750
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
751 result = false;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
752 num = tokenarray_num(&tokens);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
753 if (num == 2) {
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
754 t1 = tokenarray_get(&tokens, num-1);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
755 t2 = tokenarray_get(&tokens, num-2);
91
bd1b7a09da89 Don't expect the eval result to contain EOF *then* a value.
David A. Holland
parents: 63
diff changeset
756 if (t2->tok == T_VAL &&
bd1b7a09da89 Don't expect the eval result to contain EOF *then* a value.
David A. Holland
parents: 63
diff changeset
757 t1->tok == T_EOF) {
bd1b7a09da89 Don't expect the eval result to contain EOF *then* a value.
David A. Holland
parents: 63
diff changeset
758 result = t2->val != 0;
16
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
759 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
760 }
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
761
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
762 tokenarray_destroyall(&tokens);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
763 tokenarray_cleanup(&tokens);
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
764 return result;
9dda765ee85c expression evaluator
David A. Holland
parents:
diff changeset
765 }