diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 36a0629a..f6b6d18b 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -58,7 +58,9 @@ )) (define (write-any x) - (write-char (if (char? x) x (integer->char (if (>= x 0) x (+ x 256)))))) + (write-char (cond ((char? x) x) + ((number? x) (integer->char (if (>= x 0) x (+ x 256)))) + (else (stderr "write-any: ~a\n" x) barf)))) (define (ast:function? o) (and (pair? o) (eq? (car o) 'fctn-defn))) @@ -167,10 +169,7 @@ ;;(stderr "S=~a\n" o) (let* ((text (.text text+symbols+locals)) (symbols (.symbols text+symbols+locals)) - (locals (.locals text+symbols+locals)) - (text-list (text->list text)) - (prefix-list (symbols->text symbols 0 0)) - (statement-offset (- (+ (length prefix-list) (length text-list))))) + (locals (.locals text+symbols+locals))) ;; (stderr " tsl=~a\n" text+symbols+locals) ;; (stderr " locals=~s\n" locals) (pmatch o @@ -190,8 +189,7 @@ (append text (list (lambda (s t d) (i386:call s t d - (+ t (function-offset name s) - statement-offset) + (+ t (function-offset name s)) (+ d (data-offset string s)))))) (append symbols (list (string->symbols string))) locals))) @@ -202,10 +200,40 @@ (args (map (expr->arg symbols locals) expr-list))) (make-text+symbols+locals (append text - (list (lambda (s t d) (apply i386:call (cons* s t d (+ t (function-offset name s) statement-offset) args))))) + (list (lambda (s t d) (apply i386:call (cons* s t d (+ t (function-offset name s)) args))))) symbols locals))) - + + ((compd-stmt (block-item-list . ,statements)) + (let loop ((statements statements) + (text+symbols+locals (make-text+symbols+locals text symbols locals))) + (if (null? statements) text+symbols+locals + (let* ((statement (car statements)) + (r ((statement->text+symbols+locals text+symbols+locals) statement))) + (loop (cdr statements) r))))) + + ((if (gt (p-expr (ident ,name)) (p-expr (fixed ,value))) ,body) + (let* ((value (string->number value)) + + (t+s+l (make-text+symbols+locals '() symbols locals)) + + (body-t+s+l ((statement->text+symbols+locals t+s+l) body)) + (body-text (.text body-t+s+l)) + ;;(body-symbols (.symbols body-t+s+l)) + (symbols (.symbols body-t+s+l)) + (body-locals (.locals body-t+s+l)) + (body-length (length (text->list body-text)))) + + (make-text+symbols+locals + (append text + (list (lambda (s t d) + (append + (i386:local-test (assoc-ref locals name) value) + (i386:jump-le body-length)))) + body-text) + symbols + locals))) + ((while ,test ,body) (let* ((t+s+l (make-text+symbols+locals '() symbols locals)) @@ -227,7 +255,7 @@ (list (lambda (s t d) (i386:jump body-length))) body-text test-text - (list (lambda (s t d) (i386:test-jump (- (+ body-length test-length)))))) + (list (lambda (s t d) (i386:jump-nz (- (+ body-length test-length)))))) symbols locals))) @@ -399,8 +427,7 @@ (format (current-error-port) "compiling ~a\n" (.name o)) ;;(stderr "formals=~a\n" (.formals o)) (let* ((text (formals->text (.formals o))) - (locals (formals->locals (.formals o))) - (text-offset (length (symbols->text symbols 0 0)))) + (locals (formals->locals (.formals o)))) ;;(stderr "locals=~a\n" locals) (let loop ((statements (.statements o)) (text+symbols+locals (make-text+symbols+locals text symbols locals))) diff --git a/module/mes/elf-util.mes b/module/mes/elf-util.mes index 3231e7b0..72a5981e 100644 --- a/module/mes/elf-util.mes +++ b/module/mes/elf-util.mes @@ -53,7 +53,10 @@ (append-map cdr (filter function-symbol? (map cdr symbols)))) (define (symbols->text symbols t d) - (append-map (lambda (f) (f symbols t d)) (symbols->functions symbols))) + (let loop ((functions (symbols->functions symbols)) (text '())) + (if (null? functions) text + (loop (cdr functions) + (append text ((car functions) symbols (- (length text)) d)))))) (define (function-offset name symbols) (let* ((functions (filter function-entry? symbols)) diff --git a/module/mes/libc-i386.mes b/module/mes/libc-i386.mes index 0fe8df84..4a3fa51f 100644 --- a/module/mes/libc-i386.mes +++ b/module/mes/libc-i386.mes @@ -95,6 +95,9 @@ `(#xc7 #x45 ,(- 0 (* 4 n)) ; movl $,0x(%ebp) ,@(int->bv32 v))) +(define (i386:local-test n v) + `(#x83 #x7d ,(- 0 (* 4 n)) ,v)) ; cmpl $,0x(%ebp) + (define (i386:ret-local n) `( #x89 #x45 ,(- 0 (* 4 n)) ; mov %eax,-0x(%ebp) @@ -157,7 +160,10 @@ (define (i386:jump n) `(#xeb ,(if (>= n 0) n (- n 2)))) ; jmp -(define (i386:test-jump n) +(define (i386:jump-le n) + `(#x7e ,(if (>= n 0) n (- n 4)))) ; jle + +(define (i386:jump-nz n) `(#x84 #xc0 ; test %al,%al #x75 ,(if (>= n 0) n (- n 4)))) ; jne @@ -165,7 +171,8 @@ int strcmp (char const* a, char const* b) { - while (*a && *b && *a == *b) {*a++;b++;} + while (*a && *b && *a == *b) {*a++;b++; + } return *a == *b; } 08048150 : @@ -208,4 +215,3 @@ strcmp (char const* a, char const* b) 804819a: 5d pop %ebp 804819b: c3 ret !# - diff --git a/module/mes/libc-i386.scm b/module/mes/libc-i386.scm index 58cdb14d..9095076e 100644 --- a/module/mes/libc-i386.scm +++ b/module/mes/libc-i386.scm @@ -35,10 +35,13 @@ i386:function-locals i386:eputs i386:jump + i386:jump-nz + i386:jump-le i386:local-add i386:local-assign i386:local->accu i386:local->base + i386:local-test i386:mem->accu i386:mem-byte->accu i386:push-accu @@ -47,7 +50,6 @@ i386:ref-local i386:ret i386:ret-local - i386:test-jump i386:value->accu i386:write )) diff --git a/scaffold/micro-mes.c b/scaffold/micro-mes.c index fcb1d0f6..97b646c6 100644 --- a/scaffold/micro-mes.c +++ b/scaffold/micro-mes.c @@ -220,8 +220,11 @@ main (int argc, char *argv[]) { puts ("arg0="); puts (argv[0]); - puts ("\narg1="); - puts (argv[1]); + if (argc > 1) + { + puts ("\narg1="); + puts (argv[1]); + } puts ("\n"); eputs ("Strlen...\n"); puts ("Bye micro\n");