Mercurial > hg-old > index.cgi
annotate lwasm/lwasm.c @ 420:7366deedfa85 3.0-beta2
Branched for 3.0-beta2 release
author | lost@l-w.ca |
---|---|
date | Sun, 19 Sep 2010 01:12:26 -0600 |
parents | 4b137a8cf32a |
children | 00924eeb2ec8 |
rev | line source |
---|---|
337 | 1 /* |
2 lwasm.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
22 #define ___lwasm_c_seen___ |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
23 |
337 | 24 #include <config.h> |
25 | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
26 #include <stdio.h> |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
27 #include <stdarg.h> |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
28 #include <string.h> |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
29 |
337 | 30 #include <lw_expr.h> |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
31 #include <lw_alloc.h> |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
32 #include <lw_string.h> |
337 | 33 |
34 #include "lwasm.h" | |
35 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
36 void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
37 |
375 | 38 int lwasm_expr_exportable(asmstate_t *as, lw_expr_t expr) |
39 { | |
40 return 0; | |
41 } | |
42 | |
43 int lwasm_expr_exportval(asmstate_t *as, lw_expr_t expr) | |
44 { | |
45 return 0; | |
46 } | |
47 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
48 lw_expr_t lwasm_evaluate_var(char *var, void *priv) |
337 | 49 { |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
50 asmstate_t *as = (asmstate_t *)priv; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
51 lw_expr_t e; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
52 importlist_t *im; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
53 struct symtabe *s; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
54 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
55 s = lookup_symbol(as, as -> cl, var); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
56 if (s) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
57 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
58 e = lw_expr_build(lw_expr_type_special, lwasm_expr_syment, s); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
59 return e; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
60 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
61 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
62 // undefined here is undefied unless output is object |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
63 if (as -> output_format != OUTPUT_OBJ) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
64 goto nomatch; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
65 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
66 // check for import |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
67 for (im = as -> importlist; im; im = im -> next) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
68 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
69 if (!strcmp(im -> symbol, var)) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
70 break; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
71 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
72 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
73 // check for "undefined" to import automatically |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
74 if (!im && CURPRAGMA(as -> cl, PRAGMA_UNDEFEXTERN)) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
75 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
76 im = lw_alloc(sizeof(importlist_t)); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
77 im -> symbol = lw_strdup(var); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
78 im -> next = as -> importlist; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
79 as -> importlist = im; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
80 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
81 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
82 if (!im) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
83 goto nomatch; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
84 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
85 e = lw_expr_build(lw_expr_type_special, lwasm_expr_import, im); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
86 return e; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
87 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
88 nomatch: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
89 if (as -> badsymerr) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
90 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
91 lwasm_register_error(as, as -> cl, "Undefined symbol %s", var); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
92 } |
337 | 93 return NULL; |
94 } | |
95 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
96 lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv) |
337 | 97 { |
98 switch (t) | |
99 { | |
375 | 100 case lwasm_expr_secbase: |
101 { | |
385 | 102 // sectiontab_t *s = priv; |
103 asmstate_t *as = priv; | |
104 if (as -> exportcheck && ptr == as -> csect) | |
375 | 105 return lw_expr_build(lw_expr_type_int, 0); |
106 return NULL; | |
107 } | |
108 | |
337 | 109 case lwasm_expr_linelen: |
110 { | |
111 line_t *cl = ptr; | |
112 if (cl -> len == -1) | |
113 return NULL; | |
114 return lw_expr_build(lw_expr_type_int, cl -> len); | |
115 } | |
116 break; | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
117 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
118 case lwasm_expr_lineaddr: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
119 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
120 line_t *cl = ptr; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
121 if (cl -> addr) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
122 return lw_expr_copy(cl -> addr); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
123 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
124 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
125 } |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
126 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
127 case lwasm_expr_syment: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
128 { |
371 | 129 struct symtabe *sym = ptr; |
130 return lw_expr_copy(sym -> value); | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
131 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
132 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
133 case lwasm_expr_import: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
134 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
135 return NULL; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
136 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
137 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
138 case lwasm_expr_nextbp: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
139 { |
418 | 140 line_t *cl = ptr; |
141 for (cl = cl -> next; cl; cl = cl -> next) | |
142 { | |
143 if (cl -> isbrpt) | |
144 break; | |
145 } | |
146 if (cl) | |
147 { | |
148 return lw_expr_copy(cl -> addr); | |
149 } | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
150 return NULL; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
151 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
152 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
153 case lwasm_expr_prevbp: |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
154 { |
418 | 155 line_t *cl = ptr; |
156 for (cl = cl -> prev; cl; cl = cl -> prev) | |
157 { | |
158 if (cl -> isbrpt) | |
159 break; | |
160 } | |
161 if (cl) | |
162 { | |
163 return lw_expr_copy(cl -> addr); | |
164 } | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
165 return NULL; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
166 } |
337 | 167 } |
168 return NULL; | |
169 } | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
170 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
171 void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
172 { |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
173 lwasm_error_t *e; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
174 va_list args; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
175 char errbuff[1024]; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
176 int r; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
177 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
178 if (!l) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
179 return; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
180 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
181 va_start(args, msg); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
182 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
183 e = lw_alloc(sizeof(lwasm_error_t)); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
184 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
185 e -> next = l -> err; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
186 l -> err = e; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
187 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
188 as -> errorcount++; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
189 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
190 r = vsnprintf(errbuff, 1024, msg, args); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
191 e -> mess = lw_strdup(errbuff); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
192 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
193 va_end(args); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
337
diff
changeset
|
194 } |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
195 |
351 | 196 void lwasm_register_warning(asmstate_t *as, line_t *l, const char *msg, ...) |
197 { | |
198 lwasm_error_t *e; | |
199 va_list args; | |
200 char errbuff[1024]; | |
201 int r; | |
202 | |
203 if (!l) | |
204 return; | |
205 | |
206 va_start(args, msg); | |
207 | |
208 e = lw_alloc(sizeof(lwasm_error_t)); | |
209 | |
210 e -> next = l -> err; | |
211 l -> err = e; | |
212 | |
213 as -> errorcount++; | |
214 | |
215 r = vsnprintf(errbuff, 1024, msg, args); | |
216 e -> mess = lw_strdup(errbuff); | |
217 | |
218 va_end(args); | |
219 } | |
220 | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
221 int lwasm_next_context(asmstate_t *as) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
222 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
223 int r; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
224 r = as -> nextcontext; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
225 as -> nextcontext++; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
226 return r; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
227 } |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
228 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
229 void lwasm_emit(line_t *cl, int byte) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
230 { |
374 | 231 if (cl -> outputl < 0) |
232 cl -> outputl = 0; | |
233 | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
234 if (cl -> outputl == cl -> outputbl) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
235 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
236 cl -> output = lw_realloc(cl -> output, cl -> outputbl + 8); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
237 cl -> outputbl += 8; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
238 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
239 cl -> output[cl -> outputl++] = byte & 0xff; |
354 | 240 |
241 if (cl -> inmod) | |
242 { | |
243 asmstate_t *as = cl -> as; | |
244 // update module CRC | |
245 // this is a direct transliteration from the nitros9 asm source | |
246 // to C; it can, no doubt, be optimized for 32 bit processing | |
247 byte &= 0xff; | |
248 | |
249 byte ^= (as -> crc)[0]; | |
250 (as -> crc)[0] = (as -> crc)[1]; | |
251 (as -> crc)[1] = (as -> crc)[2]; | |
252 (as -> crc)[1] ^= (byte >> 7); | |
253 (as -> crc)[2] = (byte << 1); | |
254 (as -> crc)[1] ^= (byte >> 2); | |
255 (as -> crc)[2] ^= (byte << 6); | |
256 byte ^= (byte << 1); | |
257 byte ^= (byte << 2); | |
258 byte ^= (byte << 4); | |
259 if (byte & 0x80) | |
260 { | |
261 (as -> crc)[0] ^= 0x80; | |
262 (as -> crc)[2] ^= 0x21; | |
263 } | |
264 } | |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
265 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
266 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
267 void lwasm_emitop(line_t *cl, int opc) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
268 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
269 if (opc > 0x100) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
270 lwasm_emit(cl, opc >> 8); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
271 lwasm_emit(cl, opc); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
272 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
273 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
274 lw_expr_t lwasm_parse_term(char **p, void *priv) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
275 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
276 asmstate_t *as = priv; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
277 int val; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
278 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
279 if (!**p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
280 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
281 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
282 if (**p == '*' || ( |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
283 **p == '.' |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
284 && !((*p)[1] >= 'A' && (*p)[1] <= 'Z') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
285 && !((*p)[1] >= 'a' && (*p)[1] <= 'z') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
286 && !((*p)[1] >= '0' && (*p)[1] <= '9') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
287 )) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
288 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
289 // special "symbol" for current line addr (*, .) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
290 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
291 return lw_expr_build(lw_expr_type_special, lwasm_expr_lineaddr, as -> cl); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
292 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
293 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
294 // branch points |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
295 if (**p == '<') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
296 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
297 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
298 return lw_expr_build(lw_expr_type_special, lwasm_expr_prevbp, as -> cl); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
299 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
300 if (**p == '>') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
301 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
302 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
303 return lw_expr_build(lw_expr_type_special, lwasm_expr_nextbp, as -> cl); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
304 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
305 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
306 // double ascii constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
307 if (**p == '"') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
308 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
309 int v; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
310 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
311 if (!**p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
312 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
313 if (!*((*p)+1)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
314 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
315 v = (unsigned char)**p << 8 | (unsigned char)*((*p)+1); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
316 (*p) += 2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
317 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
318 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
319 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
320 if (**p == '\'') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
321 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
322 int v; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
323 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
324 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
325 if (!**p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
326 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
327 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
328 v = (unsigned char)**p; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
329 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
330 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
331 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
332 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
333 if (**p == '&') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
334 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
335 // decimal constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
336 int v = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
337 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
338 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
339 if (!strchr("0123456789", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
340 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
341 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
342 while (**p && strchr("0123456789", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
343 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
344 val = val * 10 + (**p - '0'); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
345 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
346 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
347 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
348 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
349 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
350 if (**p == '%') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
351 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
352 // binary constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
353 int v = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
354 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
355 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
356 if (**p != '0' && **p != '1') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
357 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
358 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
359 while (**p && (**p == '0' || **p == '1')) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
360 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
361 val = val * 2 + (**p - '0'); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
362 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
363 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
364 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
365 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
366 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
367 if (**p == '$') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
368 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
369 // hexadecimal constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
370 int v = 0, v2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
371 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
372 if (!strchr("0123456789abcdefABCDEF", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
373 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
374 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
375 while (**p && strchr("0123456789abcdefABCDEF", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
376 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
377 v2 = toupper(**p) - '0'; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
378 if (v2 > 9) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
379 v2 -= 7; |
382 | 380 v = v * 16 + v2; |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
381 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
382 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
383 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
384 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
385 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
386 if (**p == '0' && (*((*p)+1) == 'x' || *((*p)+1) == 'X')) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
387 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
388 // hexadecimal constant, C style |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
389 int v = 0, v2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
390 (*p)+=2; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
391 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
392 if (!strchr("0123456789abcdefABCDEF", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
393 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
394 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
395 while (**p && strchr("0123456789abcdefABCDEF", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
396 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
397 v2 = toupper(**p) - '0'; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
398 if (v2 > 9) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
399 v2 -= 7; |
382 | 400 v = v * 16 + v2; |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
401 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
402 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
403 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
404 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
405 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
406 if (**p == '@' && (*((*p)+1) >= '0' && *((*p)+1) <= '7')) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
407 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
408 // octal constant |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
409 int v = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
410 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
411 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
412 if (!strchr("01234567", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
413 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
414 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
415 while (**p && strchr("01234567", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
416 { |
382 | 417 v = v * 8 + (**p - '0'); |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
418 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
419 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
420 return lw_expr_build(lw_expr_type_int, v); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
421 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
422 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
423 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
424 // symbol or bare decimal or suffix constant here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
425 do |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
426 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
427 int havedol = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
428 int l = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
429 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
430 while ((*p)[l] && strchr(SYMCHARS, (*p)[l])) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
431 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
432 if ((*p)[l] == '$') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
433 havedol = 1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
434 l++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
435 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
436 if (l == 0) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
437 return NULL; |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
438 |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
439 if ((*p)[l] == '{') |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
440 { |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
441 while ((*p)[l] && (*p)[l] != '}') |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
442 l++; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
443 l++; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
387
diff
changeset
|
444 } |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
445 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
446 if (havedol || **p < '0' || **p > '9') |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
447 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
448 // have a symbol here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
449 char *sym; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
450 lw_expr_t term; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
451 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
452 sym = lw_strndup(*p, l); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
453 (*p) += l; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
454 term = lw_expr_build(lw_expr_type_var, sym); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
455 lw_free(sym); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
456 return term; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
457 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
458 } while (0); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
459 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
460 if (!**p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
461 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
462 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
463 // we have a numeric constant here, either decimal or postfix base notation |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
464 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
465 int decval = 0, binval = 0, hexval = 0, octval = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
466 int valtype = 15; // 1 = bin, 2 = oct, 4 = dec, 8 = hex |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
467 int bindone = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
468 int val; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
469 int dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
470 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
471 while (1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
472 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
473 if (!**p || !strchr("0123456789ABCDEFabcdefqhoQHO", **p)) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
474 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
475 // we can legally be bin or decimal here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
476 if (bindone) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
477 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
478 // just finished a binary value |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
479 val = binval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
480 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
481 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
482 else if (valtype & 4) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
483 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
484 val = decval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
485 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
486 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
487 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
488 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
489 // bad value |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
490 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
491 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
492 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
493 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
494 dval = toupper(**p); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
495 (*p)++; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
496 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
497 if (bindone) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
498 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
499 // any characters past "B" means it is not binary |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
500 bindone = 0; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
501 valtype &= 14; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
502 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
503 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
504 switch (dval) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
505 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
506 case 'Q': |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
507 case 'O': |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
508 if (valtype & 2) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
509 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
510 val = octval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
511 valtype = -1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
512 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
513 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
514 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
515 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
516 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
517 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
518 /* can't get here */ |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
519 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
520 case 'H': |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
521 if (valtype & 8) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
522 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
523 val = hexval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
524 valtype = -1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
525 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
526 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
527 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
528 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
529 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
530 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
531 /* can't get here */ |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
532 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
533 case 'B': |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
534 // this is a bit of a sticky one since B may be a |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
535 // hex number instead of the end of a binary number |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
536 // so it falls through to the digit case |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
537 if (valtype & 1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
538 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
539 // could still be binary of hex |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
540 bindone = 1; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
541 valtype = 9; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
542 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
543 /* fall through intented */ |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
544 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
545 default: |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
546 // digit |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
547 dval -= '0'; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
548 if (dval > 9) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
549 dval -= 7; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
550 if (valtype & 8) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
551 hexval = hexval * 16 + dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
552 if (valtype & 4) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
553 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
554 if (dval > 9) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
555 valtype &= 11; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
556 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
557 decval = decval * 10 + dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
558 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
559 if (valtype & 2) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
560 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
561 if (dval > 7) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
562 valtype &= 13; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
563 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
564 octval = octval * 8 + dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
565 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
566 if (valtype & 1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
567 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
568 if (dval > 1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
569 valtype &= 14; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
570 else |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
571 binval = binval * 2 + dval; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
572 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
573 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
574 if (valtype == -1) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
575 break; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
576 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
577 // return if no more valid types |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
578 if (valtype == 0) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
579 return NULL; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
580 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
581 val = decval; // in case we fall through |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
582 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
583 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
584 // get here if we have a value |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
585 return lw_expr_build(lw_expr_type_int, val); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
586 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
587 // can't get here |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
588 } |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
589 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
590 lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p) |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
591 { |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
592 lw_expr_t e; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
593 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
594 e = lw_expr_parse(p, as); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
595 |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
596 return e; |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
597 } |
347 | 598 |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
599 int lwasm_reduce_expr(asmstate_t *as, lw_expr_t expr) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
600 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
601 lw_expr_simplify(expr, as); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
602 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
603 |
347 | 604 void lwasm_save_expr(line_t *cl, int id, lw_expr_t expr) |
605 { | |
606 struct line_expr_s *e; | |
607 | |
608 for (e = cl -> exprs; e; e = e -> next) | |
609 { | |
610 if (e -> id == id) | |
611 { | |
612 lw_expr_destroy(e -> expr); | |
613 e -> expr = expr; | |
614 return; | |
615 } | |
616 } | |
617 | |
618 e = lw_alloc(sizeof(struct line_expr_s)); | |
619 e -> expr = expr; | |
620 e -> id = id; | |
621 e -> next = cl -> exprs; | |
622 cl -> exprs = e; | |
623 } | |
624 | |
625 lw_expr_t lwasm_fetch_expr(line_t *cl, int id) | |
626 { | |
627 struct line_expr_s *e; | |
628 | |
629 for (e = cl -> exprs; e; e = e -> next) | |
630 { | |
631 if (e -> id == id) | |
632 { | |
633 return e -> expr; | |
634 } | |
635 } | |
636 return NULL; | |
637 } | |
638 | |
639 void skip_operand(char **p) | |
640 { | |
641 for (; **p && !isspace(**p); (*p)++) | |
642 /* do nothing */ ; | |
643 } | |
644 | |
645 int lwasm_emitexpr(line_t *l, lw_expr_t expr, int size) | |
646 { | |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
647 int v = 0; |
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
648 int ol; |
347 | 649 |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
650 ol = l -> outputl; |
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
651 if (ol == -1) |
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
652 ol = 0; |
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
653 |
347 | 654 if (lw_expr_istype(expr, lw_expr_type_int)) |
655 { | |
656 v = lw_expr_intval(expr); | |
657 } | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
658 // handle external/cross-section/incomplete references here |
347 | 659 else |
660 { | |
374 | 661 if (l -> as -> output_format == OUTPUT_OBJ) |
662 { | |
663 reloctab_t *re; | |
376 | 664 lw_expr_t te; |
374 | 665 |
381 | 666 if (size == 4) |
667 { | |
668 // create a two part reference because lwlink doesn't | |
669 // support 32 bit references | |
670 lw_expr_t te2; | |
671 te = lw_expr_build(lw_expr_type_int, 0x10000); | |
672 te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_divide, expr, te); | |
673 lw_expr_destroy(te); | |
674 | |
675 re = lw_alloc(sizeof(reloctab_t)); | |
676 re -> next = l -> csect -> reloctab; | |
677 l -> csect -> reloctab = re; | |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
678 te = lw_expr_build(lw_expr_type_int, ol); |
381 | 679 re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te); |
680 lw_expr_destroy(te); | |
681 lwasm_reduce_expr(l -> as, re -> offset); | |
682 re -> expr = te2; | |
683 re -> size = 2; | |
684 | |
685 te = lw_expr_build(lw_expr_type_int, 0xFFFF); | |
686 te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_bwand, expr, te); | |
687 lw_expr_destroy(te); | |
688 | |
689 re = lw_alloc(sizeof(reloctab_t)); | |
690 re -> next = l -> csect -> reloctab; | |
691 l -> csect -> reloctab = re; | |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
692 te = lw_expr_build(lw_expr_type_int, ol + 2); |
381 | 693 re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te); |
694 lw_expr_destroy(te); | |
695 lwasm_reduce_expr(l -> as, re -> offset); | |
696 re -> expr = te2; | |
697 re -> size = 2; | |
698 } | |
699 else | |
700 { | |
701 // add "expression" record to section table | |
702 re = lw_alloc(sizeof(reloctab_t)); | |
703 re -> next = l -> csect -> reloctab; | |
704 l -> csect -> reloctab = re; | |
416
1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
lost@l-w.ca
parents:
394
diff
changeset
|
705 te = lw_expr_build(lw_expr_type_int, ol); |
381 | 706 re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te); |
707 lw_expr_destroy(te); | |
708 lwasm_reduce_expr(l -> as, re -> offset); | |
709 re -> size = size; | |
710 re -> expr = lw_expr_copy(expr); | |
711 } | |
374 | 712 for (v = 0; v < size; v++) |
713 lwasm_emit(l, 0); | |
714 return 0; | |
715 } | |
347 | 716 lwasm_register_error(l -> as, l, "Expression not fully resolved"); |
717 return -1; | |
718 } | |
719 | |
720 switch (size) | |
721 { | |
722 case 4: | |
723 lwasm_emit(l, v >> 24); | |
724 lwasm_emit(l, v >> 16); | |
725 /* fallthrough intended */ | |
726 | |
727 case 2: | |
728 lwasm_emit(l, v >> 8); | |
729 /* fallthrough intended */ | |
730 | |
731 case 1: | |
732 lwasm_emit(l, v); | |
733 } | |
734 | |
735 return 0; | |
736 } | |
357 | 737 |
738 int lwasm_lookupreg2(const char *regs, char **p) | |
739 { | |
740 int rval = 0; | |
741 | |
742 while (*regs) | |
743 { | |
744 if (toupper(**p) == *regs) | |
745 { | |
746 if (regs[1] == ' ' && !isalpha(*(*p + 1))) | |
747 break; | |
748 if (toupper(*(*p + 1)) == regs[1]) | |
749 break; | |
750 } | |
751 regs += 2; | |
752 rval++; | |
753 } | |
754 if (!*regs) | |
755 return -1; | |
756 if (regs[1] == ' ') | |
757 (*p)++; | |
758 else | |
759 (*p) += 2; | |
760 return rval; | |
761 } | |
359 | 762 |
763 int lwasm_lookupreg3(const char *regs, char **p) | |
764 { | |
765 int rval = 0; | |
766 | |
767 while (*regs) | |
768 { | |
769 if (toupper(**p) == *regs) | |
770 { | |
771 if (regs[1] == ' ' && !isalpha(*(*p + 1))) | |
772 break; | |
773 if (toupper(*(*p + 1)) == regs[1]) | |
774 { | |
775 if (regs[2] == ' ' && !isalpha(*(*p + 2))) | |
776 break; | |
777 if (toupper(*(*p + 2)) == regs[2]) | |
778 break; | |
779 } | |
780 } | |
781 regs += 3; | |
782 rval++; | |
783 } | |
784 if (!*regs) | |
785 return -1; | |
786 if (regs[1] == ' ') | |
787 (*p)++; | |
788 else if (regs[2] == ' ') | |
789 (*p) += 2; | |
790 else | |
791 (*p) += 3; | |
792 return rval; | |
793 } | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
794 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
795 void lwasm_show_errors(asmstate_t *as) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
796 { |
382 | 797 line_t *cl; |
798 lwasm_error_t *e; | |
799 | |
800 for (cl = as -> line_head; cl; cl = cl -> next) | |
801 { | |
802 if (!(cl -> err) && !(cl -> warn)) | |
803 continue; | |
804 for (e = cl -> err; e; e = e -> next) | |
805 { | |
806 fprintf(stderr, "ERROR: %s\n", e -> mess); | |
807 } | |
808 for (e = cl -> warn; e; e = e -> next) | |
809 { | |
810 fprintf(stderr, "WARNING: %s\n", e -> mess); | |
811 } | |
394
a2f52e97b454
Actually show name of file and line number where error occurred
lost@l-w.ca
parents:
391
diff
changeset
|
812 fprintf(stderr, "%s:%05d %s\n\n", cl -> linespec, cl -> lineno, cl -> ltext); |
382 | 813 } |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
359
diff
changeset
|
814 } |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
815 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
816 /* |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
817 this does any passes and other gymnastics that might be useful |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
818 to see if an expression reduces early |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
819 */ |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
820 extern void do_pass3(asmstate_t *as); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
821 extern void do_pass4_aux(asmstate_t *as, int force); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
822 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
823 void lwasm_interim_reduce(asmstate_t *as) |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
824 { |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
825 do_pass3(as); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
826 // do_pass4_aux(as, 0); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
827 } |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
828 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
829 lw_expr_t lwasm_parse_cond(asmstate_t *as, char **p) |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
830 { |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
831 lw_expr_t e; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
832 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
833 debug_message(as, 250, "Parsing condition"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
834 e = lwasm_parse_expr(as, p); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
835 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
836 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
837 if (!e) |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
838 { |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
839 lwasm_register_error(as, as -> cl, "Bad expression"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
840 return NULL; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
841 } |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
842 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
843 /* we need to simplify the expression here */ |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
844 debug_message(as, 250, "Doing interim reductions"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
845 lwasm_interim_reduce(as); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
846 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
847 debug_message(as, 250, "Reducing expression"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
848 lwasm_reduce_expr(as, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
849 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
850 /* lwasm_reduce_expr(as, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
851 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
852 lwasm_reduce_expr(as, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
853 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
854 lwasm_reduce_expr(as, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
855 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
856 */ |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
857 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
858 lwasm_save_expr(as -> cl, 4242, e); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
859 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
860 if (!lw_expr_istype(e, lw_expr_type_int)) |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
861 { |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
862 debug_message(as, 250, "Non-constant expression"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
863 lwasm_register_error(as, as -> cl, "Conditions must be constant on pass 1"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
864 return NULL; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
865 } |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
866 debug_message(as, 250, "Returning expression"); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
867 return e; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
868 } |