diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 04c55914..490e6c21 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -390,7 +390,8 @@ ;; (i386:global->accu (+ (data-offset o g) d))))) (else (list (lambda (f g ta t d) (append (i386:value->accu (+ (data-offset o g) d)))))))) - (error "TODO ident-address->accu" o)))))) + (list (lambda (f g ta t d) + (i386:global->accu (+ ta (function-offset o f)))))))))) (define (ident-address->base info) (lambda (o) @@ -532,8 +533,20 @@ (append-text info ((ident->accu info) name))) ((initzer ,initzer) ((expr->accu info) initzer)) + + ;; &foo ((ref-to (p-expr (ident ,name))) - (append-text info ((ident->accu info) name))) + (append-text info ((ident-address->accu info) name))) + + ;; &f.field + ((ref-to (d-sel (ident ,field) (p-expr (ident ,array)))) + (let* ((type (ident->type info array)) + (fields (type->description info type)) + (field-size 4) ;; FIXME:4, not fixed + (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b)))))))) + (text (.text info))) + (append-text info (append ((ident->accu info) array) + (wrap-as (i386:accu+n offset)))))) ((sizeof-type (type-name (decl-spec-list (type-spec (struct-ref (ident ,name)))))) (let* ((type (list "struct" name)) @@ -576,6 +589,16 @@ (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array)))))) (append-text info (wrap-as (i386:mem+n->accu offset))))) + ((i-sel (ident ,field) (p-expr (ident ,array))) + (let* ((type (ident->type info array)) + (fields (type->description info type)) + (field-size 4) ;; FIXME:4, not fixed + (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b)))))))) + (text (.text info))) + (append-text info (append ((ident-address->accu info) array) + (wrap-as (i386:mem->accu)) + (wrap-as (i386:mem+n->accu offset)))))) + ;;; FIXME: FROM INFO ...only zero?! ((p-expr (fixed ,value)) (let ((value (cstring->number value))) @@ -1690,6 +1713,14 @@ ((ast->info info) `(decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (ident ,name))))))) + ;; struct foo* bar = expr; + ((decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (ref-to (p-expr (ident ,value))))))) + (if (.function info) (let* ((locals (add-local locals name (list "struct" type) 1)) + (info (clone info #:locals locals))) + (append-text info (append ((ident-address->accu info) value) + ((accu->ident info) name)))) + (error "ast->info: unsupported global:" o))) + ;; char *p = &bla; ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (ref-to (p-expr (ident ,value))))))) (let ((type (decl->type type))) diff --git a/scaffold/t.c b/scaffold/t.c index 5cbbd193..d2b4861d 100644 --- a/scaffold/t.c +++ b/scaffold/t.c @@ -478,6 +478,10 @@ struct_test () puts ("t: g_functions[g_function++] = g_foo;\n"); g_functions[g_function++] = g_foo; + puts ("t: pbar->arity == 1\n"); + struct function* barp = &g_bar; + if (barp->arity != 1) return 1; + int fn = 0; puts ("t: g_functions[g_cells[fn].cdr].arity\n"); if (g_functions[g_cells[fn].cdr].arity) return 1;