Mercurial > hg-old > index.cgi
annotate lwasm/pseudo.c @ 369:898a41f7eb59
check for valid expressions in pass 6
author | lost@starbug |
---|---|
date | Thu, 15 Apr 2010 22:26:49 -0600 |
parents | d96c30e60ddf |
children | 6b33faa21a0a |
rev | line source |
---|---|
347 | 1 /* |
2 pseudo.c | |
3 Copyright © 2010 William Astle | |
4 | |
5 This file is part of LWASM. | |
6 | |
7 LWASM is free software: you can redistribute it and/or modify it under the | |
8 terms of the GNU General Public License as published by the Free Software | |
9 Foundation, either version 3 of the License, or (at your option) any later | |
10 version. | |
11 | |
12 This program is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 more details. | |
16 | |
17 You should have received a copy of the GNU General Public License along with | |
18 this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
356 | 24 #include <stdio.h> |
25 | |
347 | 26 #include "lwasm.h" |
27 #include "instab.h" | |
356 | 28 #include "input.h" |
347 | 29 |
349 | 30 #include "lw_string.h" |
31 | |
347 | 32 // for "end" |
33 PARSEFUNC(pseudo_parse_end) | |
34 { | |
35 lw_expr_t addr; | |
36 | |
37 as -> endseen = 1; | |
38 | |
39 if (as -> output_format != OUTPUT_DECB) | |
40 { | |
41 skip_operand(p); | |
42 return; | |
43 } | |
44 | |
45 addr = lwasm_parse_expr(as, p); | |
46 if (!addr) | |
47 { | |
48 lwasm_register_error(as, l, "Bad expression"); | |
49 addr = lw_expr_build(lw_expr_type_int, 0); | |
50 } | |
51 lwasm_save_expr(l, 0, addr); | |
52 } | |
53 | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
54 EMITFUNC(pseudo_emit_end) |
347 | 55 { |
56 lw_expr_t addr; | |
57 | |
58 addr = lwasm_fetch_expr(l, 0); | |
59 | |
60 if (addr) | |
61 { | |
62 if (!lw_expr_istype(addr, lw_expr_type_int)) | |
63 lwasm_register_error(as, l, "Exec address not constant!"); | |
64 else | |
65 as -> execaddr = lw_expr_intval(addr); | |
66 } | |
67 as -> endseen = 1; | |
68 } | |
69 | |
70 PARSEFUNC(pseudo_parse_fcb) | |
71 { | |
72 int i = 0; | |
73 lw_expr_t e; | |
74 | |
75 for (;;) | |
76 { | |
77 e = lwasm_parse_expr(as, p); | |
78 if (!e) | |
79 { | |
80 lwasm_register_error(as, l, "Bad expression (#%s)", i); | |
81 break; | |
82 } | |
83 lwasm_save_expr(l, i, e); | |
84 i++; | |
85 } | |
86 | |
87 l -> len = i; | |
88 } | |
89 | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
90 EMITFUNC(pseudo_emit_fcb) |
347 | 91 { |
92 int i; | |
93 lw_expr_t e; | |
94 int v; | |
95 | |
96 for (i = 0; i < l -> len; i++) | |
97 { | |
98 e = lwasm_fetch_expr(l, i); | |
99 lwasm_emitexpr(l, e, 1); | |
100 } | |
101 } | |
102 | |
103 PARSEFUNC(pseudo_parse_fdb) | |
104 { | |
105 int i = 0; | |
106 lw_expr_t e; | |
107 | |
108 for (;;) | |
109 { | |
110 e = lwasm_parse_expr(as, p); | |
111 if (!e) | |
112 { | |
113 lwasm_register_error(as, l, "Bad expression (#%s)", i); | |
114 break; | |
115 } | |
116 lwasm_save_expr(l, i, e); | |
117 i++; | |
118 } | |
119 | |
120 l -> len = i * 2; | |
121 } | |
122 | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
123 EMITFUNC(pseudo_emit_fdb) |
347 | 124 { |
125 int i; | |
126 lw_expr_t e; | |
127 int v; | |
128 | |
129 for (i = 0; i < (l -> len)/2; i++) | |
130 { | |
131 e = lwasm_fetch_expr(l, i); | |
132 lwasm_emitexpr(l, e, 2); | |
133 } | |
134 } | |
135 | |
136 PARSEFUNC(pseudo_parse_fqb) | |
137 { | |
138 int i = 0; | |
139 lw_expr_t e; | |
140 | |
141 for (;;) | |
142 { | |
143 e = lwasm_parse_expr(as, p); | |
144 if (!e) | |
145 { | |
146 lwasm_register_error(as, l, "Bad expression (#%s)", i); | |
147 break; | |
148 } | |
149 lwasm_save_expr(l, i, e); | |
150 i++; | |
151 } | |
152 | |
153 l -> len = i * 4; | |
154 } | |
155 | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
156 EMITFUNC(pseudo_emit_fqb) |
347 | 157 { |
158 int i; | |
159 lw_expr_t e; | |
160 int v; | |
161 | |
162 for (i = 0; i < (l -> len)/4; i++) | |
163 { | |
164 e = lwasm_fetch_expr(l, i); | |
165 lwasm_emitexpr(l, e, 4); | |
166 } | |
167 } | |
349 | 168 |
169 PARSEFUNC(pseudo_parse_fcc) | |
170 { | |
171 char delim; | |
172 int i; | |
173 | |
174 if (!**p) | |
175 { | |
176 lwasm_register_error(as, l, "Bad operand"); | |
177 return; | |
178 } | |
179 | |
180 delim = **p; | |
181 (*p)++; | |
182 | |
183 for (i = 0; (*p)[i] && (*p)[i] != delim; i++) | |
184 /* do nothing */ ; | |
185 | |
186 if ((*p)[i] != delim) | |
187 { | |
188 lwasm_register_error(as, l, "Bad operand"); | |
189 return; | |
190 } | |
191 | |
192 l -> lstr = lw_strndup(*p, i); | |
193 (*p) += i + 1; | |
194 | |
195 l -> len = i; | |
196 } | |
197 | |
198 EMITFUNC(pseudo_emit_fcc) | |
199 { | |
200 int i; | |
201 | |
202 for (i = 0; i < l -> len; i++) | |
203 lwasm_emit(l, l -> lstr[i]); | |
204 } | |
205 | |
206 PARSEFUNC(pseudo_parse_fcs) | |
207 { | |
208 char delim; | |
209 int i; | |
210 | |
211 if (!**p) | |
212 { | |
213 lwasm_register_error(as, l, "Bad operand"); | |
214 return; | |
215 } | |
216 | |
217 delim = **p; | |
218 (*p)++; | |
219 | |
220 for (i = 0; (*p)[i] && (*p)[i] != delim; i++) | |
221 /* do nothing */ ; | |
222 | |
223 if ((*p)[i] != delim) | |
224 { | |
225 lwasm_register_error(as, l, "Bad operand"); | |
226 return; | |
227 } | |
228 | |
229 l -> lstr = lw_strndup(*p, i); | |
230 (*p) += i + 1; | |
231 | |
232 l -> len = i; | |
233 } | |
234 | |
235 EMITFUNC(pseudo_emit_fcs) | |
236 { | |
237 int i; | |
238 | |
239 for (i = 0; i < l -> len - 1; i++) | |
240 lwasm_emit(l, l -> lstr[i]); | |
241 lwasm_emit(l, l -> lstr[i] | 0x80); | |
242 } | |
243 | |
244 PARSEFUNC(pseudo_parse_fcn) | |
245 { | |
246 char delim; | |
247 int i; | |
248 | |
249 if (!**p) | |
250 { | |
251 lwasm_register_error(as, l, "Bad operand"); | |
252 return; | |
253 } | |
254 | |
255 delim = **p; | |
256 (*p)++; | |
257 | |
258 for (i = 0; (*p)[i] && (*p)[i] != delim; i++) | |
259 /* do nothing */ ; | |
260 | |
261 if ((*p)[i] != delim) | |
262 { | |
263 lwasm_register_error(as, l, "Bad operand"); | |
264 return; | |
265 } | |
266 | |
267 l -> lstr = lw_strndup(*p, i); | |
268 (*p) += i + 1; | |
269 | |
270 l -> len = i; | |
271 } | |
272 | |
273 EMITFUNC(pseudo_emit_fcn) | |
274 { | |
275 int i; | |
276 | |
277 for (i = 0; i < l -> len; i++) | |
278 lwasm_emit(l, l -> lstr[i]); | |
279 lwasm_emit(l, 0); | |
280 } | |
281 | |
282 PARSEFUNC(pseudo_parse_rmb) | |
283 { | |
284 lw_expr_t expr; | |
285 | |
286 expr = lwasm_parse_expr(as, p); | |
287 if (!expr) | |
288 { | |
289 lwasm_register_error(as, l, "Bad expression"); | |
290 } | |
291 | |
292 lwasm_save_expr(l, 0, expr); | |
293 } | |
294 | |
295 RESOLVEFUNC(pseudo_resolve_rmb) | |
296 { | |
297 lw_expr_t expr; | |
298 | |
299 if (l -> len >= 0) | |
300 return; | |
301 | |
302 expr = lwasm_fetch_expr(l, 0); | |
303 | |
304 if (lw_expr_istype(expr, lw_expr_type_int)) | |
305 { | |
306 l -> len = lw_expr_intval(expr); | |
307 } | |
308 } | |
309 | |
310 EMITFUNC(pseudo_emit_rmb) | |
311 { | |
312 if (l -> len < 0) | |
313 lwasm_register_error(as, l, "Expression not constant"); | |
314 } | |
315 | |
316 PARSEFUNC(pseudo_parse_rmd) | |
317 { | |
318 lw_expr_t expr; | |
319 | |
320 expr = lwasm_parse_expr(as, p); | |
321 if (!expr) | |
322 { | |
323 lwasm_register_error(as, l, "Bad expression"); | |
324 } | |
325 | |
326 lwasm_save_expr(l, 0, expr); | |
327 } | |
328 | |
329 RESOLVEFUNC(pseudo_resolve_rmd) | |
330 { | |
331 lw_expr_t expr; | |
332 | |
333 if (l -> len >= 0) | |
334 return; | |
335 | |
336 expr = lwasm_fetch_expr(l, 0); | |
337 | |
338 if (lw_expr_istype(expr, lw_expr_type_int)) | |
339 { | |
340 l -> len = lw_expr_intval(expr) * 2; | |
341 } | |
342 } | |
343 | |
344 EMITFUNC(pseudo_emit_rmd) | |
345 { | |
346 if (l -> len < 0) | |
347 lwasm_register_error(as, l, "Expression not constant"); | |
348 } | |
349 | |
350 | |
351 PARSEFUNC(pseudo_parse_rmq) | |
352 { | |
353 lw_expr_t expr; | |
354 | |
355 expr = lwasm_parse_expr(as, p); | |
356 if (!expr) | |
357 { | |
358 lwasm_register_error(as, l, "Bad expression"); | |
359 } | |
360 | |
361 lwasm_save_expr(l, 0, expr); | |
362 } | |
363 | |
364 RESOLVEFUNC(pseudo_resolve_rmq) | |
365 { | |
366 lw_expr_t expr; | |
367 | |
368 if (l -> len >= 0) | |
369 return; | |
370 | |
371 expr = lwasm_fetch_expr(l, 0); | |
372 | |
373 if (lw_expr_istype(expr, lw_expr_type_int)) | |
374 { | |
375 l -> len = lw_expr_intval(expr) * 4; | |
376 } | |
377 } | |
378 | |
379 EMITFUNC(pseudo_emit_rmq) | |
380 { | |
381 if (l -> len < 0) | |
382 lwasm_register_error(as, l, "Expression not constant"); | |
383 } | |
384 | |
385 | |
386 PARSEFUNC(pseudo_parse_zmq) | |
387 { | |
388 lw_expr_t expr; | |
389 | |
390 expr = lwasm_parse_expr(as, p); | |
391 if (!expr) | |
392 { | |
393 lwasm_register_error(as, l, "Bad expression"); | |
394 } | |
395 | |
396 lwasm_save_expr(l, 0, expr); | |
397 } | |
398 | |
399 RESOLVEFUNC(pseudo_resolve_zmq) | |
400 { | |
401 lw_expr_t expr; | |
402 | |
403 if (l -> len >= 0) | |
404 return; | |
405 | |
406 expr = lwasm_fetch_expr(l, 0); | |
407 | |
408 if (lw_expr_istype(expr, lw_expr_type_int)) | |
409 { | |
410 l -> len = lw_expr_intval(expr) * 4; | |
411 } | |
412 } | |
413 | |
414 EMITFUNC(pseudo_emit_zmq) | |
415 { | |
416 int i; | |
417 | |
418 if (l -> len < 0) | |
419 { | |
420 lwasm_register_error(as, l, "Expression not constant"); | |
421 return; | |
422 } | |
423 | |
424 for (i = 0; i < l -> len; i++) | |
425 lwasm_emit(l, 0); | |
426 } | |
427 | |
428 | |
429 PARSEFUNC(pseudo_parse_zmd) | |
430 { | |
431 lw_expr_t expr; | |
432 | |
433 expr = lwasm_parse_expr(as, p); | |
434 if (!expr) | |
435 { | |
436 lwasm_register_error(as, l, "Bad expression"); | |
437 } | |
438 | |
439 lwasm_save_expr(l, 0, expr); | |
440 } | |
441 | |
442 RESOLVEFUNC(pseudo_resolve_zmd) | |
443 { | |
444 lw_expr_t expr; | |
445 | |
446 if (l -> len >= 0) | |
447 return; | |
448 | |
449 expr = lwasm_fetch_expr(l, 0); | |
450 | |
451 if (lw_expr_istype(expr, lw_expr_type_int)) | |
452 { | |
453 l -> len = lw_expr_intval(expr) * 2; | |
454 } | |
455 } | |
456 | |
457 EMITFUNC(pseudo_emit_zmd) | |
458 { | |
459 int i; | |
460 | |
461 if (l -> len < 0) | |
462 { | |
463 lwasm_register_error(as, l, "Expression not constant"); | |
464 return; | |
465 } | |
466 | |
467 for (i = 0; i < l -> len; i++) | |
468 lwasm_emit(l, 0); | |
469 } | |
470 | |
471 PARSEFUNC(pseudo_parse_zmb) | |
472 { | |
473 lw_expr_t expr; | |
474 | |
475 expr = lwasm_parse_expr(as, p); | |
476 if (!expr) | |
477 { | |
478 lwasm_register_error(as, l, "Bad expression"); | |
479 } | |
480 | |
481 lwasm_save_expr(l, 0, expr); | |
482 } | |
483 | |
484 RESOLVEFUNC(pseudo_resolve_zmb) | |
485 { | |
486 lw_expr_t expr; | |
487 | |
488 if (l -> len >= 0) | |
489 return; | |
490 | |
491 expr = lwasm_fetch_expr(l, 0); | |
492 | |
493 if (lw_expr_istype(expr, lw_expr_type_int)) | |
494 { | |
495 l -> len = lw_expr_intval(expr); | |
496 } | |
497 } | |
498 | |
499 EMITFUNC(pseudo_emit_zmb) | |
500 { | |
501 int i; | |
502 | |
503 if (l -> len < 0) | |
504 { | |
505 lwasm_register_error(as, l, "Expression not constant"); | |
506 return; | |
507 } | |
508 | |
509 for (i = 0; i < l -> len; i++) | |
510 lwasm_emit(l, 0); | |
511 } | |
350 | 512 |
513 PARSEFUNC(pseudo_parse_org) | |
514 { | |
515 lw_expr_t e; | |
516 | |
351 | 517 l -> len = 0; |
518 | |
350 | 519 e = lwasm_parse_expr(as, p); |
520 if (!e) | |
521 { | |
522 lwasm_register_error(as, l, "Bad operand"); | |
523 return; | |
524 } | |
525 | |
526 lw_expr_destroy(l -> addr); | |
527 l -> addr = e; | |
528 l -> len = 0; | |
529 } | |
530 | |
531 PARSEFUNC(pseudo_parse_equ) | |
532 { | |
533 lw_expr_t e; | |
534 | |
351 | 535 l -> len = 0; |
536 | |
350 | 537 if (!(l -> sym)) |
538 { | |
539 lwasm_register_error(as, l, "Missing symbol"); | |
540 return; | |
541 } | |
542 | |
543 e = lwasm_parse_expr(as, p); | |
544 if (!e) | |
545 { | |
546 lwasm_register_error(as, l, "Bad operand"); | |
547 return; | |
548 } | |
549 | |
550 register_symbol(as, l, l -> sym, e, symbol_flag_none); | |
551 l -> symset = 1; | |
552 } | |
351 | 553 |
554 PARSEFUNC(pseudo_parse_set) | |
555 { | |
556 lw_expr_t e; | |
557 | |
558 l -> len = 0; | |
559 | |
560 if (!(l -> sym)) | |
561 { | |
562 lwasm_register_error(as, l, "Missing symbol"); | |
563 return; | |
564 } | |
565 | |
566 e = lwasm_parse_expr(as, p); | |
567 if (!e) | |
568 { | |
569 lwasm_register_error(as, l, "Bad operand"); | |
570 return; | |
571 } | |
572 | |
573 register_symbol(as, l, l -> sym, e, symbol_flag_set); | |
574 l -> symset = 1; | |
575 } | |
576 | |
577 PARSEFUNC(pseudo_parse_setdp) | |
578 { | |
579 lw_expr_t e; | |
580 | |
581 l -> len = 0; | |
582 | |
583 if (as -> output_format == OUTPUT_OBJ) | |
584 { | |
585 lwasm_register_error(as, l, "SETDP not permitted for object target"); | |
586 return; | |
587 } | |
588 | |
589 e = lwasm_parse_expr(as, p); | |
590 if (!e) | |
591 { | |
592 lwasm_register_error(as, l, "Bad operand"); | |
593 return; | |
594 } | |
595 | |
596 if (!lw_expr_istype(e, lw_expr_type_int)) | |
597 { | |
598 lwasm_register_error(as, l, "SETDP must be constant on pass 1"); | |
599 return; | |
600 } | |
601 l -> dpval = lw_expr_intval(e) & 0xff; | |
602 } | |
603 | |
604 PARSEFUNC(pseudo_parse_ifp1) | |
605 { | |
606 l -> len = 0; | |
607 | |
608 if (as -> skipcond && !(as -> skipmacro)) | |
609 { | |
610 as -> skipcount++; | |
611 skip_operand(p); | |
612 return; | |
613 } | |
614 | |
615 lwasm_register_warning(as, l, "IFP1 if is not supported; ignoring"); | |
616 | |
617 } | |
618 | |
619 PARSEFUNC(pseudo_parse_ifp2) | |
620 { | |
621 l -> len = 0; | |
622 | |
623 if (as -> skipcond && !(as -> skipmacro)) | |
624 { | |
625 as -> skipcount++; | |
626 skip_operand(p); | |
627 return; | |
628 } | |
629 | |
630 lwasm_register_warning(as, l, "IFP2 if is not supported; ignoring"); | |
631 } | |
632 | |
633 PARSEFUNC(pseudo_parse_ifeq) | |
634 { | |
635 lw_expr_t e; | |
636 | |
637 l -> len = 0; | |
638 | |
639 if (as -> skipcond && !(as -> skipmacro)) | |
640 { | |
641 as -> skipcount++; | |
642 skip_operand(p); | |
643 return; | |
644 } | |
645 | |
646 e = lwasm_parse_expr(as, p); | |
647 if (!e) | |
648 { | |
649 lwasm_register_error(as, l, "Bad expression"); | |
650 return; | |
651 } | |
652 if (!lw_expr_istype(e, lw_expr_type_int)) | |
653 { | |
654 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
655 return; | |
656 } | |
657 if (lw_expr_intval(e) != 0) | |
658 { | |
659 as -> skipcond = 1; | |
660 as -> skipcount = 1; | |
661 } | |
662 } | |
663 | |
664 PARSEFUNC(pseudo_parse_ifne) | |
665 { | |
666 lw_expr_t e; | |
667 | |
668 l -> len = 0; | |
669 | |
670 if (as -> skipcond && !(as -> skipmacro)) | |
671 { | |
672 as -> skipcount++; | |
673 skip_operand(p); | |
674 return; | |
675 } | |
676 | |
677 e = lwasm_parse_expr(as, p); | |
678 if (!e) | |
679 { | |
680 lwasm_register_error(as, l, "Bad expression"); | |
681 return; | |
682 } | |
683 if (!lw_expr_istype(e, lw_expr_type_int)) | |
684 { | |
685 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
686 return; | |
687 } | |
688 if (lw_expr_intval(e) == 0) | |
689 { | |
690 as -> skipcond = 1; | |
691 as -> skipcount = 1; | |
692 } | |
693 } | |
694 | |
695 | |
696 PARSEFUNC(pseudo_parse_ifgt) | |
697 { | |
698 lw_expr_t e; | |
699 | |
700 l -> len = 0; | |
701 | |
702 if (as -> skipcond && !(as -> skipmacro)) | |
703 { | |
704 as -> skipcount++; | |
705 skip_operand(p); | |
706 return; | |
707 } | |
708 | |
709 e = lwasm_parse_expr(as, p); | |
710 if (!e) | |
711 { | |
712 lwasm_register_error(as, l, "Bad expression"); | |
713 return; | |
714 } | |
715 if (!lw_expr_istype(e, lw_expr_type_int)) | |
716 { | |
717 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
718 return; | |
719 } | |
720 if (lw_expr_intval(e) <= 0) | |
721 { | |
722 as -> skipcond = 1; | |
723 as -> skipcount = 1; | |
724 } | |
725 } | |
726 | |
727 PARSEFUNC(pseudo_parse_ifge) | |
728 { | |
729 lw_expr_t e; | |
730 | |
731 l -> len = 0; | |
732 | |
733 if (as -> skipcond && !(as -> skipmacro)) | |
734 { | |
735 as -> skipcount++; | |
736 skip_operand(p); | |
737 return; | |
738 } | |
739 | |
740 e = lwasm_parse_expr(as, p); | |
741 if (!e) | |
742 { | |
743 lwasm_register_error(as, l, "Bad expression"); | |
744 return; | |
745 } | |
746 if (!lw_expr_istype(e, lw_expr_type_int)) | |
747 { | |
748 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
749 return; | |
750 } | |
751 if (lw_expr_intval(e) < 0) | |
752 { | |
753 as -> skipcond = 1; | |
754 as -> skipcount = 1; | |
755 } | |
756 } | |
757 | |
758 PARSEFUNC(pseudo_parse_iflt) | |
759 { | |
760 lw_expr_t e; | |
761 | |
762 l -> len = 0; | |
763 | |
764 if (as -> skipcond && !(as -> skipmacro)) | |
765 { | |
766 as -> skipcount++; | |
767 skip_operand(p); | |
768 return; | |
769 } | |
770 | |
771 e = lwasm_parse_expr(as, p); | |
772 if (!e) | |
773 { | |
774 lwasm_register_error(as, l, "Bad expression"); | |
775 return; | |
776 } | |
777 if (!lw_expr_istype(e, lw_expr_type_int)) | |
778 { | |
779 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
780 return; | |
781 } | |
782 if (lw_expr_intval(e) >= 0) | |
783 { | |
784 as -> skipcond = 1; | |
785 as -> skipcount = 1; | |
786 } | |
787 } | |
788 | |
789 PARSEFUNC(pseudo_parse_ifle) | |
790 { | |
791 lw_expr_t e; | |
792 | |
793 l -> len = 0; | |
794 | |
795 if (as -> skipcond && !(as -> skipmacro)) | |
796 { | |
797 as -> skipcount++; | |
798 skip_operand(p); | |
799 return; | |
800 } | |
801 | |
802 e = lwasm_parse_expr(as, p); | |
803 if (!e) | |
804 { | |
805 lwasm_register_error(as, l, "Bad expression"); | |
806 return; | |
807 } | |
808 if (!lw_expr_istype(e, lw_expr_type_int)) | |
809 { | |
810 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
811 return; | |
812 } | |
813 if (lw_expr_intval(e) > 0) | |
814 { | |
815 as -> skipcond = 1; | |
816 as -> skipcount = 1; | |
817 } | |
818 } | |
819 | |
820 PARSEFUNC(pseudo_parse_endc) | |
821 { | |
822 l -> len = 0; | |
823 if (as -> skipcond && !(as -> skipmacro)) | |
824 { | |
825 as -> skipcount--; | |
826 if (as -> skipcount < 0) | |
827 as -> skipcond = 0; | |
828 } | |
829 } | |
830 | |
831 PARSEFUNC(pseudo_parse_else) | |
832 { | |
833 l -> len = 0; | |
834 | |
835 if (as -> skipmacro) | |
836 return; | |
837 | |
838 if (as -> skipcond) | |
839 { | |
840 if (as -> skipcount == 1) | |
841 { | |
842 as -> skipcount = 0; | |
843 as -> skipcond = 0; | |
844 } | |
845 return; | |
846 } | |
847 as -> skipcond = 1; | |
848 as -> skipcount = 1; | |
849 } | |
850 | |
851 PARSEFUNC(pseudo_parse_ifdef) | |
852 { | |
853 char *sym; | |
854 int i; | |
855 struct symtabe *s; | |
856 | |
857 l -> len = 0; | |
858 | |
859 if (as -> skipcond && !(as -> skipmacro)) | |
860 { | |
861 as -> skipcount++; | |
862 skip_operand(p); | |
863 return; | |
864 } | |
865 | |
866 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | |
867 /* do nothing */ ; | |
868 | |
869 sym = lw_strndup(*p, i); | |
870 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
871 s = lookup_symbol(as, l, sym); |
351 | 872 |
873 lw_free(sym); | |
874 | |
875 if (!s) | |
876 { | |
877 as -> skipcond = 1; | |
878 as -> skipcount = 1; | |
879 } | |
880 } | |
881 | |
882 PARSEFUNC(pseudo_parse_ifndef) | |
883 { | |
884 char *sym; | |
885 int i; | |
886 struct symtabe *s; | |
887 | |
888 l -> len = 0; | |
889 | |
890 if (as -> skipcond && !(as -> skipmacro)) | |
891 { | |
892 as -> skipcount++; | |
893 skip_operand(p); | |
894 return; | |
895 } | |
896 | |
897 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | |
898 /* do nothing */ ; | |
899 | |
900 sym = lw_strndup(*p, i); | |
901 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
902 s = lookup_symbol(as, l, sym); |
351 | 903 |
904 lw_free(sym); | |
905 | |
906 if (s) | |
907 { | |
908 as -> skipcond = 1; | |
909 as -> skipcount = 1; | |
910 } | |
911 } | |
912 | |
354 | 913 PARSEFUNC(pseudo_parse_error) |
914 { | |
915 lwasm_register_error(as, l, "User error: %s", *p); | |
916 skip_operand(p); | |
917 } | |
356 | 918 |
919 PARSEFUNC(pseudo_parse_includebin) | |
920 { | |
921 char *fn, *p2; | |
922 int delim = 0; | |
923 FILE *fp; | |
924 long flen; | |
925 | |
926 if (!**p) | |
927 { | |
928 lwasm_register_error(as, l, "Missing filename"); | |
929 return; | |
930 } | |
931 | |
932 if (**p == '"' || **p == '\'') | |
933 { | |
934 delim = **p; | |
935 (*p)++; | |
936 | |
937 for (p2 = *p; *p2 && *p2 != delim; p2++) | |
938 /* do nothing */ ; | |
939 } | |
940 else | |
941 { | |
942 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
943 /* do nothing */ ; | |
944 } | |
945 fn = lw_strndup(*p, p2 - *p); | |
946 | |
947 if (delim && **p) | |
948 (*p)++; | |
949 | |
950 fp = input_open_standalone(as, fn); | |
951 if (!fp) | |
952 { | |
953 lwasm_register_error(as, l, "Cannot open file"); | |
954 lw_free(fn); | |
955 return; | |
956 } | |
957 | |
958 l -> lstr = fn; | |
959 | |
960 fseek(fp, 0, SEEK_END); | |
961 flen = ftell(fp); | |
962 fclose(fp); | |
963 | |
964 l -> len = flen; | |
965 } | |
966 | |
967 EMITFUNC(pseudo_emit_includebin) | |
968 { | |
969 FILE *fp; | |
970 int c; | |
971 | |
972 fp = input_open_standalone(as, l -> lstr); | |
973 if (!fp) | |
974 { | |
975 lwasm_register_error(as, l, "Cannot open file (emit)!"); | |
976 return; | |
977 } | |
978 | |
979 for (;;) | |
980 { | |
981 c = fgetc(fp); | |
982 if (c == EOF) | |
983 { | |
984 fclose(fp); | |
985 return; | |
986 } | |
987 lwasm_emit(l, c); | |
988 } | |
989 } | |
990 | |
991 PARSEFUNC(pseudo_parse_include) | |
992 { | |
993 char *fn, *p2; | |
994 int delim = 0; | |
995 | |
996 if (!**p) | |
997 { | |
998 lwasm_register_error(as, l, "Missing filename"); | |
999 return; | |
1000 } | |
1001 | |
1002 if (**p == '"' || **p == '\'') | |
1003 { | |
1004 delim = **p; | |
1005 (*p)++; | |
1006 | |
1007 for (p2 = *p; *p2 && *p2 != delim; p2++) | |
1008 /* do nothing */ ; | |
1009 } | |
1010 else | |
1011 { | |
1012 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
1013 /* do nothing */ ; | |
1014 } | |
1015 fn = lw_strndup(*p, p2 - *p); | |
1016 | |
1017 if (delim && **p) | |
1018 (*p)++; | |
1019 | |
1020 input_open(as, fn); | |
1021 | |
1022 l -> len = 0; | |
1023 } | |
1024 | |
1025 PARSEFUNC(pseudo_parse_align) | |
1026 { | |
1027 lw_expr_t e; | |
1028 | |
1029 if (!**p) | |
1030 { | |
1031 lwasm_register_error(as, l, "Bad operand"); | |
1032 return; | |
1033 } | |
1034 | |
1035 e = lwasm_parse_expr(as, p); | |
1036 if (!e) | |
1037 { | |
1038 lwasm_register_error(as, l, "Bad operand"); | |
1039 return; | |
1040 } | |
1041 | |
1042 lwasm_save_expr(l, 0, e); | |
1043 | |
1044 if (**p == ',') | |
1045 { | |
1046 e = lwasm_parse_expr(as, p); | |
1047 } | |
1048 else | |
1049 { | |
1050 e = lw_expr_build(lw_expr_type_int, 0); | |
1051 } | |
1052 if (!e) | |
1053 { | |
1054 lwasm_register_error(as, l, "Bad padding"); | |
1055 return; | |
1056 } | |
1057 | |
1058 lwasm_save_expr(l, 1, e); | |
1059 } | |
1060 | |
1061 RESOLVEFUNC(pseudo_resolve_align) | |
1062 { | |
1063 lw_expr_t e; | |
1064 int align; | |
1065 | |
1066 e = lwasm_fetch_expr(l, 0); | |
1067 | |
1068 if (lw_expr_istype(e, lw_expr_type_int)) | |
1069 { | |
1070 align = lw_expr_intval(e); | |
1071 if (align < 1) | |
1072 { | |
1073 lwasm_register_error(as, l, "Invalid alignment"); | |
1074 return; | |
1075 } | |
1076 } | |
1077 | |
1078 if (lw_expr_istype(l -> addr, lw_expr_type_int)) | |
1079 { | |
1080 int a; | |
1081 a = lw_expr_intval(l -> addr); | |
1082 if (a % align == 0) | |
1083 { | |
1084 l -> len = 0; | |
1085 return; | |
1086 } | |
1087 l -> len = align - (a % align); | |
1088 return; | |
1089 } | |
1090 } | |
1091 | |
1092 EMITFUNC(pseudo_emit_align) | |
1093 { | |
1094 lw_expr_t e; | |
1095 int i; | |
1096 | |
1097 e = lwasm_fetch_expr(l, 1); | |
1098 for (i = 0; i < l -> len; i++) | |
1099 { | |
1100 lwasm_emitexpr(l, e, 1); | |
1101 } | |
1102 } |