annotate src/expr.c @ 159:71561c12b20b

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