mescc: Support struct pointers.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 6 May 2017 09:01:58 +0000 (11:01 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 6 May 2017 09:01:58 +0000 (11:01 +0200)
* module/language/c99/compiler.mes (expr->accu): Support
  &struct.field, struct->field.
  (ast->info): Support struct *foo = &bar;
* scaffold/t.c (struct_test): Test it.

module/language/c99/compiler.mes
scaffold/t.c

index 04c55914b5113e192bc88965ea11a7bd91312aea..490e6c2118e067ee97d4c26c94d8da8597a2b7f3 100644 (file)
                   ;;          (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)
          (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))
                 (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)))
            ((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)))
index 5cbbd193d09fa1c5a673690beb39dc32bead571a..d2b4861d13bd76401b1db26d04ce50a23df0dec9 100644 (file)
@@ -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;