mescc: Tinycc support: Export nested struct definitions.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 19 May 2018 18:49:56 +0000 (20:49 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 19 May 2018 18:49:56 +0000 (20:49 +0200)
* module/language/c99/compiler.mes (struct-field): Support nested,
  named and anonymous enums.
  (field->info): New function.
  (type->info): Use it to reap nestedly defined enums, structs, unions.
  (decl->info): Likewise.
* scaffold/tests/t.c: Test it.

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

index ce29ea7c290d8efac4501380d0625b8c067d6868..fd1f2fc3f9dd9b8a359bffe75d36fdd433dd46a9 100644 (file)
 (define (struct-field info)
   (lambda (o)
     (pmatch o
-      ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ident ,name))))
+      ((comp-decl (decl-spec-list (type-spec (enum-def (ident ,name) (enum-def-list . ,fields)))) (comp-declr-list . ,decls))
+       (let (
+             ;;(constants (enum-def-list->constants (.constants info) fields))
+             ;;(type-entry (enum->type-entry name fields))
+             )
+         (append-map (lambda (o)
+                       ((struct-field info) `(comp-decl (decl-spec-list (type-spec "int")) (comp-declr-list ,o))))
+                     decls)))
+    ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ident ,name))))
        (list (cons name (ast->type type info))))
       ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ptr-declr ,pointer (ident ,name)))))
        (let ((rank (pointer->rank pointer)))
             (type (rank+= type rank)))
        (clone info #:types (acons name type (.types info)))))
     (((decl-spec-list (stor-spec (,store)) (type-spec ,type)) (init-declr-list . ,inits))
-     (let* ((type (ast->type type info))
+     (let* ((info (type->info type #f info))
+            (type (ast->type type info))
             (function (.function info)))
        (if (not function) (fold (cut init-declr->info type <> <>) info (map cdr inits))
            (let* ((tmp (clone info #:function #f #:globals '()))
 
     ((struct-def (field-list . ,fields))
      (mescc:trace name " <t>")
-     (let ((type-entry (struct->type-entry name (append-map (struct-field info) fields))))
+     (let* ((info (fold field->info info fields))
+            (type-entry (struct->type-entry name (append-map (struct-field info) fields))))
        (clone info #:types (cons type-entry (.types info)))))
 
     ((struct-def (ident ,name) (field-list . ,fields))
      (mescc:trace name " <t>")
-     (let ((type-entry (struct->type-entry name (append-map (struct-field info) fields))))
+     (let* ((info (fold field->info info fields))
+            (type-entry (struct->type-entry name (append-map (struct-field info) fields))))
        (clone info #:types (cons type-entry (.types info)))))
 
     ((union-def (ident ,name) (field-list . ,fields))
      info
      )))
 
+(define (field->info o info)
+  (pmatch o
+    ((comp-decl (decl-spec-list (type-spec (struct-def (ident ,name) (field-list . ,fields)))) . _)
+     (let* ((fields (append-map (struct-field info) fields))
+            (struct (make-type 'struct (apply + (map field:size fields)) fields)))
+       (clone info #:types (acons `(tag ,name) struct (.types info)))))
+    ((comp-decl (decl-spec-list (type-spec (union-def (ident ,name) (field-list . ,fields)))) . _)
+     (let* ((fields (append-map (struct-field info) fields))
+            (union (make-type 'union (apply + (map field:size fields)) fields)))
+       (clone info #:types (acons `(tag ,name) union (.types info))) ))
+    ((comp-decl (decl-spec-list (type-spec (enum-def (enum-def-list . ,fields)))) . _)
+     (let ((constants (enum-def-list->constants (.constants info) fields)))
+       (clone info
+              #:constants (append constants (.constants info)))))
+    ((comp-decl (decl-spec-list (type-spec (enum-def (ident ,name) (enum-def-list . ,fields)))) . _)
+     (let ((constants (enum-def-list->constants (.constants info) fields))
+           (type-entry (enum->type-entry name fields)))
+       (clone info
+              #:types (cons type-entry (.types info))
+              #:constants (append constants (.constants info)))))
+    (_ info)))
+
 ;;;\f fctn-defn
 (define (param-decl:get-name o)
   (pmatch o
index 9dad4c8948f63ccc4a95c73ffad9cb0e45e19da9..884a2a87cd3d298945c326deca4c52b77160ec5a 100644 (file)
@@ -49,6 +49,23 @@ int_array_t bar;
 typedef struct foo *foo_pointer_t;
 foo_pointer_t foep;
 
+struct nest
+{
+  struct bar
+  {
+    int baz;
+  } bar;
+  int i;
+  enum baz
+    {
+      bla
+    } baz;
+  enum
+    {
+      blub = 33,
+    } blub;
+};
+
 int
 test (struct foo* p)
 {
@@ -134,6 +151,16 @@ main (int argc, char* argv[])
   if (u.foo != 3) return 24;
   if (u.bla != 4) return 25;
 
+  struct nest n = {0};
+  if (n.bar.baz)
+    return 26;
+
+  if (bla != 0)
+    return 27;
+
+  if (blub != 33)
+    return 28;
+
   char buf[sizeof (g_f.string)];
   char buf1[sizeof (g_g->string)];