annotate old-trunk/lwasm/old/expr.c @ 339:eb230fa7d28e

Prepare for migration to hg
author lost
date Fri, 19 Mar 2010 02:54:14 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
339
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
1 /*
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
2 expr.c
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
3 Copyright © 2008 William Astle
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
4
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
5 This file is part of LWASM.
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
6
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
7 LWASM is free software: you can redistribute it and/or modify it under the
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
8 terms of the GNU General Public License as published by the Free Software
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
9 Foundation, either version 3 of the License, or (at your option) any later
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
10 version.
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
11
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
12 This program is distributed in the hope that it will be useful, but WITHOUT
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
15 more details.
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
16
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
17 You should have received a copy of the GNU General Public License along with
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
18 this program. If not, see <http://www.gnu.org/licenses/>.
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
19 */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
20
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
21 /*
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
22 This file contains the actual expression evaluator
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
23 */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
24
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
25 #define __expr_c_seen__
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
26
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
27 #include <config.h>
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
28
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
29 #include <ctype.h>
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
30 #include <stdlib.h>
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
31 #include <string.h>
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
32
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
33 #include "expr.h"
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
34 #include "util.h"
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
35 #include "lwasm.h"
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
36
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
37 lwasm_expr_stack_t *lwasm_expr_stack_create(void)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
38 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
39 lwasm_expr_stack_t *s;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
40
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
41 s = lwasm_alloc(sizeof(lwasm_expr_stack_t));
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
42 s -> head = NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
43 s -> tail = NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
44 return s;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
45 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
46
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
47 void lwasm_expr_stack_free(lwasm_expr_stack_t *s)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
48 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
49 while (s -> head)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
50 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
51 s -> tail = s -> head;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
52 s -> head = s -> head -> next;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
53 lwasm_expr_term_free(s -> tail -> term);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
54 lwasm_free(s -> tail);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
55 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
56 lwasm_free(s);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
57 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
58
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
59 void lwasm_expr_term_free(lwasm_expr_term_t *t)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
60 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
61 if (t)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
62 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
63 if (t -> term_type == LWASM_TERM_SYM)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
64 lwasm_free(t -> symbol);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
65 lwasm_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
66 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
67 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
68
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
69 lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
70 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
71 lwasm_expr_term_t *t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
72
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
73 debug_message(10, "Creating operator term: %d", oper);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
74
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
75 t = lwasm_alloc(sizeof(lwasm_expr_term_t));
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
76 t -> term_type = LWASM_TERM_OPER;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
77 t -> value = oper;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
78 return t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
79 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
80
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
81 lwasm_expr_term_t *lwasm_expr_term_create_int(int val)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
82 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
83 lwasm_expr_term_t *t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
84 debug_message(10, "Creating integer term: %d", val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
85
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
86 t = lwasm_alloc(sizeof(lwasm_expr_term_t));
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
87 t -> term_type = LWASM_TERM_INT;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
88 t -> value = val;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
89 return t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
90 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
91
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
92 lwasm_expr_term_t *lwasm_expr_term_create_secbase(void)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
93 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
94 lwasm_expr_term_t *t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
95 debug_message(10, "Creating section base term");
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
96
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
97 t = lwasm_alloc(sizeof(lwasm_expr_term_t));
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
98 t -> term_type = LWASM_TERM_SECBASE;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
99 return t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
100 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
101
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
102 lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
103 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
104 lwasm_expr_term_t *t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
105
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
106 debug_message(10, "Creating symbol term: %s", sym);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
107
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
108 t = lwasm_alloc(sizeof(lwasm_expr_term_t));
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
109 t -> term_type = LWASM_TERM_SYM;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
110 t -> symbol = lwasm_strdup(sym);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
111 return t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
112 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
113
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
114 lwasm_expr_term_t *lwasm_expr_term_dup(lwasm_expr_term_t *t)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
115 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
116 switch (t -> term_type)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
117 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
118 case LWASM_TERM_INT:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
119 return lwasm_expr_term_create_int(t -> value);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
120
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
121 case LWASM_TERM_OPER:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
122 return lwasm_expr_term_create_oper(t -> value);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
123
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
124 case LWASM_TERM_SYM:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
125 return lwasm_expr_term_create_sym(t -> symbol);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
126
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
127 case LWASM_TERM_SECBASE:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
128 return lwasm_expr_term_create_secbase();
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
129
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
130 default:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
131 debug_message(0, "lwasm_expr_term_dup(): invalid term type %d", t -> term_type);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
132 exit(1);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
133 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
134 // can't get here
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
135 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
136
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
137 void lwasm_expr_stack_push(lwasm_expr_stack_t *s, lwasm_expr_term_t *t)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
138 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
139 lwasm_expr_stack_node_t *n;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
140
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
141 if (!s)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
142 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
143 debug_message(0, "lwasm_expr_stack_push(): invalid stack pointer");
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
144 exit(1);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
145 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
146
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
147 n = lwasm_alloc(sizeof(lwasm_expr_stack_node_t));
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
148 n -> next = NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
149 n -> prev = s -> tail;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
150 n -> term = lwasm_expr_term_dup(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
151
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
152 if (s -> head)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
153 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
154 s -> tail -> next = n;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
155 s -> tail = n;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
156 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
157 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
158 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
159 s -> head = n;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
160 s -> tail = n;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
161 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
162 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
163
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
164 lwasm_expr_term_t *lwasm_expr_stack_pop(lwasm_expr_stack_t *s)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
165 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
166 lwasm_expr_term_t *t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
167 lwasm_expr_stack_node_t *n;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
168
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
169 if (!(s -> tail))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
170 return NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
171
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
172 n = s -> tail;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
173 s -> tail = n -> prev;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
174 if (!(n -> prev))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
175 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
176 s -> head = NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
177 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
178
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
179 t = n -> term;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
180 n -> term = NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
181
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
182 lwasm_free(n);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
183
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
184 return t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
185 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
186
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
187 // the following two functions are co-routines which actually parse
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
188 // an infix expression onto the expression stack, each returns -1
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
189 // if an error is encountered
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
190
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
191 /*
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
192 parse a term and push it onto the stack
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
193
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
194 this function handles unary prefix operators (-, +, .not., .com.)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
195 as well as ()
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
196 */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
197 int lwasm_expr_parse_term(lwasm_expr_stack_t *s, const char **p)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
198 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
199 lwasm_expr_term_t *t;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
200 debug_message(2, "Expression string %s", *p);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
201
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
202 eval_next:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
203 if (!**p || isspace(**p) || **p == ')' || **p == ']')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
204 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
205 if (**p == '(')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
206 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
207 debug_message(3, "Starting paren");
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
208 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
209 lwasm_expr_parse_expr(s, p, 0);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
210 if (**p != ')')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
211 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
212 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
213 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
214 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
215
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
216 if (**p == '+')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
217 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
218 debug_message(3, "Unary +");
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
219 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
220 goto eval_next;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
221 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
222
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
223 if (**p == '-')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
224 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
225 // parse expression following "-"
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
226 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
227 if (lwasm_expr_parse_expr(s, p, 200) < 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
228 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
229 t = lwasm_expr_term_create_oper(LWASM_OPER_NEG);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
230 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
231 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
232 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
233 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
234
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
235 if (**p == '^' || **p == '~')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
236 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
237 // parse expression following "^"
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
238 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
239 if (lwasm_expr_parse_expr(s, p, 200) < 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
240 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
241 t = lwasm_expr_term_create_oper(LWASM_OPER_COM);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
242 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
243 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
244 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
245 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
246
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
247 /*
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
248 we have an actual term here so evaluate it
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
249
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
250 it could be one of the following:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
251
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
252 1. a decimal constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
253 2. a hexadecimal constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
254 3. an octal constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
255 4. a binary constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
256 5. a symbol reference
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
257 6. the "current" instruction address (*)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
258 7. the "current" data address (.)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
259 8. a "back reference" (<)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
260 9. a "forward reference" (>)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
261
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
262 items 6 through 9 are stored as symbol references
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
263
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
264 (a . followed by a . or a alpha char or number is a symbol)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
265 */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
266 if (**p == '*'
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
267 || (
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
268 **p == '.'
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
269 && (*p)[1] != '.'
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
270 && !((*p)[1] >= 'A' && (*p)[1] <= 'Z')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
271 && !((*p)[1] >= 'a' && (*p)[1] <= 'z')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
272 && !((*p)[1] >= '0' && (*p)[1] <= '9')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
273 )
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
274 || **p == '<'
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
275 || **p == '>')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
276 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
277 char tstr[2];
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
278 tstr[0] = **p;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
279 tstr[1] = '\0';
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
280 t = lwasm_expr_term_create_sym(tstr);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
281 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
282 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
283 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
284 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
285 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
286
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
287 /*
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
288 - a symbol will be a string of characters introduced by a letter, ".",
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
289 "_" but NOT a number OR it may start with a digit if it contains a $
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
290 - a decimal constant will consist of only digits, optionally prefixed
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
291 with "&"
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
292 - a binary constant will consist of only 0s and 1s either prefixed with %
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
293 or suffixed with "B"
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
294 - a hex constant will consist of 0-9A-F either prefixed with $ or
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
295 suffixed with "H"; a hex number starting with A-F must be prefixed
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
296 with $ or start with 0 and end with H
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
297 - an octal constant will consist of 0-7 either prefixed with @ or
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
298 suffixed with "O" or "Q"
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
299 - an ascii constant will be a single character prefixed with a '
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
300 - a double ascii constant will be two characters prefixed with a "
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
301
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
302 */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
303 if (**p == '"')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
304 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
305 // double ascii constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
306 int val;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
307 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
308 if (!**p)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
309 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
310 if (!*((*p)+1))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
311 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
312 val = **p << 8 | *((*p) + 1);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
313 (*p) += 2;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
314 t = lwasm_expr_term_create_int(val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
315 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
316 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
317 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
318 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
319 else if (**p == '\'')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
320 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
321 // single ascii constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
322 int val;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
323 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
324 debug_message(3, "Single ascii character constant '%c'", **p);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
325 if (!**p)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
326 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
327 val = **p;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
328 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
329 t = lwasm_expr_term_create_int(val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
330 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
331 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
332 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
333 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
334 else if (**p == '&')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
335 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
336 // decimal constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
337 int val = 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
338
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
339 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
340 while (**p && strchr("0123456789", **p))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
341 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
342 val = val * 10 + (**p - '0');
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
343 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
344 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
345 t = lwasm_expr_term_create_int(val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
346 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
347 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
348 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
349 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
350 else if (**p == '%')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
351 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
352 // binary constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
353 int val = 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
354
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
355 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
356 while (**p == '0' || **p == '1')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
357 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
358 val = val * 2 + (**p - '0');
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
359 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
360 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
361 t = lwasm_expr_term_create_int(val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
362 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
363 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
364 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
365 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
366 else if (**p == '$')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
367 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
368 // hexadecimal constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
369 int val = 0, val2;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
370
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
371 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
372 debug_message(3, "Found prefix hex constant: %s", *p);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
373 while (**p && strchr("0123456789ABCDEFabcdef", **p))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
374 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
375 val2 = toupper(**p) - '0';
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
376 if (val2 > 9)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
377 val2 -= 7;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
378 debug_message(3, "Got char: %c (%d)", **p, val2);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
379 val = val * 16 + val2;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
380 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
381 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
382 t = lwasm_expr_term_create_int(val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
383 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
384 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
385 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
386 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
387 else if (**p == '0' && tolower(*(*p + 1)) == 'x')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
388 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
389 // "C" style hexadecimal constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
390 int val = 0, val2;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
391
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
392 (*p)+=2;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
393 debug_message(3, "Found \"C\" style prefix hex constant: %s", *p);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
394 while (**p && strchr("0123456789ABCDEFabcdef", **p))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
395 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
396 val2 = toupper(**p) - '0';
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
397 if (val2 > 9)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
398 val2 -= 7;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
399 debug_message(3, "Got char: %c (%d)", **p, val2);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
400 val = val * 16 + val2;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
401 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
402 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
403 t = lwasm_expr_term_create_int(val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
404 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
405 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
406 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
407 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
408 // an @ followed by a digit is an octal number
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
409 // but if it's followed by anything else, it is a symbol
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
410 else if (**p == '@' && isdigit(*(*p + 1)))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
411 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
412 // octal constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
413 int val = 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
414
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
415 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
416 while (**p && strchr("01234567", **p))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
417 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
418 val = val * 8 + (**p - '0');
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
419 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
420 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
421 t = lwasm_expr_term_create_int(val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
422 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
423 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
424 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
425 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
426
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
427 // symbol or bare decimal or suffix identified constant here
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
428
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
429 // find the end of a potential symbol
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
430 do
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
431 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
432 int l = 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
433 char *sb;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
434 int havedol = 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
435
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
436 // evaluate a symbol here
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
437 static const char *symchars = "_.$@?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
438 while ((*p)[l] && strchr(symchars, (*p)[l]))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
439 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
440 if ((*p)[l] == '$')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
441 havedol = 1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
442 l++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
443 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
444 if (l == 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
445 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
446
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
447 if (havedol || **p < '0' || **p > '9')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
448 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
449 // have a symbol here
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
450
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
451 sb = lwasm_alloc(l + 1);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
452 sb[l] = '\0';
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
453 memcpy(sb, *p, l);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
454 t = lwasm_expr_term_create_sym(sb);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
455 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
456 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
457 (*p) += l;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
458 debug_message(3, "Symbol: '%s'; (%s)", sb, *p);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
459 lwasm_free(sb);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
460 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
461 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
462 } while (0);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
463
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
464 if (!**p)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
465 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
466
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
467 // evaluate a suffix based constant
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
468 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
469 int decval = 0, binval = 0, hexval = 0, octval = 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
470 int valtype = 15; // 1 = bin, 2 = oct, 4 = dec, 8 = hex
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
471 int bindone = 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
472 int val;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
473 int dval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
474
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
475 while (1)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
476 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
477 if (!**p || !strchr("0123456789ABCDEFabcdefqhoQHO", **p))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
478 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
479 // we can legally have bin or decimal here
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
480 if (bindone)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
481 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
482 // we just finished a binary value
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
483 val = binval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
484 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
485 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
486 else if (valtype & 4)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
487 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
488 // otherwise we must be decimal (if we're still allowed one)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
489 val = decval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
490 debug_message(3, "End of decimal value");
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
491 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
492 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
493 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
494 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
495 // bad value
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
496 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
497 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
498 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
499
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
500 dval = toupper(**p);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
501 (*p)++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
502
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
503 if (bindone)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
504 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
505 // any characters past "B" means it is not binary
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
506 bindone = 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
507 valtype &= 14;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
508 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
509
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
510 switch (dval)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
511 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
512 case 'Q':
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
513 case 'O':
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
514 if (valtype & 2)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
515 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
516 val = octval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
517 valtype = -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
518 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
519 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
520 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
521 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
522 // not a valid octal value
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
523 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
524 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
525 /* can't get here */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
526
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
527 case 'H':
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
528 if (valtype & 8)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
529 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
530 val = hexval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
531 valtype = -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
532 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
533 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
534 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
535 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
536 // not a valid hex number
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
537 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
538 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
539 /* can't get here */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
540
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
541 case 'B':
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
542 // this is a bit of a sticky one since B is a legit hex
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
543 // digit so this may or may not be the end of the number
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
544 // so we fall through to the digit case
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
545
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
546 if (valtype & 1)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
547 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
548 // could still be binary
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
549 bindone = 1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
550 valtype = 9; // hex and binary
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
551 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
552 /* fall through intentional */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
553
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
554 default:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
555 // digit
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
556 dval -= '0';
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
557 if (dval > 9)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
558 dval -= 7;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
559 debug_message(3, "Got digit: %d", dval);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
560 // if (dval > 1)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
561 // valtype &= 14;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
562 // if (dval > 7)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
563 // valtype &= 12;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
564 // if (dval > 9)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
565 // valtype &= 8;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
566
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
567 if (valtype & 8)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
568 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
569 hexval = hexval * 16 + dval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
570 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
571 if (valtype & 4)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
572 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
573 if (dval > 9)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
574 valtype &= 11;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
575 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
576 decval = decval * 10 + dval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
577 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
578 if (valtype & 2)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
579 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
580 if (dval > 7)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
581 valtype &= 13;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
582 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
583 octval = octval * 8 + dval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
584 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
585 if (valtype & 1)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
586 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
587 if (dval > 1)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
588 valtype &= 14;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
589 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
590 binval = binval * 2 + dval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
591 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
592 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
593 // break out if we have a return value
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
594 if (valtype == -1)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
595 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
596 // return if no more valid possibilities!
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
597 if (valtype == 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
598 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
599 val = decval; // in case we fall through
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
600 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
601
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
602 // we get here when we have a value to return
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
603 t = lwasm_expr_term_create_int(val);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
604 lwasm_expr_stack_push(s, t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
605 lwasm_expr_term_free(t);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
606 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
607 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
608 /* can't get here */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
609 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
610
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
611 // parse an expression and push the result onto the stack
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
612 // if an operator of lower precedence than the value of "prec" is found,
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
613 int lwasm_expr_parse_expr(lwasm_expr_stack_t *s, const char **p, int prec)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
614 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
615 static const struct operinfo
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
616 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
617 int opernum;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
618 char *operstr;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
619 int operprec;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
620 } operators[] =
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
621 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
622 { LWASM_OPER_PLUS, "+", 100 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
623 { LWASM_OPER_MINUS, "-", 100 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
624 { LWASM_OPER_TIMES, "*", 150 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
625 { LWASM_OPER_DIVIDE, "/", 150 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
626 { LWASM_OPER_MOD, "%", 150 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
627 { LWASM_OPER_INTDIV, "\\", 150 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
628
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
629 // boolean AND/OR
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
630 { LWASM_OPER_AND, "&&", 25 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
631 { LWASM_OPER_OR, "||", 25 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
632
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
633 // bitwise ops
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
634 { LWASM_OPER_BWAND, "&", 50 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
635 { LWASM_OPER_BWOR, "|", 50 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
636
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
637 // this collides with the unary complement but shouldn't cause
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
638 // any trouble because of operator precedence
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
639 { LWASM_OPER_BWXOR, "^", 50 },
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
640
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
641 { LWASM_OPER_NONE, "", 0 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
642 };
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
643 int opern, i;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
644 lwasm_expr_term_t *operterm;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
645
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
646 // return if we are at the end of the expression or a subexpression
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
647 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
648 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
649
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
650 if (lwasm_expr_parse_term(s, p) < 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
651 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
652
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
653 eval_next:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
654 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
655 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
656
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
657 // expecting an operator here
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
658 for (opern = 0; operators[opern].opernum != LWASM_OPER_NONE; opern++)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
659 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
660 for (i = 0; (*p)[i] && operators[opern].operstr[i] && ((*p)[i] == operators[opern].operstr[i]); i++)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
661 /* do nothing */ ;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
662 if (operators[opern].operstr[i] == '\0')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
663 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
664 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
665 if (operators[opern].opernum == LWASM_OPER_NONE)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
666 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
667 // unrecognized operator
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
668 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
669 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
670
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
671 // the operator number in question is in opern; i is the length of the
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
672 // operator string
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
673
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
674 // logic:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
675 // if the precedence of this operation is <= to the "prec" flag,
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
676 // we simply return without advancing the input pointer; the operator
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
677 // will be evaluated again in the enclosing function call
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
678 if (operators[opern].operprec <= prec)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
679 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
680
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
681 // logic:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
682 // we have a higher precedence operator here so we will advance the
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
683 // input pointer to the next term and let the expression evaluator
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
684 // loose on it after which time we will push our operator onto the
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
685 // stack and then go on with the expression evaluation
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
686 (*p) += i; // advance input pointer
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
687
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
688 // evaluate next expression(s) of higher precedence
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
689 if (lwasm_expr_parse_expr(s, p, operators[opern].operprec) < 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
690 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
691
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
692 operterm = lwasm_expr_term_create_oper(operators[opern].opernum);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
693 lwasm_expr_stack_push(s, operterm);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
694 lwasm_expr_term_free(operterm);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
695
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
696 // return if we are at the end of the expression or a subexpression
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
697 if (!**p || isspace(**p) || **p == ')')
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
698 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
699
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
700 // continue evaluating
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
701 goto eval_next;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
702 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
703
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
704 /*
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
705 actually evaluate an expression
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
706
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
707 This happens in two stages. The first stage merely parses the expression into
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
708 a lwasm_expr_stack_t * which is then evaluated as much as possible before the
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
709 result is returned.
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
710
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
711 Returns NULL on a parse error or otherwise invalid expression. *outp will
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
712 contain the pointer to the next character after the expression if and only
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
713 if there is no error. In the case of an error, *outp is undefined.
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
714 */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
715 lwasm_expr_stack_t *lwasm_expr_eval(const char *inp, const char **outp, lwasm_expr_stack_t *(*sfunc)(char *sym, void *state), void *state)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
716 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
717 lwasm_expr_stack_t *s;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
718 const char *p;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
719 int rval;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
720
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
721 // actually parse the expression
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
722 p = inp;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
723 s = lwasm_expr_stack_create();
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
724
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
725 rval = lwasm_expr_parse_expr(s, &p, 0);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
726 if (rval < 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
727 goto cleanup_error;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
728
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
729 // save end of expression
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
730 if (outp)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
731 (*outp) = p;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
732
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
733 // return potentially partial expression
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
734 if (lwasm_expr_reval(s, sfunc, state) < 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
735 goto cleanup_error;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
736
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
737 if (lwasm_expr_is_constant(s))
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
738 debug_message(3, "Constant expression evaluates to: %d", lwasm_expr_get_value(s));
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
739
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
740 return s;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
741
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
742 cleanup_error:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
743 lwasm_expr_stack_free(s);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
744 return NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
745 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
746
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
747 /*
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
748 take an expression stack s and scan for operations that can be completed
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
749
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
750 return -1 on error, 0 on no error
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
751
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
752 possible errors are: division by zero or unknown operator
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
753
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
754 theory of operation:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
755
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
756 scan the stack for an operator which has two constants preceding it (binary)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
757 or 1 constant preceding it (unary) and if found, perform the calculation
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
758 and replace the operator and its operands with the result
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
759
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
760 repeat the scan until no futher simplications are found or if there are no
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
761 further operators or only a single term remains
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
762
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
763 */
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
764 int lwasm_expr_reval(lwasm_expr_stack_t *s, lwasm_expr_stack_t *(*sfunc)(char *sym, void *state), void *state)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
765 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
766 lwasm_expr_stack_node_t *n, *n2;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
767 lwasm_expr_stack_t *ss;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
768 int c;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
769
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
770 next_iter_sym:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
771 // resolve symbols
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
772 // symbols that do not resolve to an expression are left alone
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
773 for (c = 0, n = s -> head; n; n = n -> next)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
774 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
775 if (n -> term -> term_type == LWASM_TERM_SYM)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
776 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
777 ss = sfunc(n -> term -> symbol, state);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
778 if (ss)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
779 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
780 c++;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
781 // splice in the result stack
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
782 if (n -> prev)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
783 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
784 n -> prev -> next = ss -> head;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
785 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
786 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
787 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
788 s -> head = ss -> head;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
789 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
790 ss -> head -> prev = n -> prev;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
791 ss -> tail -> next = n -> next;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
792 if (n -> next)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
793 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
794 n -> next -> prev = ss -> tail;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
795 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
796 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
797 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
798 s -> tail = ss -> tail;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
799 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
800 lwasm_expr_term_free(n -> term);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
801 lwasm_free(n);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
802 n = ss -> tail;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
803
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
804 ss -> head = NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
805 ss -> tail = NULL;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
806 lwasm_expr_stack_free(ss);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
807 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
808 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
809 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
810 if (c)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
811 goto next_iter_sym;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
812
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
813 next_iter:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
814 // a single term
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
815 if (s -> head == s -> tail)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
816 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
817
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
818 // search for an operator
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
819 for (n = s -> head; n; n = n -> next)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
820 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
821 if (n -> term -> term_type == LWASM_TERM_OPER)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
822 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
823 if (n -> term -> value == LWASM_OPER_NEG
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
824 || n -> term -> value == LWASM_OPER_COM
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
825 )
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
826 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
827 // unary operator
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
828 if (n -> prev && n -> prev -> term -> term_type == LWASM_TERM_INT)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
829 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
830 // a unary operator we can resolve
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
831 // we do the op then remove the term "n" is pointing at
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
832 if (n -> term -> value == LWASM_OPER_NEG)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
833 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
834 n -> prev -> term -> value = -(n -> prev -> term -> value);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
835 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
836 else if (n -> term -> value == LWASM_OPER_COM)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
837 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
838 n -> prev -> term -> value = ~(n -> prev -> term -> value);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
839 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
840 n -> prev -> next = n -> next;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
841 if (n -> next)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
842 n -> next -> prev = n -> prev;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
843 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
844 s -> tail = n -> prev;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
845
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
846 lwasm_expr_term_free(n -> term);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
847 lwasm_free(n);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
848 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
849 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
850 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
851 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
852 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
853 // binary operator
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
854 if (n -> prev && n -> prev -> prev && n -> prev -> term -> term_type == LWASM_TERM_INT && n -> prev -> prev -> term -> term_type == LWASM_TERM_INT)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
855 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
856 // a binary operator we can resolve
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
857 switch (n -> term -> value)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
858 {
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
859 case LWASM_OPER_PLUS:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
860 n -> prev -> prev -> term -> value += n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
861 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
862
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
863 case LWASM_OPER_MINUS:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
864 n -> prev -> prev -> term -> value -= n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
865 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
866
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
867 case LWASM_OPER_TIMES:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
868 n -> prev -> prev -> term -> value *= n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
869 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
870
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
871 case LWASM_OPER_DIVIDE:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
872 if (n -> prev -> term -> value == 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
873 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
874 n -> prev -> prev -> term -> value /= n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
875 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
876
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
877 case LWASM_OPER_MOD:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
878 if (n -> prev -> term -> value == 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
879 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
880 n -> prev -> prev -> term -> value %= n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
881 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
882
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
883 case LWASM_OPER_INTDIV:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
884 if (n -> prev -> term -> value == 0)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
885 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
886 n -> prev -> prev -> term -> value /= n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
887 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
888
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
889 case LWASM_OPER_BWAND:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
890 n -> prev -> prev -> term -> value &= n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
891 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
892
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
893 case LWASM_OPER_BWOR:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
894 n -> prev -> prev -> term -> value |= n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
895 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
896
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
897 case LWASM_OPER_BWXOR:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
898 n -> prev -> prev -> term -> value ^= n -> prev -> term -> value;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
899 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
900
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
901 case LWASM_OPER_AND:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
902 n -> prev -> prev -> term -> value = (n -> prev -> term -> value && n -> prev -> prev -> term -> value) ? 1 : 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
903 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
904
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
905 case LWASM_OPER_OR:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
906 n -> prev -> prev -> term -> value = (n -> prev -> term -> value || n -> prev -> prev -> term -> value) ? 1 : 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
907 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
908
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
909 default:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
910 // return error if unknown operator!
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
911 return -1;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
912 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
913
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
914 // now remove the two unneeded entries from the stack
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
915 n -> prev -> prev -> next = n -> next;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
916 if (n -> next)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
917 n -> next -> prev = n -> prev -> prev;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
918 else
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
919 s -> tail = n -> prev -> prev;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
920
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
921 lwasm_expr_term_free(n -> term);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
922 lwasm_expr_term_free(n -> prev -> term);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
923 lwasm_free(n -> prev);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
924 lwasm_free(n);
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
925 break;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
926 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
927 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
928 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
929 }
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
930 // note for the terminally confused about dynamic memory and pointers:
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
931 // n will not be NULL even after the lwasm_free calls above so
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
932 // this test will still work (n will be a dangling pointer)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
933 // (n will only be NULL if we didn't find any operators to simplify)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
934 if (n)
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
935 goto next_iter;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
936
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
937 return 0;
eb230fa7d28e Prepare for migration to hg
lost
parents:
diff changeset
938 }