mescc: Tinycc support: ((foo*) p) + n.
authorJan Nieuwenhuizen <janneke@gnu.org>
Mon, 31 Jul 2017 10:19:23 +0000 (12:19 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Mon, 31 Jul 2017 10:19:23 +0000 (12:19 +0200)
* module/language/c99/compiler.mes init-declr->pointer, expr->pointer,
  expr->size): support: ((foo*) p) + n.
  (expr->accu*): Consider field size for foo.bar[baz].
* scaffold/tests/7b-struct-int-array.c: Test it.
* make.scm (add-scaffold-test): Build it.

make.scm
module/language/c99/compiler.mes
scaffold/tests/7a-struct-char-array.c
scaffold/tests/7b-struct-int-array.c [new file with mode: 0644]

index 65c0710edb2c04429f7804331f7f56e54e2cd71f..f86dc99dc254c5ca965924838d8e639ecf034209 100755 (executable)
--- a/make.scm
+++ b/make.scm
@@ -160,7 +160,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
    "77-pointer-assign"
    "78-union-struct"
    "79-int-array"
-   "7a-struct-char-array"))
+   "7a-struct-char-array"
+   "7b-struct-int-array"))
 
 (add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))
 
index b3b464091152143fc944bc20e3aaed17039566fe..55bea4a8aa9e6429b241ad6791972e0e5e22ed39 100644 (file)
                 (info ((expr->accu info) a))
                 (value (cstring->number value))
                 (value (* size value)))
