mescc: Tinycc support: Implement ((struct foo*)p)->bar.
authorJan Nieuwenhuizen <janneke@gnu.org>
Fri, 11 May 2018 22:20:51 +0000 (00:20 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Fri, 11 May 2018 22:20:51 +0000 (00:20 +0200)
* module/language/c99/compiler.mes (expr->accu*):
* scaffold/tests/7p-struct-cast.c: Test it.
* build-aux/check-mescc.sh (tests): Run it.

build-aux/check-mescc.sh
module/language/c99/compiler.mes
scaffold/tests/7p-struct-cast.c [new file with mode: 0644]

index 59d2328dc97210709d1063266f30059af4bee464..094edae0c6693edd4e0b4cb1bc31d9d206018d41 100755 (executable)
@@ -112,6 +112,7 @@ t
 7m-struct-char-array-assign
 7n-struct-struct-array
 7o-struct-pre-post
+7p-struct-cast
 80-setjmp
 81-qsort
 82-define
index 947ab1df50e932388d704ee5353738b4c22f86fa..82bb1b50b5849f3636064334d59c0c309f6849bd 100644 (file)
             (info (expr->base array info)))
        (append-text info (wrap-as (i386:accu+base)))))
 
-    ;;((cast (type-name (decl-spec-list (type-spec (typename "Elf32_Rel"))) (abs-declr (pointer))) (add (i-sel (ident "data") (p-expr (ident "sr"))) (p-expr (ident "a")))))
-
     ((cast ,type ,expr)
-     (expr->accu expr info))
+     (expr->accu `(ref-to ,expr) info))
 
-    ;; ((post-dec (p-expr (ident "vtop"))))
-
-    ;; ((cast ,type ,expr)
-    ;;  (expr->accu `(ref-to ,expr) info))
+    ((add ,a ,b)
+     (let* ((rank (expr->rank info a))
+            (rank-b (expr->rank info b))
+            (type (ast->basic-type a info))
+            (struct? (structured-type? type))
+            (size (cond ((= rank 1) (ast-type->size info a))
+                        ((> rank 1) 4)
+                        ((and struct? (= rank 2)) 4)
+                        (else 1))))
+       (if (or (= size 1)) ((binop->accu* info) a b (i386:accu+base))
+           (let* ((info (expr->accu b info))
+                  (info (append-text info (wrap-as (append (i386:value->base size)
+                                                           (i386:accu*base)
+                                                           (i386:accu->base)))))
+                  (info (expr->accu* a info)))
+             (append-text info (wrap-as (i386:accu+base)))))))
+
+      ((sub ,a ,b)
+       (let* ((rank (expr->rank info a))
+              (rank-b (expr->rank info b))
+              (type (ast->basic-type a info))
+              (struct? (structured-type? type))
+              (size (->size type))
+              (size  (cond ((= rank 1) size)
+                           ((> rank 1) 4)
+                           ((and struct? (= rank 2)) 4)
+                           (else 1))))
+         (if (or (= size 1) (or (= rank-b 2) (= rank-b 1)))
+             (let ((info ((binop->accu* info) a b (i386:accu-base))))
+               (if (and (not (= rank-b 2)) (not (= rank-b 1))) info
+                   (append-text info (wrap-as (append (i386:value->base size)
+                                                      (i386:accu/base))))))
+             (let* ((info (expr->accu* b info))
+                    (info (append-text info (wrap-as (append (i386:value->base size)
+                                                             (i386:accu*base)
+                                                             (i386:accu->base)))))
+                    (info (expr->accu* a info)))
+               (append-text info (wrap-as (i386:accu-base)))))))
 
       ((pre-dec ,expr)
          (let* ((rank (expr->rank info expr))
            (info (expr->base b info)))
       (append-text info (wrap-as c)))))
 
+(define (binop->accu* info)
+  (lambda (a b c)
+    (let* ((info (expr->accu* a info))
+           (info (expr->base b info)))
+      (append-text info (wrap-as c)))))
+
 (define (wrap-as o . annotation)
   `(,@annotation ,o))
 
diff --git a/scaffold/tests/7p-struct-cast.c b/scaffold/tests/7p-struct-cast.c
new file mode 100644 (file)
index 0000000..e3bb51a
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * Mes --- Maxwell Equations of Software
+ * Copyright © 2018 Jan (janneke) 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/>.
+ */
+
+struct foo {int length; char* string;};
+
+int
+main ()
+{
+  struct foo f = {3, "foo"};
+  struct foo *pf = &f;
+  char *p = (char*)&f;
+  int i = 0;
+  i = ((struct foo*)p)->length;
+  i = 0;
+  i = ((struct foo*)(p + i))->length;
+
+  return i - 3;
+}