annotate lwasm/expr.c @ 205:42df94f30d82

checkpoint
author lost
date Sun, 19 Apr 2009 17:44:46 +0000
parents 2c1afbdb2de0
children bae1e3ecdce1
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
191
29ba546ceea0 Added ~ prefix operator (1s complement)
lost
parents: 170
diff changeset
233 if (**p == '^' || **p == '~')
23
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, ".",
194
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
287 "_" but NOT a number OR it may start with a digit if it contains a $
18
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 }
170
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
385 else if (**p == '0' && tolower(*(*p + 1)) == 'x')
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
386 {
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
387 // "C" style hexadecimal constant
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
388 int val = 0, val2;
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
389
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
390 (*p)+=2;
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
391 debug_message(3, "Found \"C\" style prefix hex constant: %s", *p);
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
392 while (**p && strchr("0123456789ABCDEFabcdef", **p))
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
393 {
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
394 val2 = toupper(**p) - '0';
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
395 if (val2 > 9)
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
396 val2 -= 7;
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
397 debug_message(3, "Got char: %c (%d)", **p, val2);
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
398 val = val * 16 + val2;
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
399 (*p)++;
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
400 }
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
401 t = lwasm_expr_term_create_int(val);
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
402 lwasm_expr_stack_push(s, t);
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
403 lwasm_expr_term_free(t);
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
404 return 0;
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
405 }
40
d2cee0c335e7 adjusted symbol rules to accept symbols starting with @ but not @<digit>
lost
parents: 39
diff changeset
406 // 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
407 // 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
408 else if (**p == '@' && isdigit(*(*p + 1)))
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
409 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
410 // octal constant
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
411 int val = 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
412
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
413 (*p)++;
47
804d7465e0f9 Implemented ORG and fixed problems with constants using $, &, or @ to specify base
lost
parents: 44
diff changeset
414 while (**p && strchr("01234567", **p))
18
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 val = val * 8 + (**p - '0');
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
417 (*p)++;
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 t = lwasm_expr_term_create_int(val);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
420 lwasm_expr_stack_push(s, t);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
421 lwasm_expr_term_free(t);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
422 return 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
423 }
170
bf69160da467 Added ability to use 0x and 0X as prefixes for hexadecimal numbers
lost
parents: 151
diff changeset
424
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
425 // symbol or bare decimal or suffix identified constant here
194
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
426
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
427 // find the end of a potential symbol
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
428 do
18
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 int l = 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
431 char *sb;
194
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
432 int havedol = 0;
18
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 symbol here
41
7eafdb3a8074 Fixed symbol parsing to prevent string overflow
lost
parents: 40
diff changeset
435 static const char *symchars = "_.$@?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
7eafdb3a8074 Fixed symbol parsing to prevent string overflow
lost
parents: 40
diff changeset
436 while ((*p)[l] && strchr(symchars, (*p)[l]))
194
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
437 {
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
438 if ((*p)[l] == '$')
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
439 havedol = 1;
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
440 l++;
194
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
441 }
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
442 if (l == 0)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
443 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
444
194
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
445 if (havedol || **p < '0' || **p > '9')
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
446 {
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
447 // have a symbol here
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
448
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
449 sb = lwasm_alloc(l + 1);
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
450 sb[l] = '\0';
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
451 memcpy(sb, *p, l);
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
452 t = lwasm_expr_term_create_sym(sb);
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
453 lwasm_expr_stack_push(s, t);
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
454 lwasm_expr_term_free(t);
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
455 (*p) += l;
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
456 debug_message(3, "Symbol: '%s'; (%s)", sb, *p);
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
457 lwasm_free(sb);
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
458 return 0;
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
459 }
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
460 } while (0);
0d916bcebb90 First pass at allowing symbols starting with digits but containing $
lost
parents: 191
diff changeset
461
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
462 if (!**p)
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 // evaluate a suffix based constant
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 int decval = 0, binval = 0, hexval = 0, octval = 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
468 int valtype = 15; // 1 = bin, 2 = oct, 4 = dec, 8 = hex
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
469 int bindone = 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
470 int val;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
471 int dval;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
472
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
473 while (1)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
474 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
475 if (!**p || !strchr("0123456789ABCDEFabcdefqhoQHO", **p))
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 // we can legally have bin or decimal here
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
478 if (bindone)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
479 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
480 // we just finished a binary value
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
481 val = binval;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
482 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
483 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
484 else if (valtype & 4)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
485 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
486 // otherwise we must be decimal (if we're still allowed one)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
487 val = decval;
39
efa19ec69df9 tweaked debugging system for expression handler
lost
parents: 37
diff changeset
488 debug_message(3, "End of decimal value");
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
489 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
490 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
491 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
492 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
493 // bad value
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
494 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
495 }
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
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
498 dval = toupper(**p);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
499 (*p)++;
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 if (bindone)
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 // any characters past "B" means it is not binary
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
504 bindone = 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
505 valtype &= 14;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
506 }
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 switch (dval)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
509 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
510 case 'Q':
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
511 case 'O':
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
512 if (valtype & 2)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
513 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
514 val = octval;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
515 valtype = -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
516 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
517 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
518 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
519 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
520 // not a valid octal value
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
521 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
522 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
523 /* can't get here */
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
524
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
525 case 'H':
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
526 if (valtype & 8)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
527 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
528 val = hexval;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
529 valtype = -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
530 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
531 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
532 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
533 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
534 // not a valid hex number
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
535 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
536 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
537 /* can't get here */
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
538
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
539 case 'B':
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
540 // 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
541 // 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
542 // so we fall through to the digit case
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
543
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
544 if (valtype & 1)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
545 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
546 // could still be binary
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
547 bindone = 1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
548 valtype = 9; // hex and binary
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
549 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
550 /* fall through intentional */
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 default:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
553 // digit
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
554 dval -= '0';
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
555 if (dval > 9)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
556 dval -= 7;
39
efa19ec69df9 tweaked debugging system for expression handler
lost
parents: 37
diff changeset
557 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
558 // if (dval > 1)
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
559 // valtype &= 14;
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
560 // if (dval > 7)
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
561 // valtype &= 12;
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
562 // if (dval > 9)
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
563 // valtype &= 8;
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
564
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
565 if (valtype & 8)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
566 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
567 hexval = hexval * 16 + dval;
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 if (valtype & 4)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
570 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
571 if (dval > 9)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
572 valtype &= 11;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
573 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
574 decval = decval * 10 + dval;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
575 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
576 if (valtype & 2)
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 if (dval > 7)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
579 valtype &= 13;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
580 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
581 octval = octval * 8 + dval;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
582 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
583 if (valtype & 1)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
584 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
585 if (dval > 1)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
586 valtype &= 14;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
587 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
588 binval = binval * 2 + dval;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
589 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
590 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
591 // 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
592 if (valtype == -1)
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
593 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
594 // return if no more valid possibilities!
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
595 if (valtype == 0)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
596 return -1;
37
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
597 val = decval; // in case we fall through
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
598 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
599
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
600 // we get here when we have a value to return
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
601 t = lwasm_expr_term_create_int(val);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
602 lwasm_expr_stack_push(s, t);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
603 lwasm_expr_term_free(t);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
604 return 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
605 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
606 /* can't get here */
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
607 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
608
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
609 // parse an expression and push the result onto the stack
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
610 // 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
611 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
612 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
613 static const struct operinfo
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 int opernum;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
616 char *operstr;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
617 int operprec;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
618 } operators[] =
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 { LWASM_OPER_PLUS, "+", 100 },
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
621 { LWASM_OPER_MINUS, "-", 100 },
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
622 { LWASM_OPER_TIMES, "*", 150 },
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
623 { LWASM_OPER_DIVIDE, "/", 150 },
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
624 { LWASM_OPER_MOD, "%", 150 },
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
625 { LWASM_OPER_INTDIV, "\\", 150 },
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
626
203
2c1afbdb2de0 Added |, &, and ^ binary bitwise operators
lost
parents: 194
diff changeset
627 { LWASM_OPER_BWAND, "&", 50 },
2c1afbdb2de0 Added |, &, and ^ binary bitwise operators
lost
parents: 194
diff changeset
628 { LWASM_OPER_BWOR, "|", 50 },
2c1afbdb2de0 Added |, &, and ^ binary bitwise operators
lost
parents: 194
diff changeset
629
2c1afbdb2de0 Added |, &, and ^ binary bitwise operators
lost
parents: 194
diff changeset
630 // this collides with the unary complement but shouldn't cause
2c1afbdb2de0 Added |, &, and ^ binary bitwise operators
lost
parents: 194
diff changeset
631 // any trouble because of operator precedence
2c1afbdb2de0 Added |, &, and ^ binary bitwise operators
lost
parents: 194
diff changeset
632 { LWASM_OPER_BWXOR, "^", 50 },
2c1afbdb2de0 Added |, &, and ^ binary bitwise operators
lost
parents: 194
diff changeset
633
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
634 { LWASM_OPER_NONE, "", 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 int opern, i;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
637 lwasm_expr_term_t *operterm;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
638
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
639 // 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
640 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']')
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
641 return 0;
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 if (lwasm_expr_parse_term(s, p) < 0)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
644 return -1;
37
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
645
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
646 eval_next:
61
73423b66e511 Fixed error with single char ascii constants
lost
parents: 47
diff changeset
647 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
648 return 0;
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
649
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
650 // expecting an operator here
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
651 for (opern = 0; operators[opern].opernum != LWASM_OPER_NONE; opern++)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
652 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
653 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
654 /* do nothing */ ;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
655 if (operators[opern].operstr[i] == '\0')
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
656 break;
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 if (operators[opern].opernum == LWASM_OPER_NONE)
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 // unrecognized operator
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
661 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
662 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
663
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
664 // 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
665 // operator string
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
666
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
667 // logic:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
668 // if the precedence of this operation is <= to the "prec" flag,
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
669 // we simply return without advancing the input pointer; the operator
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
670 // will be evaluated again in the enclosing function call
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
671 if (operators[opern].operprec <= prec)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
672 return 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
673
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
674 // logic:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
675 // we have a higher precedence operator here so we will advance the
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
676 // input pointer to the next term and let the expression evaluator
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
677 // 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
678 // stack and then go on with the expression evaluation
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
679 (*p) += i; // advance input pointer
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
680
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
681 // evaluate next expression(s) of higher precedence
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
682 if (lwasm_expr_parse_expr(s, p, operators[opern].operprec) < 0)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
683 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
684
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
685 operterm = lwasm_expr_term_create_oper(operators[opern].opernum);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
686 lwasm_expr_stack_push(s, operterm);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
687 lwasm_expr_term_free(operterm);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
688
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
689 // 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
690 if (!**p || isspace(**p) || **p == ')')
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
691 return 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
692
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
693 // continue evaluating
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
694 goto eval_next;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
695 }
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 /*
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
698 actually evaluate an expression
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
699
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
700 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
701 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
702 result is returned.
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
703
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
704 Returns NULL on a parse error or otherwise invalid expression. *outp will
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
705 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
706 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
707 */
76
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
708 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
709 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
710 lwasm_expr_stack_t *s;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
711 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
712 int rval;
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
713
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
714 // actually parse the expression
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
715 p = inp;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
716 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
717
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
718 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
719 if (rval < 0)
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
720 goto cleanup_error;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
721
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
722 // save end of expression
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
723 if (outp)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
724 (*outp) = p;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
725
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
726 // 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
727 if (lwasm_expr_reval(s, sfunc, state) < 0)
18
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
728 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
729
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
730 if (lwasm_expr_is_constant(s))
39
efa19ec69df9 tweaked debugging system for expression handler
lost
parents: 37
diff changeset
731 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
732
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
733 return s;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
734
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
735 cleanup_error:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
736 lwasm_expr_stack_free(s);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
737 return NULL;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
738 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
739
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
740 /*
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
741 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
742
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
743 return -1 on error, 0 on no error
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
744
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
745 possible errors are: division by zero or unknown operator
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
746
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
747 theory of operation:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
748
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
749 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
750 or 1 constant preceding it (unary) and if found, perform the calculation
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
751 and replace the operator and its operands with the result
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
752
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
753 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
754 further operators or only a single term remains
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
755
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
756 */
76
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
757 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
758 {
76
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
759 lwasm_expr_stack_node_t *n, *n2;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
760 lwasm_expr_stack_t *ss;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
761 int c;
37
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
762
76
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
763 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
764 // resolve symbols
76
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
765 // symbols that do not resolve to an expression are left alone
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
766 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
767 {
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
768 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
769 {
76
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
770 ss = sfunc(n -> term -> symbol, state);
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
771 if (ss)
37
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
772 {
76
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
773 c++;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
774 // splice in the result stack
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
775 if (n -> prev)
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
776 {
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
777 n -> prev -> next = ss -> head;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
778 }
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
779 else
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
780 {
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
781 s -> head = ss -> head;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
782 }
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
783 ss -> head -> prev = n -> prev;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
784 ss -> tail -> next = n -> next;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
785 if (n -> next)
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
786 {
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
787 n -> next -> prev = ss -> tail;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
788 }
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
789 else
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
790 {
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
791 s -> tail = ss -> tail;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
792 }
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
793 lwasm_expr_term_free(n -> term);
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
794 lwasm_free(n);
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
795 n = ss -> tail;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
796
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
797 ss -> head = NULL;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
798 ss -> tail = NULL;
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
799 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
800 }
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
801 }
538e15927776 Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents: 23
diff changeset
802 }
76
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
803 if (c)
2fe5fd7d65a3 Checkpointing object target implementation
lost
parents: 61
diff changeset
804 goto next_iter_sym;
18
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 next_iter:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
807 // a single term
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
808 if (s -> head == s -> tail)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
809 return 0;
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 // search for an operator
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
812 for (n = s -> head; n; n = n -> next)
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 if (n -> term -> term_type == LWASM_TERM_OPER)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
815 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
816 if (n -> term -> value == LWASM_OPER_NEG
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
817 || n -> term -> value == LWASM_OPER_COM
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
818 )
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
819 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
820 // unary operator
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
821 if (n -> prev && n -> prev -> term -> term_type == LWASM_TERM_INT)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
822 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
823 // a unary operator we can resolve
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
824 // we do the op then remove the term "n" is pointing at
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
825 if (n -> term -> value == LWASM_OPER_NEG)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
826 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
827 n -> prev -> term -> value = -(n -> prev -> term -> value);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
828 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
829 else if (n -> term -> value == LWASM_OPER_COM)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
830 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
831 n -> prev -> term -> value = ~(n -> prev -> term -> value);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
832 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
833 n -> prev -> next = n -> next;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
834 if (n -> next)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
835 n -> next -> prev = n -> prev;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
836 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
837 s -> tail = n -> prev;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
838
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
839 lwasm_expr_term_free(n -> term);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
840 lwasm_free(n);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
841 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
842 }
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 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
845 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
846 // binary operator
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
847 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
848 {
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
849 // a binary operator we can resolve
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
850 switch (n -> term -> value)
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_PLUS:
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_MINUS:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
857 n -> prev -> prev -> term -> value -= n -> prev -> term -> value;
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_TIMES:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
861 n -> prev -> prev -> term -> value *= n -> prev -> term -> value;
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 case LWASM_OPER_DIVIDE:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
865 if (n -> prev -> term -> value == 0)
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 n -> prev -> prev -> term -> value /= n -> prev -> term -> value;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
868 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
869
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
870 case LWASM_OPER_MOD:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
871 if (n -> prev -> term -> value == 0)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
872 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
873 n -> prev -> prev -> term -> value %= n -> prev -> term -> value;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
874 break;
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 case LWASM_OPER_INTDIV:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
877 if (n -> prev -> term -> value == 0)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
878 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
879 n -> prev -> prev -> term -> value /= n -> prev -> term -> value;
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 case LWASM_OPER_BWAND:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
883 n -> prev -> prev -> term -> value &= n -> prev -> term -> value;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
884 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
885
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
886 case LWASM_OPER_BWOR:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
887 n -> prev -> prev -> term -> value |= n -> prev -> term -> value;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
888 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
889
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
890 case LWASM_OPER_BWXOR:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
891 n -> prev -> prev -> term -> value ^= n -> prev -> term -> value;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
892 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
893
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
894 case LWASM_OPER_AND:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
895 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
896 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
897
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
898 case LWASM_OPER_OR:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
899 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
900 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
901
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
902 default:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
903 // return error if unknown operator!
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
904 return -1;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
905 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
906
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
907 // now remove the two unneeded entries from the stack
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
908 n -> prev -> prev -> next = n -> next;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
909 if (n -> next)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
910 n -> next -> prev = n -> prev -> prev;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
911 else
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
912 s -> tail = n -> prev -> prev;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
913
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
914 lwasm_expr_term_free(n -> term);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
915 lwasm_expr_term_free(n -> prev -> term);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
916 lwasm_free(n -> prev);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
917 lwasm_free(n);
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
918 break;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
919 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
920 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
921 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
922 }
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
923 // note for the terminally confused about dynamic memory and pointers:
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
924 // 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
925 // this test will still work (n will be a dangling pointer)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
926 // (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
927 if (n)
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
928 goto next_iter;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
929
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
930 return 0;
218aabbc3b1a First pass at expression evaluator complete
lost
parents: 17
diff changeset
931 }