-           (stderr "sub[~s]: ~s + ~s\n" size a value)
            (append-text info (wrap-as (i386:accu+value (- value))))))
 
         ((sub ,a ,b)
               (type1 (field-type info type0 field0))
               (offset (field-offset info type0 field0))
               (info ((expr->accu info) index))
-              (size (ast-type->size info type1)))
+              (ptr (field-pointer info type0 field0))
+              (size (if (= ptr -1) (ast-type->size info type1)
+                        4)))
          (append-text info (append (wrap-as (append (i386:accu->base)
                                                     (if (eq? size 1) '()
                                                         (append
                                                              (i386:accu+accu))
                                                          (if (<= size 8) '()
                                                              (i386:accu+base))
-                                                         (i386:accu-shl 2))))
-                                            (i386:push-accu))
+                                                         (i386:accu-shl 2)))))
+                                   (wrap-as (i386:push-accu))
                                    ((ident-address->accu info) struct0)
                                    (wrap-as (append (i386:accu+value offset)
                                                     (i386:pop-base)
               (type1 (field-type info type0 field0))
               (offset (field-offset info type0 field0))
               (info ((expr->accu info) index))
-              (size (ast-type->size info type1)))
+              (ptr (field-pointer info type0 field0))
+              (size (if (= ptr -1) (ast-type->size info type1)
+                        4)))
          (append-text info (append (wrap-as (append (i386:accu->base)
                                                     (if (eq? size 1) '()
                                                         (append
                                                              (i386:accu+accu))
                                                          (if (<= size 8) '()
                                                              (i386:accu+base))
-                                                         (i386:accu-shl 2))))
-                                            (i386:push-accu))
+                                                         (i386:accu-shl 2)))))
+                                   (wrap-as (i386:push-accu))
                                    ((ident->accu info) struct0)
                                    (wrap-as (append (i386:accu+value offset)
                                                     (i386:pop-base)
 (define (ast-type->type info o)
   (pmatch o
     ((p-expr ,expr) (ast-type->type info (p-expr->type info o)))
-    ((decl-spec-list (type-spec (fixed-type ,type)))
-     (ast-type->type info type))
+    ((decl-spec-list ,type-spec)
+     (ast-type->type info type-spec))
     ((decl-spec-list (type-qual ,qual) (type-spec (fixed-type ,type)))
      (ast-type->type info type))
     ((struct-ref (ident (,type)))
     ((pre-dec ,a) (expr->pointer info a))
     ((post-inc ,a) (expr->pointer info a))
     ((post-dec ,a) (expr->pointer info a))
+    ((cast (type-name ,type (abs-declr ,pointer)) (p-expr (ident ,name)))
+     (let* ((type (ast-type->type info type))
+            (pointer0 (type:pointer type))
+            (pointer1 (ptr-declr->pointer pointer)))
+       (+ pointer0 pointer1)))
     (_ (stderr "expr->pointer: unsupported: ~s\n" o) 0)))
 
 (define (expr->size info o)
     ((pre-dec ,a) (expr->size info a))
     ((post-inc ,a) (expr->size info a))
     ((post-dec ,a) (expr->size info a))
+    ((cast (type-name ,type (abs-declr ,pointer)) (p-expr (ident ,name)))
+     (let ((type (ast-type->type info type)))
+       (type:size type)))
     (_ (stderr "expr->size: unsupported: ~s\n" o) 4)))
 
 (define (p-expr->type info o)
index ef5e11e5518065ac49b96950ace132d12fd8df40..3d9c45b2b8b95643db7fe092994d83da65864e4e 100644 (file)
@@ -70,14 +70,18 @@ test ()
   if (pfile->buffer[4] != '4') return 3;
 
   memcpy (pfile->buffer + 4, " ", 1);
+  eputs (file.buffer);
+  if (p[4] != ' ') return 4;
+  if (file.buffer[4] != ' ') return 5;
+  if (pfile->buffer[4] != ' ') return 6;
 
   strcpy (file.buffer, "0123456789\n");
   eputs (file.buffer);
   p[4] = 'A';
   eputs (file.buffer);
-  if (p[4] != 'A') return 4;
-  if (file.buffer[4] != 'A') return 5;
-  if (pfile->buffer[4] != 'A') return 6;
+  if (p[4] != 'A') return 7;
+  if (file.buffer[4] != 'A') return 8;
+  if (pfile->buffer[4] != 'A') return 9;
 
   return 0;
 }
diff --git a/scaffold/tests/7b-struct-int-array.c b/scaffold/tests/7b-struct-int-array.c
new file mode 100644 (file)
index 0000000..e402716
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*-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"
+
+struct foo {
+  int a;
+  int b;
+};
+
+struct foo g_foo[2] = {0,1,2,3};
+
+struct bar
+{
+  int bar[4];
+};
+
+struct bar g_bar = {101,102};
+typedef struct bar bar_struct;
+typedef struct bar foo_struct;
+
+int
+test ()
+{
+  if (g_foo[0].a != 0) return 1;
+  if (g_foo[0].b != 1) return 2;
+  if (g_foo[1].a != 2) return 3;
+  if (g_foo[1].b != 3) return 4;
+
+  void *p = &g_foo;
+  struct foo* pfoo = (((struct foo *)p) + 1);
+  if (pfoo->a != 2) return 5;
+  if (pfoo->b != 3) return 6;
+
+  int *pi = &g_foo;
+  if (*pi != 0) return 5;
+
+  pi = &g_bar;
+  if (*pi != 101) return 6;
+
+  struct bar bar = {0x22, 0x33};
+  pi = &bar;
+  if (*pi != 0x22) return 6;
+
+  bar_struct bs;
+  bs.bar[0] = 102;
+  pi = &bs;
+  if (*pi != 102) return 7;
+
+  foo_struct fs;
+  fs.bar[0] = 0x22;
+  fs.bar[1] = 0x33;
+
+  pi = &fs;
+  if (*pi != 0x22) return 7;
+  pi++;
+
+  if (*pi != 0x33) return 8;
+
+  foo_struct *pfs = &fs;
+  pfs->bar[3] = 0x44;
+  pfs->bar[4] = 0x55;
+
+  pi = &fs.bar[3];
+  if (*pi != 0x44) return 9;
+  pi++;
+  if (*pi != 0x55) return 10;
+
+  return 0;
+}