mescc: Tinycc support: struct.struct.
authorJan Nieuwenhuizen <janneke@gnu.org>
Thu, 10 Aug 2017 19:36:49 +0000 (21:36 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Thu, 10 Aug 2017 19:36:49 +0000 (21:36 +0200)
* module/language/c99/compiler.mes (field:name):
  (field:pointer):
  (field:size):
  (field:type):
  (field-field):
  (field-offset):
  (struct-field): Support struct.struct.
* scaffold/tests/7i-struct-struct.c: Test it.
* make.scm (add-scaffold-test): Build it.

make.scm
module/language/c99/compiler.mes
scaffold/tests/7i-struct-struct.c [new file with mode: 0644]

index d245149de65bfb6b2235c6d2ba2f01fc191a5d57..fea0869a7121f68ad3d7fdbab0d2db76a597a7bf 100755 (executable)
--- a/make.scm
+++ b/make.scm
@@ -167,7 +167,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
    "7e-struct-array-access"
    "7f-struct-pointer-arithmetic"
    "7g-struct-byte-word-field"
-   "7h-struct-assign"))
+   "7h-struct-assign"
+   "7i-struct-struct"))
 
 (add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))
 
index 96f2d46caf4162757197056420980a1ebed69929..a1c9d1c17903f1aac0e40b35d7612f9dd1a85134 100644 (file)
 
 (define (field:name o)
   (pmatch o
+    ((struct (,name ,type ,size ,pointer) . ,rest) name)
     ((union (,name ,type ,size ,pointer) . ,rest) name)
-    ;;((union (,name ,type ,size) . ,rest) name)
     ((,name ,type ,size ,pointer) name)
-    ;;((,name ,type ,size) name)
     (_ (error "field:name not supported:" o))))
 
 (define (field:pointer o)
   (pmatch o
+    ((struct (,name ,type ,size ,pointer) . ,rest) pointer)
     ((union (,name ,type ,size ,pointer) . ,rest) pointer)
     ((,name ,type ,size ,pointer) pointer)
     (_ (error "field:name not supported:" o))))
 
 (define (field:size o)
   (pmatch o
+    ((struct . ,fields) (apply + (map field:size fields)))
     ((union . ,fields) 4) ;; FIXME
     ((,name ,type ,size ,pointer) size)
-    ;;((,name ,type ,size) size)
     (_ 4)))
 
 (define (field:type o)
   (pmatch o
     ((,name ,type ,size ,pointer) type)
-    ;;((,name ,type ,size) type)
     (_ (error "field:type:" o))))
 
 (define (get-type types o)
       (if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
           (let ((f (car fields)))
             (cond ((equal? (car f) field) f)
-                  ((and (eq? (car f) 'union)
+                  ((and (memq (car f) '(struct union))
                         (find (lambda (x) (equal? (car x) field)) (cdr f))))
                   (else (loop (cdr fields)))))))))
 
             (if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
                 (let ((f (car fields)))
                   (cond ((equal? (car f) field) offset)
+                        ((and (eq? (car f) 'struct)
+                              (find (lambda (x) (equal? (car x) field)) (cdr f))
+                              (apply + (cons offset
+                                             (map field:size
+                                                  (member field (reverse (cdr f))
+                                                          (lambda (a b)
+                                                            (equal? a (car b) field))))))))
                         ((and (eq? (car f) 'union)
                               (find (lambda (x) (equal? (car x) field)) (cdr f))
                               offset))
        (let ((size (ast-type->size info `("tag" ,type))))
          (list name `("tag" ,type) size 0)))
 
+      ((comp-decl (decl-spec-list (type-spec (struct-def (field-list . ,fields)))))
+       `(struct ,@(map (struct-field info) fields)))
+
       ((comp-decl (decl-spec-list (type-spec (union-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name))))
        (let ((size (ast-type->size info `("tag" ,type))))
          (list name `("tag" ,type) size 0)))
diff --git a/scaffold/tests/7i-struct-struct.c b/scaffold/tests/7i-struct-struct.c
new file mode 100644 (file)
index 0000000..8c8b678
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * Mes --- Maxwell Equations of Software
+ * Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+ *
+ * This file is part of Mes.
+ *
+ * Mes is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Mes is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "30-test.i"
+#include <stdio.h>
+
+struct s
+{
+  int bar;
+  int baz;
+};
+
+struct foo
+{
+  struct s s;
+};
+
+struct anon
+{
+  struct {
+    int bar;
+    int baz;
+  };
+};
+
+
+int
+test ()
+{
+  struct foo f = {1,2};
+  f.s.baz = 2; // FIXME
+  printf ("f.s.bar=%d\n", f.s.bar);
+  if (f.s.bar != 1) return 1;
+  printf ("f.s.baz=%d\n", f.s.baz);
+  if (f.s.baz != 2) return 2;
+
+  struct anon a = {3,4};
+  a.baz = 4; // FIXME
+  printf ("a.bar=%d\n", a.bar);
+  if (a.bar != 3) return 1;
+  printf ("a.baz=%d\n", a.baz);
+  if (a.baz != 4) return 1;
+  
+  return 0;
+}