3 ;;; Mes --- Maxwell Equations of Software
4 ;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
6 ;;; This file is part of Mes.
8 ;;; Mes is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
13 ;;; Mes is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;;; GNU General Public License for more details.
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
23 ;;; compiler.mes produces an i386 binary from the C produced by
30 (set-port-encoding! (current-output-port) "ISO-8859-1"))
33 (mes-use-module (nyacc lang c99 parser))
34 (mes-use-module (mes elf-util))
35 (mes-use-module (mes pmatch))
36 (mes-use-module (mes elf))
37 (mes-use-module (mes as-i386))
38 (mes-use-module (mes libc))
39 (mes-use-module (mes optargs))))
41 (define (logf port string . rest)
42 (apply format (cons* port string rest))
46 (define (stderr string . rest)
47 (apply logf (cons* (current-error-port) string rest)))
49 (define (gnuc-xdef? name mode) (if (equal? name "__GNUC__") #f (eq? mode 'code)))
53 #:inc-dirs (string-split (getenv "C_INCLUDE_PATH") #\:)
65 (write-char (cond ((char? x) x)
66 ((and (number? x) (< (+ x 256) 0)) (format (current-error-port) "***BROKEN*** x=~a ==> ~a\n" x (dec->hex x)) (integer->char #xaa))
67 ((number? x) (integer->char (if (>= x 0) x (+ x 256))))
69 (stderr "write-any: proc: ~a\n" x)
70 (stderr " ==> ~a\n" (map dec->hex (x '() '() 0 0)))
72 (else (stderr "write-any: ~a\n" x) barf))))
74 (define (ast:function? o)
75 (and (pair? o) (eq? (car o) 'fctn-defn)))
79 ((fctn-defn _ (ftn-declr (ident ,name) _) _) name)
80 ((fctn-defn _ (ptr-declr (pointer) (ftn-declr (ident ,name) _)) _) name)
81 ((param-decl _ (param-declr (ident ,name))) name)
82 ((param-decl _ (param-declr (ptr-declr (pointer) (ident ,name)))) name)
83 ((param-decl _ (param-declr (ptr-declr (pointer) (array-of (ident ,name))))) name)
85 (format (current-error-port) "SKIP: .name =~a\n" o))))
89 ((param-decl (decl-spec-list (type-spec ,type)) _) (decl->type type))
90 ((param-decl ,type _) type)
92 (format (current-error-port) "SKIP: .type =~a\n" o))))
94 (define (.statements o)
96 ((fctn-defn _ (ftn-declr (ident ,name) _) (compd-stmt (block-item-list . ,statements))) statements)
97 ((fctn-defn _ (ptr-declr (pointer) (ftn-declr (ident ,name) _)) (compd-stmt (block-item-list . ,statements))) statements)))
99 (define <info> '<info>)
100 (define <types> '<types>)
101 (define <constants> '<constants>)
102 (define <functions> '<functions>)
103 (define <globals> '<globals>)
104 (define <init> '<init>)
105 (define <locals> '<locals>)
106 (define <function> '<function>)
107 (define <text> '<text>)
109 (define* (make o #:key (types '()) (constants '()) (functions '()) (globals '()) (init '()) (locals '()) (function #f) (text '()))
113 (cons <constants> constants)
114 (cons <functions> functions)
115 (cons <globals> globals)
117 (cons <locals> locals)
118 (cons <function> function)
119 (cons <text> text)))))
123 ((<info> . ,alist) (assq-ref alist <types>))))
125 (define (.constants o)
127 ((<info> . ,alist) (assq-ref alist <constants>))))
129 (define (.functions o)
131 ((<info> . ,alist) (assq-ref alist <functions>))))
135 ((<info> . ,alist) (assq-ref alist <globals>))))
139 ((<info> . ,alist) (assq-ref alist <init>))))
143 ((<info> . ,alist) (assq-ref alist <locals>))))
145 (define (.function o)
147 ((<info> . ,alist) (assq-ref alist <function>))))
151 ((<info> . ,alist) (assq-ref alist <text>))))
154 (and (pair? o) (eq? (car o) <info>)))
156 (define (clone o . rest)
158 (let ((types (.types o))
159 (constants (.constants o))
160 (functions (.functions o))
161 (globals (.globals o))
164 (function (.function o))
169 (constants constants)
170 (functions functions)
176 (make <info> #:types types #:constants constants #:functions functions #:globals globals #:init init #:locals locals #:function function #:text text))))))
178 (define (push-global globals)
182 (i386:push-global (+ (data-offset o g) d))))))
184 (define (push-local locals)
188 (i386:push-local (local:id o))))))
190 (define (push-global-address globals)
194 (i386:push-global-address (+ (data-offset o g) d))))))
196 (define (push-local-address locals)
200 (i386:push-local-address (local:id o))))))
202 (define push-global-de-ref push-global)
204 (define (push-local-de-ref locals)
208 (i386:push-local-de-ref (local:id o))))))
210 (define (string->global string)
211 (make-global (add-s:-prefix string) "string" 0 (append (string->list string) (list #\nul))))
213 (define (ident->global name type pointer value)
214 (make-global name type pointer (int->bv32 value)))
216 (define (make-local name type pointer id)
217 (cons name (list type pointer id)))
218 (define local:type car)
219 (define local:pointer cadr)
220 (define local:id caddr)
222 (define (push-ident info)
224 (let ((local (assoc-ref (.locals info) o)))
225 (if local ((push-local (.locals info)) local)
226 (let ((global (assoc-ref (.globals info) o)))
228 ((push-global (.globals info)) o) ;; FIXME: char*/int
229 (let ((constant (assoc-ref (.constants info) o)))
231 (list (lambda (f g ta t d)
233 (i386:value->accu constant)
235 TODO:push-function))))))))
237 (define (push-ident-address info)
239 (let ((local (assoc-ref (.locals info) o)))
240 (if local ((push-local-address (.locals info)) local)
241 ((push-global-address (.globals info)) o)))))
243 (define (push-ident-de-ref info)
245 (let ((local (assoc-ref (.locals info) o)))
246 (if local ((push-local-de-ref (.locals info)) local)
247 ((push-global-de-ref (.globals info)) o)))))
249 (define (expr->arg info) ;; FIXME: get Mes curried-definitions
251 (let ((text (.text info)))
252 ;;(stderr "expr->arg o=~s\n" o)
254 ((p-expr (fixed ,value))
255 (let ((value (cstring->number value)))
256 (clone info #:text (append text
260 (i386:value->accu value)
261 (i386:push-accu))))))))
263 ((neg (p-expr (fixed ,value)))
264 (let ((value (- (cstring->number value))))
265 (clone info #:text (append text
269 (i386:value->accu value)
270 (i386:push-accu))))))))
272 ((p-expr (string ,string))
273 (clone info #:text (append text ((push-global-address info) (add-s:-prefix string)))))
275 ((p-expr (ident ,name))
276 (clone info #:text (append text ((push-ident info) name))))
279 ((array-ref (p-expr (fixed ,index)) (p-expr (ident ,array)))
280 (let* ((index (cstring->number index))
281 (type (ident->type info array))
282 (size (type->size info type)))
285 ((ident->base info) array)
289 (i386:value->accu (* size index))
291 (i386:byte-base-mem->accu)
292 (i386:base-mem->accu))
293 (i386:push-accu))))))))
296 ((array-ref (p-expr (ident ,index)) (p-expr (ident ,array)))
297 (let* ((type (ident->type info array))
298 (size (type->size info type)))
299 (clone info #:text (append text
300 ((ident->base info) index)
301 (list (lambda (f g ta t d)
307 (if (= size 12) (i386:accu+base) '())
309 ((ident->base info) array)
310 (list (lambda (f g ta t d)
312 (i386:byte-base-mem->accu)
313 (i386:base-mem->accu))))
316 (i386:push-accu)))))))
318 ((de-ref (p-expr (ident ,name)))
319 (clone info #:text (append text ((push-ident-de-ref info) name))))
321 ((ref-to (p-expr (ident ,name)))
322 (clone info #:text (append text ((push-ident-address info) name))))
326 (let* (;;(empty (clone info #:text '()))
327 ;;(info ((ast->info empty) o))
328 (info ((ast->info info) o))
334 (i386:push-accu)))))))
338 (let* (;;(empty (clone info #:text '()))
339 ;;(expr ((expr->accu empty) `(d-sel ,@d-sel)))
340 (expr ((expr->accu info) `(d-sel ,@d-sel)))
344 (list (lambda (f g ta t d)
345 (i386:push-accu)))))))
348 ((p-expr (char ,char))
349 (let ((char (char->integer (car (string->list char)))))
352 (list (lambda (f g ta t d)
354 (i386:value->accu char)
355 (i386:push-accu)))))))
359 ;;;((add (p-expr (fixed ,value)) (d-sel (ident cdr) (array-ref (p-expr (ident x)) (p-expr (ident g_cells))))))
361 ((cast (type-name (decl-spec-list (type-spec (fixed-type _)))
362 (abs-declr (pointer)))
364 ((expr->arg info) cast))
367 ;; (stderr "catch: expr->arg=~s\n" o)
368 (let* ((info ((expr->accu info) o))
372 (list (lambda (f g ta t d)
375 (i386:push-accu))))))))
378 (stderr "SKIP: expr->arg=~s\n" o)
382 ;; FIXME: see ident->base
383 (define (ident->accu info)
385 (let ((local (assoc-ref (.locals info) o))
386 (global (assoc-ref (.globals info) o))
387 (constant (assoc-ref (.constants info) o)))
388 ;; (stderr "ident->accu: local[~a]: ~a\n" o (and local (local:id local)))
389 ;; (stderr "ident->accu: global[~a]: ~a\n" o global)
390 ;; (stderr "globals: ~a\n" (.globals info))
391 ;; (if (and (not global) (not (local:id local)))
392 ;; (stderr "globals: ~a\n" (map car (.globals info))))
394 (let* ((ptr (local:pointer local))
395 (type (ident->type info o))
396 (size (and type (type->size info type))))
397 ;;(stderr "ident->accu PTR[~a]: ~a\n" o ptr)
398 ;;(stderr "type: ~s\n" type)
399 ;;(stderr "ident->accu PTR[~a]: ~a\n" o ptr)
400 ;;(stderr "locals: ~s\n" locals)
402 ((-1) (list (lambda (f g ta t d)
403 (i386:local-ptr->accu (local:id local)))))
404 ((1) (list (lambda (f g ta t d)
405 (i386:local->accu (local:id local)))))
407 (list (lambda (f g ta t d)
409 (i386:byte-local->accu (local:id local))
410 (i386:local->accu (local:id local))))))))
412 (let ((ptr (ident->pointer info o)))
413 ;;(stderr "ident->accu PTR[~a]: ~a\n" o ptr)
415 ((-1) (list (lambda (f g ta t d)
416 (i386:global->accu (+ (data-offset o g) d)))))
417 (else (list (lambda (f g ta t d)
418 (i386:global-address->accu (+ (data-offset o g) d)))))))
420 (list (lambda (f g ta t d)
421 (i386:value->accu constant)))
422 (list (lambda (f g ta t d)
423 (i386:global->accu (+ ta (function-offset o f)))))))))))
425 (define (value->accu v)
426 (list (lambda (f g ta t d)
427 (i386:value->accu v))))
429 (define (accu->ident info)
431 (let ((local (assoc-ref (.locals info) o)))
433 (list (lambda (f g ta t d)
434 (i386:accu->local (local:id local))))
435 (list (lambda (f g ta t d)
436 (i386:accu->global (+ (data-offset o g) d))))))))
438 (define (base->ident info)
440 (let ((local (assoc-ref (.locals info) o)))
442 (list (lambda (f g ta t d)
443 (i386:base->local (local:id local))))
444 (list (lambda (f g ta t d)
445 (i386:base->global (+ (data-offset o g) d))))))))
447 (define (base->ident-address info)
449 (let ((local (assoc-ref (.locals info) o)))
451 (list (lambda (f g ta t d)
453 (i386:local->accu (local:id local))
454 (i386:byte-base->accu-address))))
455 TODO:base->ident-address-global))))
457 (define (value->ident info)
459 (let ((local (assoc-ref (.locals info) o)))
461 (list (lambda (f g ta t d)
462 (i386:value->local (local:id local) value)))
463 (list (lambda (f g ta t d)
464 (i386:value->global (+ (data-offset o g) d) value)))))))
466 (define (ident-add info)
468 (let ((local (assoc-ref (.locals info) o)))
470 (list (lambda (f g ta t d)
471 (i386:local-add (local:id local) n)))
472 (list (lambda (f g ta t d)
473 (i386:global-add (+ (data-offset o g) d) n)))))))
475 ;; FIXME: see ident->accu
476 (define (ident->base info)
478 (let ((local (assoc-ref (.locals info) o)))
479 ;;(stderr "ident->base: local[~a]: ~a\n" o (and local (local:id local)))
481 (let* ((ptr (local:pointer local))
482 (type (ident->type info o))
483 (size (and type (type->size info type))))
485 ((-1) (list (lambda (f g ta t d)
486 (i386:local-ptr->base (local:id local)))))
487 ((1) (list (lambda (f g ta t d)
488 (i386:local->base (local:id local)))))
490 (list (lambda (f g ta t d)
492 (i386:byte-local->base (local:id local))
493 (i386:local->base (local:id local))))))))
494 (let ((global (assoc-ref (.globals info) o) ))
496 (let ((ptr (ident->pointer info o)))
497 ;;(stderr "ident->accu PTR[~a]: ~a\n" o ptr)
499 ((-1) (list (lambda (f g ta t d)
500 (i386:global->base (+ (data-offset o g) d)))))
501 (else (list (lambda (f g ta t d)
502 (i386:global-address->base (+ (data-offset o g) d)))))))
503 (let ((constant (assoc-ref (.constants info) o)))
505 (list (lambda (f g ta t d)
506 (i386:value->base constant)))
507 (list (lambda (f g ta t d)
508 (i386:global->base (+ ta (function-offset o f)))))))))))))
510 (define (expr->accu info)
512 (let ((text (.text info))
513 (locals (.locals info))
514 (globals (.globals info)))
515 ;;(stderr "expr->accu o=~a\n" o)
517 ((p-expr (string ,string))
518 (clone info #:text (append text (list (lambda (f g ta t d)
519 ;;(stderr "OFF[~a]: ~a\n" string (data-offset string globals))
520 ;;(stderr "globals: ~s\n" (map car globals))
521 (i386:global->accu (+ (data-offset (add-s:-prefix string) globals) d)))))))
522 ((p-expr (fixed ,value))
523 (clone info #:text (append text (value->accu (cstring->number value)))))
524 ((p-expr (ident ,name))
525 (clone info #:text (append text ((ident->accu info) name))))
526 ((fctn-call . _) ((ast->info info) `(expr-stmt ,o)))
527 ((not (fctn-call . _)) ((ast->info info) o))
528 ((neg (p-expr (fixed ,value)))
529 (clone info #:text (append text (value->accu (- (cstring->number value))))))
531 ((initzer ,initzer) ((expr->accu info) initzer))
532 ((ref-to (p-expr (ident ,name)))
535 ((ident->accu info) name))))
537 ((sizeof-type (type-name (decl-spec-list (type-spec (struct-ref (ident ,name))))))
538 (let* ((type (list "struct" name))
539 (fields (or (type->description info type) '()))
540 (size (type->size info type)))
543 (list (lambda (f g ta t d)
545 (i386:value->accu size))))))))
548 ((array-ref (p-expr (fixed ,index)) (p-expr (ident ,array)))
549 (let* ((index (cstring->number index))
550 (type (ident->type info array))
551 (size (type->size info type)))
554 ((ident->base info) array)
555 (list (lambda (f g ta t d)
557 (i386:value->accu (* size index))
559 (i386:byte-base-mem->accu)
560 (i386:base-mem->accu)))))))))
563 ((array-ref (p-expr (ident ,index)) (p-expr (ident ,array)))
564 (let* ((type (ident->type info array))
565 (size (type->size info type)))
566 (clone info #:text (append text
567 ((ident->base info) index)
568 (list (lambda (f g ta t d)
574 (if (= size 12) (i386:accu+base) '())
576 ((ident->base info) array)
577 (list (lambda (f g ta t d)
579 (i386:byte-base-mem->accu)
580 (i386:base-mem->accu))))))))
583 ((d-sel (ident ,field) (p-expr (ident ,array)))
584 (let* ((type (ident->type info array))
585 (fields (type->description info type))
586 (field-size 4) ;; FIXME:4, not fixed
587 (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
591 ((ident->accu info) array)
592 (list (lambda (f g ta t d)
593 (i386:mem+n->accu offset)))))))
596 ((d-sel (ident ,field) (array-ref (p-expr (fixed ,index)) (p-expr (ident ,array))))
597 (let* ((type (ident->type info array))
598 (fields (or (type->description info type) '()))
599 (size (type->size info type))
600 (count (length fields))
601 (field-size 4) ;; FIXME:4, not fixed
602 (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
603 (index (cstring->number index))
607 (list (lambda (f g ta t d)
609 (i386:value->base index)
611 (if (> count 1) (i386:accu+accu) '())
612 (if (= count 3) (i386:accu+base) '())
614 ((ident->base info) array)
615 (list (lambda (f g ta t d)
616 (i386:base-mem+n->accu offset)))))))
619 ((d-sel (ident ,field) (array-ref (p-expr (ident ,index)) (p-expr (ident ,array))))
620 (let* ((type (ident->type info array))
621 (fields (or (type->description info type) '()))
622 (size (type->size info type))
623 (count (length fields))
624 (field-size 4) ;; FIXME:4, not fixed
625 (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
629 ((ident->base info) index)
630 (list (lambda (f g ta t d)
633 (if (> count 1) (i386:accu+accu) '())
634 (if (= count 3) (i386:accu+base) '())
636 ((ident->base info) array)
637 (list (lambda (f g ta t d)
638 (i386:base-mem+n->accu offset)))))))
640 ;; g_functions[g_cells[fn].cdr].arity
641 ;; INDEX0: g_cells[fn].cdr
643 ;;; index: (d-sel (ident ,cdr) (array-ref (p-expr (ident ,fn)) (p-expr (ident ,g_cells))))
644 ;;((d-sel (ident ,arity) (array-ref (d-sel (ident ,cdr) (array-ref (p-expr (ident ,fn)) (p-expr (ident ,g_cells)))) (p-expr (ident ,g_functions)))))
645 ((d-sel (ident ,field) (array-ref ,index (p-expr (ident ,array))))
646 (let* ((empty (clone info #:text '()))
647 (index ((expr->accu empty) index))
648 (type (ident->type info array))
649 (fields (or (type->description info type) '()))
650 (size (type->size info type))
651 (count (length fields))
652 (field-size 4) ;; FIXME:4, not fixed
653 (rest (or (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))
656 (offset (* field-size (1- (length rest))))
661 (list (lambda (f g ta t d)
664 (if (> count 1) (i386:accu+accu) '())
665 (if (= count 3) (i386:accu+base) '())
667 ((ident->base info) array)
668 (list (lambda (f g ta t d)
669 (i386:base-mem+n->accu offset)))))))
671 ;;; FIXME: FROM INFO ...only zero?!
672 ((p-expr (fixed ,value))
673 (let ((value (cstring->number value)))
676 (list (lambda (f g ta t d)
677 (i386:value->accu value)))))))
679 ((p-expr (char ,char))
680 (let ((char (char->integer (car (string->list char)))))
683 (list (lambda (f g ta t d)
684 (i386:value->accu char)))))))
686 ((p-expr (ident ,name))
689 ((ident->accu info) name))))
691 ((de-ref (p-expr (ident ,name)))
692 (let* ((type (ident->type info name))
693 (size (and type (type->size info type))))
696 ((ident->accu info) name)
697 (list (lambda (f g ta t d)
699 (i386:byte-mem->accu)
700 (i386:mem->accu))))))))
702 ;; GRR --> info again??!?
704 ((ast->info info) `(expr-stmt ,o)))
706 ((cond-expr . ,cond-expr)
707 ((ast->info info) `(expr-stmt ,o)))
710 ;;((post-inc ,expr) ((ast->info info) `(expr-stmt ,o)))
711 ((post-inc (p-expr (ident ,name)))
714 ((ident->accu info) name)
715 ((ident-add info) name 1))))
717 ;; GRR --> info again??!?
718 ((post-inc ,expr) ((ast->info info) `(expr-stmt ,o)))
719 ((post-dec ,expr) ((ast->info info) `(expr-stmt ,o)))
720 ((pre-inc ,expr) ((ast->info info) `(expr-stmt ,o)))
721 ((pre-dec ,expr) ((ast->info info) `(expr-stmt ,o)))
723 ((add (p-expr (ident ,name)) ,b)
724 (let* ((empty (clone info #:text '()))
725 (base ((expr->base empty) b)))
729 ((ident->accu info) name)
730 (list (lambda (f g ta t d)
731 (i386:accu+base)))))))
734 (let* ((empty (clone info #:text '()))
735 (accu ((expr->accu empty) a))
736 (base ((expr->base empty) b)))
741 (list (lambda (f g ta t d)
742 (i386:accu+base)))))))
745 (let* ((empty (clone info #:text '()))
746 (accu ((expr->accu empty) a))
747 (base ((expr->base empty) b)))
752 (list (lambda (f g ta t d)
753 (i386:accu-base)))))))
755 ((lshift ,a (p-expr (fixed ,value)))
756 (let* ((empty (clone info #:text '()))
757 (accu ((expr->accu empty) a))
758 (value (cstring->number value)))
762 (list (lambda (f g ta t d)
763 (i386:accu-shl value)))))))
766 (let* ((empty (clone info #:text '()))
767 (accu ((expr->accu empty) a))
768 (base ((expr->base empty) b)))
773 (list (lambda (f g ta t d)
774 (i386:accu/base)))))))
777 (let* ((empty (clone info #:text '()))
778 (accu ((expr->accu empty) a))
779 (base ((expr->base empty) b)))
781 (append text ;;FIXME:empty
784 (list (lambda (f g ta t d)
785 (i386:accu%base)))))))
788 (let* ((empty (clone info #:text '()))
789 (accu ((expr->accu empty) a))
790 (base ((expr->base empty) b)))
795 (list (lambda (f g ta t d)
796 (i386:accu*base)))))))
798 ;; FIXME: c/p ast->info
800 (let* ((base ((expr->base info) a))
801 (empty (clone base #:text '()))
802 (accu ((expr->accu empty) b)))
805 (list (lambda (f g ta t d)
808 (list (lambda (f g ta t d)
810 (list (lambda (f g ta t d)
811 (i386:sub-base)))))))
813 ;; FIXME: c/p ast->info
815 (let* ((base ((expr->base info) a))
816 (empty (clone base #:text '()))
817 (accu ((expr->accu empty) b)))
821 (list (lambda (f g ta t d)
822 (i386:base-sub)))))))
824 ;; FIXME: ...c/p ast->info
825 ((neg (p-expr (ident ,name)))
826 (clone info #:text (append text
827 ((ident->base info) name)
828 (list (lambda (f g ta t d)
829 (i386:value->accu 0)))
830 (list (lambda (f g ta t d)
833 ;;((cast (type-name (decl-spec-list (type-spec (typename "SCM"))) (abs-declr (declr-fctn (declr-scope (abs-declr (pointer))) (param-list (param-decl (decl-spec-list (type-spec (typename "SCM")))))))) (d-sel (ident "function") (array-ref (d-sel (ident "cdr") (array-ref (p-expr (ident "fn")) (p-expr (ident "g_cells")))) (p-expr (ident "functions"))))))
835 ((expr->accu info) o))
837 ((assn-expr (p-expr (ident ,name)) ,op ,expr)
838 (let ((info ((ast->info info) o)))
839 (clone info #:text (append (.text info)
840 ((ident->accu info) name)))))
843 (format (current-error-port) "SKIP: expr->accu=~s\n" o)
847 (define (expr->base info)
849 (let ((info ((expr->accu info) o)))
852 (list (lambda (f g ta t d)
855 (list (lambda (f g ta t d)
858 (i386:pop-accu)))))))))
860 (define (expr->accu* info)
863 ;;(stderr "expr->accu* o=~s\n" o)
865 ((d-sel (ident ,field) (array-ref (p-expr (fixed ,index)) (p-expr (ident ,array))))
866 (let* ((type (ident->type info array))
867 (fields (or (type->description info type) '()))
868 (size (type->size info type))
869 (count (length fields))
870 (field-size 4) ;; FIXME:4, not fixed
871 (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
872 (index (cstring->number index))
876 (list (lambda (f g ta t d)
878 (i386:value->base index)
880 (if (> count 1) (i386:accu+accu) '())
881 (if (= count 3) (i386:accu+base) '())
883 ;; de-ref: g_cells, non: arena
884 ;;((ident->base info) array)
885 ((ident->base info) array)
886 (list (lambda (f g ta t d)
889 (i386:accu+value offset))))))))
892 ((d-sel (ident ,field) (array-ref (p-expr (ident ,index)) (p-expr (ident ,array))))
893 (let* ((type (ident->type info array))
894 (fields (or (type->description info type) '()))
895 (size (type->size info type))
896 (count (length fields))
897 (field-size 4) ;; FIXME:4, not fixed
898 (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
902 ((ident->base info) index)
903 (list (lambda (f g ta t d)
906 (if (> count 1) (i386:accu+accu) '())
907 (if (= count 3) (i386:accu+base) '())
909 ;; de-ref: g_cells, non: arena
910 ;;((ident->base info) array)
911 ((ident->base info) array)
912 (list (lambda (f g ta t d)
915 (i386:accu+value offset))))))))
917 ;;((d-sel (ident "cdr") (p-expr (ident "scm_make_cell"))))
918 ((d-sel (ident ,field) (p-expr (ident ,name)))
919 (let* ((type (ident->type info name))
920 (fields (or (type->description info type) '()))
921 (field-size 4) ;; FIXME
922 (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
926 ((ident->accu info) name)
927 (list (lambda (f g ta t d)
928 (i386:accu+value offset)))))))
931 (format (current-error-port) "SKIP: expr->accu*=~s\n" o)
936 (define (ident->constant name value)
939 (define (make-type name type size description)
940 (cons name (list type size description)))
942 (define (enum->type name fields)
943 (make-type name 'enum 4 fields))
945 (define (struct->type name fields)
946 (make-type name 'struct (* 4 (length fields)) fields)) ;; FIXME
948 (define (decl->type o)
950 ((fixed-type ,type) type)
951 ((struct-ref (ident ,name)) (list "struct" name))
952 ((decl (decl-spec-list (type-spec (struct-ref (ident ,name)))));; "scm"
953 (list "struct" name)) ;; FIXME
954 ((typename ,name) name)
956 (stderr "SKIP: decl type=~s\n" o)
960 (define (expr->global o)
962 ((p-expr (string ,string)) (string->global string))
965 (define (initzer->global o)
967 ((initzer ,initzer) (expr->global initzer))
970 (define (byte->hex o)
971 (string->number (string-drop o 2) 16))
974 (let ((prefix ".byte "))
975 (if (not (string-prefix? prefix o)) (begin (stderr "SKIP:~s\n" o)'())
976 (let ((s (string-drop o (string-length prefix))))
977 (map byte->hex (string-split s #\space))))))
979 (define (case->jump-info info)
981 (list (lambda (f g ta t d) (i386:Xjump n))))
983 (list (lambda (f g ta t d) (i386:Xjump-nz n))))
984 (define (statement->info info body-length)
987 ((break) (clone info #:text (append (.text info) (jump body-length)
990 ((ast->info info) o)))))
993 ((case (p-expr (ident ,constant)) (compd-stmt (block-item-list . ,elements)))
994 (lambda (body-length)
996 (define (test->text value clause-length)
997 (append (list (lambda (f g ta t d) (i386:accu-cmp-value value)))
998 (jump-nz clause-length)))
999 (let* ((value (assoc-ref (.constants info) constant))
1001 (clone info #:text (append (.text info) (test->text value 0))))
1002 (text-length (length (.text test-info)))
1003 (clause-info (let loop ((elements elements) (info test-info))
1004 (if (null? elements) info
1005 (loop (cdr elements) ((statement->info info body-length) (car elements))))))
1006 (clause-text (list-tail (.text clause-info) text-length))
1007 (clause-length (length (text->list clause-text))))
1008 (clone info #:text (append
1010 (test->text value clause-length)
1012 #:globals (.globals clause-info)))))
1014 ((case (p-expr (fixed ,value)) (compd-stmt (block-item-list . ,elements)))
1015 (lambda (body-length)
1017 (define (test->text value clause-length)
1018 (append (list (lambda (f g ta t d) (i386:accu-cmp-value value)))
1019 (jump-nz clause-length)))
1020 (let* ((value (cstring->number value))
1022 (clone info #:text (append (.text info) (test->text value 0))))
1023 (text-length (length (.text test-info)))
1024 (clause-info (let loop ((elements elements) (info test-info))
1025 (if (null? elements) info
1026 (loop (cdr elements) ((statement->info info body-length) (car elements))))))
1027 (clause-text (list-tail (.text clause-info) text-length))
1028 (clause-length (length (text->list clause-text))))
1029 (clone info #:text (append
1031 (test->text value clause-length)
1033 #:globals (.globals clause-info)))))
1035 ((case (neg (p-expr (fixed ,value))) ,statement)
1036 ((case->jump-info info) `(case (p-expr (fixed ,(string-append "-" value))) ,statement)))
1038 ((default (compd-stmt (block-item-list . ,elements)))
1039 (lambda (body-length)
1040 (let ((text-length (length (.text info))))
1041 (let loop ((elements elements) (info info))
1042 (if (null? elements) info
1043 (loop (cdr elements) ((statement->info info body-length) (car elements))))))))
1045 ((case (p-expr (ident ,constant)) ,statement)
1046 ((case->jump-info info) `(case (p-expr (ident ,constant)) (compd-stmt (block-item-list ,statement)))))
1048 ((case (p-expr (fixed ,value)) ,statement)
1049 ((case->jump-info info) `(case (p-expr (fixed ,value)) (compd-stmt (block-item-list ,statement)))))
1051 ((default ,statement)
1052 ((case->jump-info info) `(default (compd-stmt (block-item-list ,statement)))))
1054 (_ (stderr "no case match: ~a\n" o) barf)
1057 (define (test->jump->info info)
1058 (define (jump type . test)
1060 (let* ((text (.text info))
1061 (info (clone info #:text '()))
1062 (info ((ast->info info) o))
1063 (jump-text (lambda (body-length)
1064 (list (lambda (f g ta t d) (type body-length))))))
1065 (lambda (body-length)
1069 (if (null? test) '() (car test))
1070 (jump-text body-length)))))))
1073 ((le ,a ,b) ((jump i386:Xjump-ncz) o))
1074 ((lt ,a ,b) ((jump i386:Xjump-nc) o))
1075 ((ge ,a ,b) ((jump i386:Xjump-ncz) o))
1076 ((gt ,a ,b) ((jump i386:Xjump-nc) o))
1077 ((ne ,a ,b) ((jump i386:Xjump-nz) o))
1078 ((eq ,a ,b) ((jump i386:Xjump-nz) o))
1079 ((not _) ((jump i386:Xjump-z) o))
1081 (let* ((text (.text info))
1082 (info (clone info #:text '()))
1084 (a-jump ((test->jump->info info) a))
1085 (a-text (.text (a-jump 0)))
1086 (a-length (length (text->list a-text)))
1088 (b-jump ((test->jump->info info) b))
1089 (b-text (.text (b-jump 0)))
1090 (b-length (length (text->list b-text))))
1092 (lambda (body-length)
1095 (.text (a-jump (+ b-length body-length)))
1096 (.text (b-jump body-length)))))))
1098 (let* ((text (.text info))
1099 (info (clone info #:text '()))
1101 (a-jump ((test->jump->info info) a))
1102 (a-text (.text (a-jump 0)))
1103 (a-length (length (text->list a-text)))
1105 (jump-text (list (lambda (f g ta t d) (i386:Xjump 0))))
1106 (jump-length (length (text->list jump-text)))
1108 (b-jump ((test->jump->info info) b))
1109 (b-text (.text (b-jump 0)))
1110 (b-length (length (text->list b-text)))
1112 (jump-text (list (lambda (f g ta t d) (i386:Xjump b-length)))))
1114 (lambda (body-length)
1117 (.text (a-jump jump-length))
1119 (.text (b-jump body-length)))))))
1121 ((array-ref . _) ((jump i386:jump-byte-z
1122 (list (lambda (f g ta t d) (i386:accu-zero?)))) o))
1124 ((de-ref _) ((jump i386:jump-byte-z
1125 (list (lambda (f g ta t d) (i386:accu-zero?)))) o))
1127 ((assn-expr (p-expr (ident ,name)) ,op ,expr)
1130 ((ident->accu info) name)
1131 (list (lambda (f g ta t d) (i386:accu-zero?))))) o))
1133 (_ ((jump i386:Xjump-z (list (lambda (f g ta t d) (i386:accu-zero?)))) o)))))
1135 (define (cstring->number s)
1136 (cond ((string-prefix? "0x" s) (string->number (string-drop s 2) 16))
1137 ((string-prefix? "0" s) (string->number s 8))
1138 (else (string->number s))))
1140 (define (struct-field o)
1142 ((comp-decl (decl-spec-list (type-spec (enum-ref (ident ,type))))
1143 (comp-declr-list (comp-declr (ident ,name))))
1145 ((comp-decl (decl-spec-list (type-spec (fixed-type ,type))) (comp-declr-list (comp-declr (ident ,name))))
1147 ((comp-decl (decl-spec-list (type-spec (typename ,type))) (comp-declr-list (comp-declr (ident ,name))))
1149 ((comp-decl (decl-spec-list (type-spec (fixed-type ,type))) (comp-declr-list (comp-declr (ftn-declr (scope (ptr-declr (pointer) (ident ,name))) (param-list (param-decl (decl-spec-list (type-spec (void)))))))))
1150 (cons type name)) ;; FIXME function / int
1151 ((comp-decl (decl-spec-list (type-spec (fixed-type ,type))) (comp-declr-list (comp-declr (ptr-declr (pointer) (ident ,name)))))
1152 (cons type name)) ;; FIXME: ptr/char
1153 (_ (stderr "struct-field: no match: ~s\n" o) barf)))
1155 (define (ast->type o)
1159 ((struct-ref (ident ,type))
1160 (list "struct" type))
1161 (_ (stderr "SKIP: type=~s\n" o)
1164 (define i386:type-alist
1165 '(("char" . (builtin 1 #f))
1166 ("int" . (builtin 4 #f))))
1168 (define (type->size info o)
1169 ;;(stderr "types=~s\n" (.types info))
1170 ;;(stderr "type->size o=~s => ~s\n" o (cadr (assoc-ref (.types info) o)))
1172 ((decl-spec-list (type-spec (fixed-type ,type)))
1173 (type->size info type))
1174 ((decl-spec-list (type-spec (fixed-type ,type)) (type-qual ,qual))
1175 (type->size info type))
1176 (_ (let ((type (assoc-ref (.types info) o)))
1177 (if type (cadr type)
1179 (stderr "***TYPE NOT FOUND**: o=~s\n" o)
1183 (define (ident->decl info o)
1184 ;; (stderr "ident->decl o=~s\n" o)
1185 ;; (stderr " types=~s\n" (.types info))
1186 ;; (stderr " local=~s\n" (assoc-ref (.locals info) o))
1187 ;; (stderr " global=~s\n" (assoc-ref (.globals info) o))
1188 (or (assoc-ref (.locals info) o)
1189 (assoc-ref (.globals info) o)
1191 (stderr "NO IDENT: ~a\n" (assoc-ref (.functions info) o))
1192 (assoc-ref (.functions info) o))))
1194 (define (ident->type info o)
1195 (and=> (ident->decl info o) car))
1197 (define (ident->pointer info o)
1198 (let ((local (assoc-ref (.locals info) o)))
1199 (if local (local:pointer local)
1200 (or (and=> (ident->decl info o) global:pointer) 0))))
1202 (define (type->description info o)
1203 ;; (stderr "type->description =~s\n" o)
1204 ;; (stderr "types=~s\n" (.types info))
1205 ;; (stderr "type->description o=~s ==> ~s\n" o (caddr (assoc-ref (.types info) o)))
1206 ;; (stderr " assoc ~a\n" (assoc-ref (.types info) o))
1208 ((decl-spec-list (type-spec (fixed-type ,type)))
1209 (type->description info type))
1210 ((decl-spec-list (type-spec (fixed-type ,type)) (type-qual ,qual))
1211 (type->description info type))
1212 (_ (caddr (assoc-ref (.types info) o)))))
1214 (define (local? o) ;; formals < 0, locals > 0
1215 (positive? (local:id o)))
1217 (define (ast->info info)
1219 (let ((globals (.globals info))
1220 (locals (.locals info))
1221 (constants (.constants info))
1222 (text (.text info)))
1223 (define (add-local locals name type pointer)
1224 (let* ((id (1+ (length (filter local? (map cdr locals)))))
1225 (locals (cons (make-local name type pointer id) locals)))
1228 ;; (stderr "\n ast->info=~s\n" o)
1229 ;; (stderr " globals[~a=>~a]: ~a\n" (length globals) (length (append-map cdr globals)) (map (lambda (s) (if (string? s) (string-delete #\newline s))) (map car globals)))
1230 ;; (stderr " text=~a\n" text)
1231 ;; (stderr " info=~a\n" info)
1232 ;; (stderr " globals=~a\n" globals)
1234 (((trans-unit . _) . _)
1235 ((ast-list->info info) o))
1236 ((trans-unit . ,elements)
1237 ((ast-list->info info) elements))
1238 ((fctn-defn . _) ((function->info info) o))
1239 ((comment . _) info)
1240 ((cpp-stmt (define (name ,name) (repl ,value)))
1243 ((cast (type-name (decl-spec-list (type-spec (void)))) _)
1246 ;; FIXME: expr-stmt wrapper?
1249 ((assn-expr . ,assn-expr)
1250 ((ast->info info) `(expr-stmt ,o)))
1253 (let ((expr ((expr->accu info) `(d-sel ,@d-sel))))
1256 ((compd-stmt (block-item-list . ,statements)) ((ast-list->info info) statements))
1258 ((expr-stmt (fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)))
1259 (if (equal? name "asm") (let ((arg0 (cadr (cadar expr-list)))) ;; FIXME
1260 (clone info #:text (append text (list (lambda (f g ta t d) (asm->hex arg0))))))
1261 (let* ((globals (append globals (filter-map expr->global expr-list)))
1262 (info (clone info #:globals globals))
1263 (text-length (length text))
1264 (args-info (let loop ((expressions (reverse expr-list)) (info info))
1265 (if (null? expressions) info
1266 (loop (cdr expressions) ((expr->arg info) (car expressions))))))
1267 (text (.text args-info))
1268 (n (length expr-list)))
1269 (if (and (not (assoc-ref locals name))
1270 (assoc-ref (.functions info) name))
1271 (clone args-info #:text
1273 (list (lambda (f g ta t d)
1274 (i386:call f g ta t d (+ t (function-offset name f)) n))))
1276 (let* ((empty (clone info #:text '()))
1277 (accu ((expr->accu empty) `(p-expr (ident ,name)))))
1278 (clone args-info #:text
1281 (list (lambda (f g ta t d)
1282 (i386:call-accu f g ta t d n))))
1283 #:globals globals))))))
1285 ;;((expr-stmt (fctn-call (d-sel (ident "function") (array-ref (d-sel (ident "cdr") (array-ref (p-expr (ident "fn")) (p-expr (ident "g_cells")))) (p-expr (ident "g_functions")))) (expr-list))))
1286 ((expr-stmt (fctn-call ,function (expr-list . ,expr-list)))
1287 (let* ((globals (append globals (filter-map expr->global expr-list)))
1288 (info (clone info #:globals globals))
1289 (text-length (length text))
1290 (args-info (let loop ((expressions (reverse expr-list)) (info info))
1291 (if (null? expressions) info
1292 (loop (cdr expressions) ((expr->arg info) (car expressions))))))
1293 (text (.text args-info))
1294 (n (length expr-list))
1295 (empty (clone info #:text '()))
1296 (accu ((expr->accu empty) function)))
1300 (list (lambda (f g ta t d)
1301 (i386:call-accu f g ta t d n))))
1302 #:globals globals)))
1305 (let* ((text-length (length text))
1307 (test-jump->info ((test->jump->info info) test))
1308 (test+jump-info (test-jump->info 0))
1309 (test-length (length (.text test+jump-info)))
1311 (body-info ((ast->info test+jump-info) body))
1312 (text-body-info (.text body-info))
1313 (body-text (list-tail text-body-info test-length))
1314 (body-length (length (text->list body-text)))
1316 (text+test-text (.text (test-jump->info body-length)))
1317 (test-text (list-tail text+test-text text-length)))
1323 #:globals (.globals body-info))))
1325 ((if ,test ,then ,else)
1326 (let* ((text-length (length text))
1328 (test-jump->info ((test->jump->info info) test))
1329 (test+jump-info (test-jump->info 0))
1330 (test-length (length (.text test+jump-info)))
1332 (then-info ((ast->info test+jump-info) then))
1333 (text-then-info (.text then-info))
1334 (then-text (list-tail text-then-info test-length))
1335 (then-jump-text (list (lambda (f g ta t d) (i386:Xjump 0))))
1336 (then-jump-length (length (text->list then-jump-text)))
1337 (then-length (+ (length (text->list then-text)) then-jump-length))
1339 (then+jump-info (clone then-info #:text (append text-then-info then-jump-text)))
1340 (else-info ((ast->info then+jump-info) else))
1341 (text-else-info (.text else-info))
1342 (else-text (list-tail text-else-info (length (.text then+jump-info))))
1343 (else-length (length (text->list else-text)))
1345 (text+test-text (.text (test-jump->info then-length)))
1346 (test-text (list-tail text+test-text text-length))
1347 (then-jump-text (list (lambda (f g ta t d) (i386:Xjump else-length)))))
1355 #:globals (append (.globals then-info)
1356 (list-tail (.globals else-info) (length globals))))))
1358 ((expr-stmt (cond-expr ,test ,then ,else))
1359 (let* ((text-length (length text))
1361 (test-jump->info ((test->jump->info info) test))
1362 (test+jump-info (test-jump->info 0))
1363 (test-length (length (.text test+jump-info)))
1365 (then-info ((ast->info test+jump-info) then))
1366 (text-then-info (.text then-info))
1367 (then-text (list-tail text-then-info test-length))
1368 (then-length (length (text->list then-text)))
1370 (jump-text (list (lambda (f g ta t d) (i386:Xjump 0))))
1371 (jump-length (length (text->list jump-text)))
1373 (test+then+jump-info
1375 #:text (append (.text then-info) jump-text)))
1377 (else-info ((ast->info test+then+jump-info) else))
1378 (text-else-info (.text else-info))
1379 (else-text (list-tail text-else-info (length (.text test+then+jump-info))))
1380 (else-length (length (text->list else-text)))
1382 (text+test-text (.text (test-jump->info (+ then-length jump-length))))
1383 (test-text (list-tail text+test-text text-length))
1384 (jump-text (list (lambda (f g ta t d) (i386:Xjump else-length)))))
1392 #:globals (.globals else-info))))
1394 ((switch ,expr (compd-stmt (block-item-list . ,cases)))
1395 (let* ((expr ((expr->accu info) expr))
1396 (empty (clone info #:text '()))
1397 (case-infos (map (case->jump-info empty) cases))
1398 (case-lengths (map (lambda (c-j) (length (text->list (.text (c-j 0))))) case-infos))
1399 (cases-info (let loop ((cases cases) (info expr) (lengths case-lengths))
1400 (if (null? cases) info
1401 (let ((c-j ((case->jump-info info) (car cases))))
1402 (loop (cdr cases) (c-j (apply + (cdr lengths))) (cdr lengths)))))))
1405 ((for ,init ,test ,step ,body)
1406 (let* ((info (clone info #:text '())) ;; FIXME: goto in body...
1408 (info ((ast->info info) init))
1410 (init-text (.text info))
1411 (init-locals (.locals info))
1412 (info (clone info #:text '()))
1414 (body-info ((ast->info info) body))
1415 (body-text (.text body-info))
1416 (body-length (length (text->list body-text)))
1418 (step-info ((ast->info info) `(expr-stmt ,step)))
1419 (step-text (.text step-info))
1420 (step-length (length (text->list step-text)))
1422 (test-jump->info ((test->jump->info info) test))
1423 (test+jump-info (test-jump->info 0))
1424 (test-length (length (text->list (.text test+jump-info))))
1426 (skip-body-text (list (lambda (f g ta t d)
1427 (i386:Xjump (+ body-length step-length)))))
1429 (jump-text (list (lambda (f g ta t d)
1430 (i386:Xjump (- (+ body-length step-length test-length))))))
1431 (jump-length (length (text->list jump-text)))
1433 (test-text (.text (test-jump->info jump-length))))
1443 #:globals (append globals (list-tail (.globals body-info) (length globals)))
1446 ;; FIXME: support break statement (see switch/case)
1447 ((while ,test ,body)
1448 (let* ((skip-info (lambda (body-length)
1449 (clone info #:text (append text
1450 (list (lambda (f g ta t d) (i386:Xjump body-length)))))))
1451 (text (.text (skip-info 0)))
1452 (text-length (length text))
1454 (body-info (lambda (body-length)
1455 ((ast->info (skip-info body-length)) body)))
1456 (body-text (list-tail (.text (body-info 0)) text-length))
1457 (body-length (length (text->list body-text)))
1459 (body-info (body-info body-length))
1461 (empty (clone info #:text '()))
1462 (test-jump->info ((test->jump->info empty) test))
1463 (test+jump-info (test-jump->info 0))
1464 (test-length (length (text->list (.text test+jump-info))))
1466 (jump-text (list (lambda (f g ta t d)
1467 (i386:Xjump (- (+ body-length test-length))))))
1468 (jump-length (length (text->list jump-text)))
1470 (test-text (.text (test-jump->info jump-length))))
1476 #:globals (.globals body-info))))
1478 ((do-while ,body ,test)
1479 (let* ((text-length (length text))
1481 (body-info ((ast->info info) body))
1482 (body-text (list-tail (.text body-info) text-length))
1483 (body-length (length (text->list body-text)))
1485 (empty (clone info #:text '()))
1486 (test-jump->info ((test->jump->info empty) test))
1487 (test+jump-info (test-jump->info 0))
1488 (test-length (length (text->list (.text test+jump-info))))
1490 (jump-text (list (lambda (f g ta t d)
1491 (i386:Xjump (- (+ body-length test-length))))))
1492 (jump-length (length (text->list jump-text)))
1494 (test-text (.text (test-jump->info jump-length))))
1500 #:globals (.globals body-info))))
1502 ((labeled-stmt (ident ,label) ,statement)
1503 (let ((info (clone info #:text (append text (list label)))))
1504 ((ast->info info) statement)))
1506 ((goto (ident ,label))
1507 (let* ((jump (lambda (n) (i386:XXjump n)))
1508 (offset (+ (length (jump 0)) (length (text->list text)))))
1511 (list (lambda (f g ta t d)
1512 (jump (- (label-offset (.function info) label f) offset))))))))
1514 ;;; FIXME: only zero?!
1515 ((p-expr (ident ,name))
1518 ((ident->accu info) name)
1519 (list (lambda (f g ta t d)
1521 (i386:accu-zero?)))))))
1523 ((p-expr (fixed ,value))
1524 (let ((value (cstring->number value)))
1527 (list (lambda (f g ta t d)
1529 (i386:value->accu value)
1530 (i386:accu-zero?))))))))
1532 ((de-ref (p-expr (ident ,name)))
1535 ((ident->accu info) name)
1536 (list (lambda (f g ta t d)
1538 (i386:byte-mem->accu)))))))
1540 ((fctn-call . ,call)
1541 (let ((info ((ast->info info) `(expr-stmt ,o))))
1543 (append (.text info)
1544 (list (lambda (f g ta t d)
1545 (i386:accu-zero?)))))))
1548 ;;((post-inc ,expr) ((ast->info info) `(expr-stmt ,o)))
1549 ((post-inc (p-expr (ident ,name)))
1552 ((ident->accu info) name)
1553 ((ident-add info) name 1)
1554 (list (lambda (f g ta t d)
1556 (i386:accu-zero?)))))))
1557 ((post-inc ,expr) ((ast->info info) `(expr-stmt ,o)))
1558 ((post-dec ,expr) ((ast->info info) `(expr-stmt ,o)))
1559 ((pre-inc ,expr) ((ast->info info) `(expr-stmt ,o)))
1560 ((pre-dec ,expr) ((ast->info info) `(expr-stmt ,o)))
1563 ((expr-stmt (post-inc (p-expr (ident ,name))))
1564 (clone info #:text (append text ((ident-add info) name 1))))
1567 ((expr-stmt (pre-inc (p-expr (ident ,name))))
1568 (or (assoc-ref locals name) barf)
1571 ((ident-add info) name 1)
1572 ((ident->accu info) name)
1573 (list (lambda (f g ta t d)
1575 ;;(i386:local->accu (local:id (assoc-ref locals name)))
1576 (i386:accu-zero?)))))))
1579 ((expr-stmt (post-dec (p-expr (ident ,name))))
1580 (or (assoc-ref locals name) barf)
1583 ((ident->accu info) name)
1584 ((ident-add info) name -1)
1585 (list (lambda (f g ta t d)
1587 ;;(i386:local-add (local:id (assoc-ref locals name)) -1)
1588 (i386:accu-zero?)))))))
1591 ((expr-stmt (pre-dec (p-expr (ident ,name))))
1592 (or (assoc-ref locals name) barf)
1595 ((ident-add info) name -1)
1596 ((ident->accu info) name)
1597 (list (lambda (f g ta t d)
1599 ;;(i386:local-add (local:id (assoc-ref locals name)) -1)
1600 ;;(i386:local->accu (local:id (assoc-ref locals name)))
1601 (i386:accu-zero?)))))))
1604 (let* ((test-info ((ast->info info) expr)))
1606 (append (.text test-info)
1607 (list (lambda (f g ta t d)
1610 (i386:accu-zero?)))))
1611 #:globals (.globals test-info))))
1614 (let* ((base ((expr->base info) a))
1615 (empty (clone base #:text '()))
1616 (accu ((expr->accu empty) b)))
1620 (list (lambda (f g ta t d)
1623 (list (lambda (f g ta t d)
1625 (list (lambda (f g ta t d)
1626 (i386:sub-base)))))))
1629 (let* ((base ((expr->base info) a))
1630 (empty (clone base #:text '()))
1631 (accu ((expr->accu empty) b)))
1635 (list (lambda (f g ta t d)
1638 (list (lambda (f g ta t d)
1640 (list (lambda (f g ta t d)
1641 (i386:sub-base)))))))
1644 (let* ((base ((expr->base info) a))
1645 (empty (clone base #:text '()))
1646 (accu ((expr->accu empty) b)))
1650 (list (lambda (f g ta t d)
1653 (list (lambda (f g ta t d)
1655 (list (lambda (f g ta t d)
1656 (i386:sub-base)))))))
1659 (let* ((base ((expr->base info) a))
1660 (empty (clone base #:text '()))
1661 (accu ((expr->accu empty) b)))
1665 (list (lambda (f g ta t d)
1668 (list (lambda (f g ta t d)
1670 (list (lambda (f g ta t d)
1673 (i386:xor-zf))))))))
1676 (let* ((base ((expr->base info) a))
1677 (empty (clone base #:text '()))
1678 (accu ((expr->accu empty) b)))
1682 (list (lambda (f g ta t d)
1685 (list (lambda (f g ta t d)
1687 (list (lambda (f g ta t d)
1688 (i386:base-sub)))))))
1691 (let* ((base ((expr->base info) a))
1692 (empty (clone base #:text '()))
1693 (accu ((expr->accu empty) b)))
1697 (list (lambda (f g ta t d)
1700 (list (lambda (f g ta t d)
1702 (list (lambda (f g ta t d)
1703 (i386:base-sub)))))))
1705 ;; TODO: byte dinges
1707 (let* ((base ((expr->base info) a))
1708 (empty (clone base #:text '()))
1709 (accu ((expr->accu empty) b)))
1713 (list (lambda (f g ta t d)
1716 (list (lambda (f g ta t d)
1718 (list (lambda (f g ta t d)
1719 (i386:base-sub)))))))
1721 ((Xsub (de-ref (p-expr (ident ,a))) (de-ref (p-expr (ident ,b))))
1724 (list (lambda (f g ta t d)
1726 (i386:local->accu (local:id (assoc-ref locals a)))
1727 (i386:byte-mem->base)
1728 (i386:local->accu (local:id (assoc-ref locals b)))
1729 (i386:byte-mem->accu)
1730 (i386:byte-sub-base)))))))
1733 ((array-ref (p-expr (fixed ,index)) (p-expr (ident ,array)))
1734 (let* ((value (cstring->number value))
1735 (type (ident->type info array))
1736 (size (type->size info type)))
1739 ((ident->base info) array)
1740 (list (lambda (f g ta t d)
1742 (i386:value->accu (* size index))
1744 (i386:byte-base-mem->accu)
1745 (i386:base-mem->accu)))))))))
1748 ((array-ref (p-expr (ident ,index)) (p-expr (ident ,array)))
1749 (let* ((type (ident->type info array))
1750 (size (type->size info type)))
1753 ((ident->base info) index)
1754 (list (lambda (f g ta t d)
1760 (if (= size 12) (i386:accu+base) '())
1761 (i386:accu-shl 2))))))
1762 ((ident->base info) array)
1763 (list (lambda (f g ta t d)
1765 (i386:byte-base-mem->accu)
1766 (i386:base-mem->accu))))))))
1769 (let ((accu ((expr->accu info) expr)))
1771 (append (.text accu) (list (lambda (f g ta t d) (i386:ret)))))))
1774 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name))))
1775 (if (.function info)
1776 (clone info #:locals (add-local locals name type 0))
1777 (clone info #:globals (append globals (list (ident->global name type 0 0))))))
1780 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name) (initzer (p-expr (fixed ,value))))))
1781 (let ((value (cstring->number value)))
1782 (if (.function info)
1783 (let* ((locals (add-local locals name type 0))
1784 (info (clone info #:locals locals)))
1787 ((value->ident info) name value))))
1788 (clone info #:globals (append globals (list (ident->global name type 0 value)))))))
1791 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name) (initzer (p-expr (char ,value))))))
1792 (if (not (.function info)) decl-barf0)
1793 (let* ((locals (add-local locals name type 0))
1794 (info (clone info #:locals locals))
1795 (value (char->integer (car (string->list value)))))
1798 ((value->ident info) name value)))))
1801 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name) (initzer (neg (p-expr (fixed ,value)))))))
1802 (let ((value (- (cstring->number value))))
1803 (if (.function info)
1804 (let* ((locals (add-local locals name type 0))
1805 (info (clone info #:locals locals)))
1808 ((value->ident info) name value))))
1809 (clone info #:globals (append globals (list (ident->global name type 0 value)))))))
1812 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name) (initzer (p-expr (ident ,local))))))
1813 (if (not (.function info)) decl-barf2)
1814 (let* ((locals (add-local locals name type 0))
1815 (info (clone info #:locals locals)))
1818 ((ident->accu info) local)
1819 ((accu->ident info) name)))))
1822 ;;(decl (decl-spec-list (type-spec (fixed-type "char"))) (init-declr-list (init-declr (ptr-declr (pointer) (ident "p")) (initzer (p-expr (string "t.c\n"))))))
1823 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (p-expr (string ,string))))))
1824 (if (not (.function info)) decl-barf3)
1825 (let* ((locals (add-local locals name type 1))
1826 (globals (append globals (list (string->global string))))
1827 (info (clone info #:locals locals #:globals globals)))
1830 (list (lambda (f g ta t d)
1832 (i386:global->accu (+ (data-offset (add-s:-prefix string) g) d)))))
1833 ((accu->ident info) name)))))
1836 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (p-expr (fixed ,value))))))
1837 (if (not (.function info)) decl-barf3)
1838 (let* ((value (cstring->number value))
1839 (locals (add-local locals name type 1))
1840 (info (clone info #:locals locals)))
1843 (list (lambda (f g ta t d)
1844 (i386:value->accu value)))
1845 ((accu->ident info) name)))))
1847 ;; char arena[20000];
1848 ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (array-of (ident ,name) (p-expr (fixed ,count))))))
1849 (let ((type (ast->type type)))
1850 (if (.function info)
1852 (let* ((globals (.globals info))
1853 (count (cstring->number count))
1854 (size (type->size info type))
1855 ;;;;(array (make-global name type -1 (string->list (make-string (* count size) #\nul))))
1856 (array (make-global name type -1 (string->list (make-string (* count size) #\nul))))
1857 (globals (append globals (list array))))
1859 #:globals globals)))))
1861 ;;struct scm *g_cells = (struct scm*)arena;
1862 ((decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (cast (type-name (decl-spec-list (type-spec (struct-ref (ident ,=type)))) (abs-declr (pointer))) (p-expr (ident ,value)))))))
1863 ;;(stderr "0TYPE: ~s\n" type)
1864 (if (.function info)
1865 (let* ((locals (add-local locals name type 1))
1866 (info (clone info #:locals locals)))
1869 ((ident->accu info) name)
1870 ((accu->ident info) value)))) ;; FIXME: deref?
1871 (let* ((globals (append globals (list (ident->global name type 1 0))))
1872 (info (clone info #:globals globals)))
1875 ((ident->accu info) name)
1876 ((accu->ident info) value)))))) ;; FIXME: deref?
1879 ((decl (decl-spec-list (type-spec (typename ,type))) (init-declr-list (init-declr (ident ,name))))
1880 ;;(stderr "1TYPE: ~s\n" type)
1881 (if (.function info)
1882 (clone info #:locals (add-local locals name type 0))
1883 (clone info #:globals (append globals (list (ident->global name type 0 0))))))
1886 ((decl (decl-spec-list (type-spec (typename ,type))) (init-declr-list (init-declr (ident ,name) (initzer (p-expr (fixed ,value))))))
1887 ;;(stderr "2TYPE: ~s\n" type)
1888 (let ((value (cstring->number value)))
1889 (if (.function info)
1890 (let* ((locals (add-local locals name type 0))
1891 (info (clone info #:locals locals)))
1894 ((value->ident info) name value))))
1895 (let ((globals (append globals (list (ident->global name type 0 value)))))
1896 (clone info #:globals globals)))))
1898 ;; SCM g_stack = 0; // comment
1899 ((decl (decl-spec-list (type-spec (typename ,type))) (init-declr-list (init-declr (ident _) (initzer (p-expr (fixed _))))) (comment _))
1900 ((ast->info info) (list-head o (- (length o) 1))))
1903 ((decl (decl-spec-list (type-spec (typename ,type))) (init-declr-list (init-declr (ident ,name) (initzer (p-expr (ident ,local))))))
1904 ;;(stderr "3TYPE: ~s\n" type)
1905 (if (.function info)
1906 (let* ((locals (add-local locals name type 0))
1907 (info (clone info #:locals locals)))
1910 ((ident->accu info) local)
1911 ((accu->ident info) name))))
1912 (let* ((globals (append globals (list (ident->global name type 0 0))))
1913 (info (clone info #:globals globals)))
1916 ((ident->accu info) local)
1917 ((accu->ident info) name))))))
1919 ;; int (*function) (void) = g_functions[g_cells[fn].cdr].function;
1920 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ftn-declr (scope (ptr-declr (pointer) (ident ,name))) (param-list . ,param-list)) (initzer ,initzer))))
1921 (let* ((locals (add-local locals name type 1))
1922 (info (clone info #:locals locals))
1923 (empty (clone info #:text '()))
1924 (accu ((expr->accu empty) initzer)))
1929 ((accu->ident info) name)
1930 (list (lambda (f g ta t d)
1932 ;;(i386:value->base t)
1934 (i386:value->base ta)
1935 (i386:accu+base)))))
1938 ;; char *p = (char*)g_cells;
1939 ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (cast (type-name (decl-spec-list (type-spec (fixed-type ,=type))) (abs-declr (pointer))) (p-expr (ident ,value)))))))
1940 ;;(stderr "6TYPE: ~s\n" type)
1941 (if (.function info)
1942 (let* ((locals (add-local locals name type 1))
1943 (info (clone info #:locals locals)))
1946 ((ident->accu info) value)
1947 ((accu->ident info) name))))
1948 (let* ((globals (append globals (list (ident->global name type 1 0))))
1949 (here (data-offset name globals))
1950 (there (data-offset value globals)))
1953 #:init (append (.init info)
1954 (list (lambda (functions globals ta t d data)
1956 (list-head data here)
1958 ;;; char *x = arena;
1959 (int->bv32 (+ d (data-offset value globals)))
1961 ;;;(list-head (list-tail data there) 4)
1962 (list-tail data (+ here 4))))))))))
1964 ;; char *p = g_cells;
1965 ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (p-expr (ident ,value))))))
1966 ;;(stderr "7TYPE: ~s\n" type)
1967 (let ((type (decl->type type)))
1968 ;;(stderr "0DECL: ~s\n" type)
1969 (if (.function info)
1970 (let* ((locals (add-local locals name type 1))
1971 (info (clone info #:locals locals)))
1974 ((ident->accu info) value)
1975 ((accu->ident info) name))))
1976 (let* ((globals (append globals (list (ident->global name type 1 0))))
1977 (here (data-offset name globals)))
1980 #:init (append (.init info)
1981 (list (lambda (functions globals ta t d data)
1983 (list-head data here)
1985 ;;; char *x = arena;p
1986 (int->bv32 (+ d (data-offset value globals)))
1987 (list-tail data (+ here 4)))))))))))
1990 ((decl (decl-spec-list (type-spec (enum-def (ident ,name) (enum-def-list . ,fields)))))
1991 (let ((type (enum->type name fields))
1992 (constants (map ident->constant (map cadadr fields) (iota (length fields)))))
1994 #:types (append (.types info) (list type))
1995 #:constants (append constants (.constants info)))))
1998 ((decl (decl-spec-list (type-spec (struct-def (ident ,name) (field-list . ,fields)))))
1999 (let* ((type (struct->type (list "struct" name) (map struct-field fields))))
2000 ;;(stderr "type: ~a\n" type)
2001 (clone info #:types (append (.types info) (list type)))))
2004 ((expr-stmt (assn-expr (de-ref (post-inc (p-expr (ident ,name)))) (op ,op) ,b))
2005 (when (not (equal? op "="))
2006 (stderr "OOOPS0.0: op=~s\n" op)
2008 (let* ((empty (clone info #:text '()))
2009 (base ((expr->base empty) b)))
2013 ((base->ident-address info) name)
2014 ((ident-add info) name 1)))))
2017 ((expr-stmt (assn-expr (de-ref (post-dec (p-expr (ident ,name)))) (op ,op) ,b))
2018 (when (not (equal? op "="))
2019 (stderr "OOOPS0.0: op=~s\n" op)
2021 (let* ((empty (clone info #:text '()))
2022 (base ((expr->base empty) b)))
2026 ((base->ident-address info) name)
2027 ((ident-add info) name -1)))))
2031 ((expr-stmt (assn-expr (d-sel (ident ,field) . ,d-sel) (op ,op) ,b))
2032 (when (not (equal? op "="))
2033 (stderr "OOOPS0: op=~s\n" op)
2035 (let* ((empty (clone info #:text '()))
2036 (expr ((expr->accu* empty) `(d-sel (ident ,field) ,@d-sel))) ;; <-OFFSET
2037 (base ((expr->base empty) b))
2038 (type (list "struct" "scm")) ;; FIXME
2039 (fields (type->description info type))
2040 (size (type->size info type))
2041 (field-size 4) ;; FIXME:4, not fixed
2042 (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b)))))))) )
2043 (clone info #:text (append text
2046 (list (lambda (f g ta t d)
2047 ;;(i386:byte-base->accu-ref) ;; FIXME: size
2048 (i386:base->accu-address)
2056 ((expr-stmt (assn-expr (p-expr (ident ,name)) (op ,op) ,b))
2057 (when (and (not (equal? op "="))
2058 (not (equal? op "+="))
2059 (not (equal? op "-=")))
2060 (stderr "OOOPS1: op=~s\n" op)
2062 (let* ((empty (clone info #:text '()))
2063 (base ((expr->base empty) b)))
2064 (clone info #:text (append text
2066 (if (equal? op "=") '()
2067 (append ((ident->accu info) name)
2068 (list (lambda (f g ta t d)
2070 (if (equal? op "+=")
2073 (i386:accu->base))))))
2075 ((base->ident info) name)))))
2078 ((expr-stmt (assn-expr (de-ref (p-expr (ident ,array))) (op ,op) ,b))
2079 (when (not (equal? op "="))
2080 (stderr "OOOPS2: op=~s\n" op)
2082 (let* ((empty (clone info #:text '()))
2083 (base ((expr->base empty) b)))
2084 (clone info #:text (append text
2087 ((base->ident-address info) array)))))
2090 ((expr-stmt (assn-expr (array-ref (p-expr (fixed ,index)) (p-expr (ident ,array))) (op ,op) ,b))
2091 (when (not (equal? op "="))
2092 (stderr "OOOPS3: op=~s\n" op)
2094 (let* ((index (cstring->number index))
2095 (empty (clone info #:text '()))
2096 (base ((expr->base empty) b))
2097 (type (ident->type info array))
2098 (fields (or (type->description info type) '())) ;; FIXME: struct!
2099 (size (type->size info type))
2100 (count (length fields))
2101 (field-size 4) ;; FIXME:4, not fixed
2102 (ptr (ident->pointer info array)))
2106 (list (lambda (f g ta t d)
2108 (list (lambda (f g ta t d)
2110 (i386:value->base index)
2112 (if (> count 1) (i386:accu+accu) '())
2113 (if (= count 3) (i386:accu+base) '())
2114 (i386:accu-shl 2))))
2115 ((ident->base info) array)
2116 (list (lambda (f g tav t d)
2118 (list (lambda (f g ta t d)
2120 (if (eq? size 1) (list (lambda (f g ta t d)
2121 (i386:byte-base->accu-address)))
2123 (list (lambda (f g ta t d)
2124 (i386:base-address->accu-address)))
2126 (list (lambda (f g ta t d)
2130 (i386:base-address->accu-address))))
2133 (list (lambda (f g ta t d)
2137 (i386:base-address->accu-address))))
2141 ((expr-stmt (assn-expr (array-ref (p-expr (ident ,index)) (p-expr (ident ,array))) (op ,op) ,b))
2142 ;;(stderr "pointer_cells4[]: ~s\n" array)
2143 (when (not (equal? op "="))
2144 (stderr "OOOPS4: op=~s\n" op)
2146 (let* ((empty (clone info #:text '()))
2147 (base ((expr->base empty) b))
2148 (type (ident->type info array))
2149 (fields (or (type->description info type) '())) ;; FIXME: struct!
2150 (size (type->size info type))
2151 (count (length fields))
2152 (field-size 4) ;; FIXME:4, not fixed
2153 (ptr (ident->pointer info array)))
2157 (list (lambda (f g ta t d)
2159 ((ident->base info) index)
2160 (list (lambda (f g ta t d)
2163 (if (> count 1) (i386:accu+accu) '())
2164 (if (= count 3) (i386:accu+base) '())
2165 (i386:accu-shl 2))))
2166 ((ident->base info) array)
2167 (list (lambda (f g ta t d)
2169 (list (lambda (f g ta t d)
2171 (if (eq? size 1) (list (lambda (f g ta t d)
2172 (i386:byte-base->accu-address)))
2174 (list (lambda (f g ta t d)
2175 (i386:base-address->accu-address)))
2177 (list (lambda (f g ta t d)
2181 (i386:base-address->accu-address))))
2184 (list (lambda (f g ta t d)
2188 (i386:base-address->accu-address))))
2191 ;; g_functions[g_function++] = g_foo;
2192 ((expr-stmt (assn-expr (array-ref (post-inc (p-expr (ident ,index))) (p-expr (ident ,array))) (op ,op) ,b))
2193 (when (not (equal? op "="))
2194 (stderr "OOOPS5: op=~s\n" op)
2196 (let* ((empty (clone info #:text '()))
2197 (base ((expr->base empty) b))
2198 (type (ident->type info array))
2199 (fields (or (type->description info type) '())) ;; FIXME: struct!
2200 (size (type->size info type))
2201 (count (length fields))
2202 (field-size 4) ;; FIXME:4, not fixed
2203 (ptr (ident->pointer info array)))
2207 (list (lambda (f g ta t d)
2209 ((ident->base info) index)
2210 (list (lambda (f g ta t d)
2213 (if (> count 1) (i386:accu+accu) '())
2214 (if (= count 3) (i386:accu+base) '())
2215 (i386:accu-shl 2))))
2216 ((ident->base info) array)
2217 (list (lambda (f g ta t d)
2219 (list (lambda (f g ta t d)
2221 (if (eq? size 1) (list (lambda (f g ta t d)
2222 (i386:byte-base->accu-address)))
2224 (list (lambda (f g ta t d)
2225 (i386:base-address->accu-address)))
2227 (list (lambda (f g ta t d)
2231 (i386:base-address->accu-address))))
2234 (list (lambda (f g ta t d)
2238 (i386:base-address->accu-address))))
2240 ((ident-add info) index 1)))))
2244 ;; struct f = {...};
2245 ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (ident ,name) (initzer (initzer-list . ,initzers)))))
2246 (let* ((type (decl->type type))
2247 ;;(foo (stderr "1DECL: ~s\n" type))
2248 (fields (type->description info type))
2249 (size (type->size info type))
2250 (field-size 4)) ;; FIXME:4, not fixed
2251 ;;(stderr "7TYPE: ~s\n" type)
2252 (if (.function info)
2253 (let* ((globals (append globals (filter-map initzer->global initzers)))
2254 (locals (let loop ((fields (cdr fields)) (locals locals))
2255 (if (null? fields) locals
2256 (loop (cdr fields) (add-local locals "foobar" "int" 0)))))
2257 (locals (add-local locals name type -1))
2258 (info (clone info #:locals locals #:globals globals))
2259 (empty (clone info #:text '())))
2260 (let loop ((fields (iota (length fields))) (initzers initzers) (info info))
2261 (if (null? fields) info
2262 (let ((offset (* field-size (car fields)))
2263 (initzer (car initzers)))
2264 (loop (cdr fields) (cdr initzers)
2268 ((ident->accu info) name)
2269 (list (lambda (f g ta t d)
2271 (i386:accu->base))))
2272 (.text ((expr->accu empty) initzer))
2273 (list (lambda (f g ta t d)
2274 (i386:accu->base-address+n offset))))))))))
2275 (let* ((globals (append globals (filter-map initzer->global initzers)))
2276 (global (make-global name type -1 (string->list (make-string size #\nul))))
2277 (globals (append globals (list global)))
2278 (here (data-offset name globals))
2279 (info (clone info #:globals globals))
2281 (let loop ((fields (iota (length fields))) (initzers initzers) (info info))
2282 (if (null? fields) info
2283 (let ((offset (* field-size (car fields)))
2284 (initzer (car initzers)))
2285 (loop (cdr fields) (cdr initzers)
2289 (list (lambda (functions globals ta t d data)
2291 (list-head data (+ here offset))
2292 (initzer->data info functions globals ta t d (car initzers))
2293 (list-tail data (+ here offset field-size)))))))))))))))
2296 ;;char cc = g_cells[c].cdr; ==> generic?
2297 ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (ident ,name) (initzer ,initzer))))
2298 (let ((type (decl->type type)))
2299 (if (.function info)
2300 (let* ((locals (add-local locals name type 0))
2301 (info (clone info #:locals locals)))
2303 (append (.text ((expr->accu info) initzer))
2304 ((accu->ident info) name))))
2305 (let* ((globals (append globals (list (ident->global name type 1 0))))
2306 (here (data-offset name globals)))
2309 #:init (append (.init info)
2310 (list (lambda (functions globals ta t d data)
2312 (list-head data here)
2313 (initzer->data info functions globals ta t d initzer)
2314 (list-tail data (+ here 4)))))))))))
2317 ((decl (decl-spec-list (type-spec (typename ,type))) (init-declr-list (init-declr (ftn-declr (ident ,name) (param-list . ,param-list)))))
2320 ((decl (decl-spec-list (type-spec (typename ,type))) (init-declr-list (init-declr (ftn-declr (ident ,name) (param-list . ,param-list)))) (comment ,comment))
2323 ((decl (decl-spec-list (stor-spec (typedef)) (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name))))
2324 (let ((types (.types info)))
2325 (clone info #:types (cons (cons name (assoc-ref types type)) types))))
2327 ((decl (decl-spec-list (stor-spec (typedef)) ,type) ,name)
2328 (format (current-error-port) "SKIP: typedef=~s\n" o)
2332 (format (current-error-port) "SKIP: at=~s\n" o)
2336 (format (current-error-port) "SKIP: decl statement=~s\n" o)
2341 (format (current-error-port) "SKIP: statement=~s\n" o)
2345 (define (initzer->data info functions globals ta t d o)
2347 ((initzer (p-expr (fixed ,value))) (int->bv32 (cstring->number value)))
2348 ((initzer (neg (p-expr (fixed ,value)))) (int->bv32 (- (cstring->number value))))
2349 ((initzer (ref-to (p-expr (ident ,name))))
2350 ;;(stderr "INITZER[~a] => 0x~a\n" o (dec->hex (+ ta (function-offset name functions))))
2351 (int->bv32 (+ ta (function-offset name functions))))
2352 ((initzer (p-expr (ident ,name)))
2353 (let ((value (assoc-ref (.constants info) name)))
2355 ((initzer (p-expr (string ,string)))
2356 (int->bv32 (+ (data-offset (add-s:-prefix string) globals) d)))
2357 (_ (stderr "initzer->data:SKIP: ~s\n" o)
2361 (define (info->exe info)
2362 (display "dumping elf\n" (current-error-port))
2363 (map write-any (make-elf (.functions info) (.globals info) (.init info))))
2365 (define (.formals o)
2367 ((fctn-defn _ (ftn-declr _ ,formals) _) formals)
2368 ((fctn-defn _ (ptr-declr (pointer) (ftn-declr _ ,formals)) _) formals)
2369 (_ (format (current-error-port) ".formals: no match: ~a\n" o)
2372 (define (formal->text n)
2378 (define (formals->text o)
2380 ((param-list . ,formals)
2381 (let ((n (length formals)))
2382 (list (lambda (f g ta t d)
2384 (i386:function-preamble)
2385 (append-map (formal->text n) formals (iota n))
2386 (i386:function-locals))))))
2387 (_ (format (current-error-port) "formals->text: no match: ~a\n" o)
2390 (define (formal:ptr o)
2392 ((param-decl (decl-spec-list . ,decl) (param-declr (ptr-declr (pointer) . _)))
2394 ((param-decl (decl-spec-list . ,decl) (param-declr (ident ,name)))
2397 (stderr "formal:ptr[~a] => 0\n" o)
2400 (define (formals->locals o)
2402 ((param-list . ,formals)
2403 (let ((n (length formals)))
2404 (map make-local (map .name formals) (map .type formals) (map formal:ptr formals) (iota n -2 -1))))
2405 (_ (format (current-error-port) "formals->info: no match: ~a\n" o)
2408 (define (function->info info)
2411 ;;(stderr "formals=~a\n" (.formals o))
2412 (let* ((name (.name o))
2413 (text (formals->text (.formals o)))
2414 (locals (formals->locals (.formals o))))
2415 (format (current-error-port) "compiling ~a\n" name)
2416 ;;(stderr "locals=~a\n" locals)
2417 (let loop ((statements (.statements o))
2418 (info (clone info #:locals locals #:function (.name o) #:text text)))
2419 (if (null? statements) (clone info
2421 #:functions (append (.functions info) (list (cons name (.text info)))))
2422 (let* ((statement (car statements)))
2423 (loop (cdr statements)
2424 ((ast->info info) (car statements)))))))))
2426 (define (ast-list->info info)
2428 (let loop ((elements elements) (info info))
2429 (if (null? elements) info
2430 (loop (cdr elements) ((ast->info info) (car elements)))))))
2433 (let* ((ast (mescc))
2435 #:functions i386:libc
2436 #:types i386:type-alist))
2437 (ast (append libc ast))
2438 (info ((ast->info info) ast))
2439 (info ((ast->info info) _start)))