mescc: Tinycc support: foo[i].bar.baz.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 22 Jul 2017 21:39:39 +0000 (23:39 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Wed, 26 Jul 2017 09:36:08 +0000 (11:36 +0200)
* module/language/c99/compiler.mes (init-declr->pointer): Use -1 for array.
 (expr->accu): Implement foo[i].bar.baz.
* scaffold/tests/72-typedef-struct-def.c (test): Test it.

module/language/c99/compiler.mes
scaffold/tests/72-typedef-struct-def.c

index 3105e4adafeb133c71f13dd025d0818c65670bdd..921694d5550116aee6ccca34971815458eab1a7c 100644 (file)
                                      (wrap-as (i386:mem->accu))
                                      (wrap-as (i386:mem+n->accu offset))))))
 
+        ;; foo[i].bar.baz
+        ((d-sel (ident ,field1) (d-sel (ident ,field0) (array-ref ,index (p-expr (ident ,array)))))
+         (let ((info ((expr->accu* info) o)))
+           (append-text info (wrap-as (i386:mem->accu)))))
+
         ;;foo[index]->bar
         ((i-sel (ident ,field) (array-ref ,index ,array))
          (let ((info ((expr->accu* info) o)))
                                    (wrap-as (i386:mem->accu))
                                    (wrap-as (i386:accu+value offset))))))
 
+      ;; foo[i].bar.baz
+      ((d-sel (ident ,field1) (d-sel (ident ,field0) (array-ref ,index (p-expr (ident ,array)))))
+         (let* ((type0 (ident->type info array))
+                (type1 (field-type info `("struct" ,type0) field0))
+                (offset (+ (field-offset info `("struct" ,type0) field0)
+                           (field-offset info `("struct" ,type1) field1)))
+                (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array))))))
+           (append-text info (wrap-as (i386:accu+value offset)))))
+
       ;;foo[index]->bar
       ((i-sel (ident ,field) (array-ref ,index (p-expr (ident ,array))))
        (let* ((type (ident->type info array))
     ((d-sel (ident ,field) (p-expr (ident ,struct)))
      (let ((type0 (ident->type info struct)))
        (field-type info `("struct" ,type0) field)))
+    ((d-sel (ident ,field) (array-ref ,index (p-expr (ident ,array))))
+     (let ((type0 (ident->type info array)))
+       (field-type info `("struct" ,type0) field)))
     (_ (error "p-expr->type: unsupported: " o))))
 
 (define (local-var? o) ;; formals < 0, locals > 0
     ((ptr-declr ,pointer (ident ,name)) name)
     ((array-of (ident ,name)) name)
     ((array-of (ident ,name) ,index) name)
+    ((ptr-declr (pointer) (array-of (ident ,name))) name)
     ((ptr-declr (pointer) (array-of (ident ,name) (p-expr ,size))) name)
     (_ (error "init-declr->name unsupported: " o))))
 
   (pmatch o
     ((ident ,name) 0)
     ((ptr-declr ,pointer (ident ,name)) (ptr-declr->pointer pointer))
-    ((array-of (ident ,name) ,index) 1)
-    ((array-of (ident ,name)) 1)
+    ((array-of (ident ,name) ,index) -1)
+    ((array-of (ident ,name)) -1)
+    ((ptr-declr (pointer) (array-of (ident ,name))) -2)
     ((ptr-declr (pointer) (array-of (ident ,name) (p-expr ,size))) -2)
     (_ (error "init-declr->pointer unsupported: " o))))
 
 (define (initzer->accu info)
   (lambda (o)
     (pmatch o
-      ((initzer-list . ,initzers) (append-map (expr->accu info) initzers))
-      ((initzer (initzer-list . ,initzers)) (append-map (expr->accu info) initzers))
+      ((initzer-list . ,initzers) (fold (lambda (i info) ((expr->accu info) i)) info initzers))
+      ((initzer (initzer-list . ,initzers)) (fold (lambda (i info) ((expr->accu info) i)) info initzers))
       ((initzer ,initzer) ((expr->accu info) o))
       (() (append-text info (wrap-as (i386:value->accu 0))))
       (_ (error "initzer->accu: " o)))))
index 7ee2a98c7c98f61d7f98c483a06b2d35148f14ea..34637ef178d42d33ba11a119b6a6cf15701d91f7 100644 (file)
@@ -34,6 +34,8 @@ typedef struct
 } bar;
 
 
+bar baz[2] = {1, 2, 3, 4, 5, 6};
+
 //NYACC
 //#define offsetof(type, field) ((size_t) &((type *)0)->field)
 #if __MESC__
@@ -86,5 +88,14 @@ test ()
   printf ("(*pp)->b.i=%d\n", (*pp)->f.i);
   if ((*pp)->f.i != 2) return 1;
 
+  if (baz[0].i != 1) return 1;
+  printf ("baz[0].f.i=%d\n", baz[0].f.i);
+  if (baz[0].f.i != 2) return 1;
+
+  printf ("baz[1].i=%d\n", baz[1].i);
+  if (baz[1].i != 4) return 1;
+  printf ("baz[1].f.i=%d\n", baz[1].f.i);
+  if (baz[1].f.i != 5) return 1;
+
   return 0;
 }