mescc: Tinycc support: foo[index]->bar for array bar.
authorJan Nieuwenhuizen <janneke@gnu.org>
Fri, 4 Aug 2017 19:45:29 +0000 (21:45 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Fri, 4 Aug 2017 19:45:29 +0000 (21:45 +0200)
* module/language/c99/compiler.mes (expr->accu*): foo[index]->bar for array bar.
* scaffold/tests/7e-struct-array-access.c: Test it.
* make.scm (add-scaffold-test): Build it.

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

index 99dbf02ec624089842e750b6f484e5f788aafc1a..b4752f5325c9cf038c6937bae312a243d82d3c4b 100755 (executable)
--- a/make.scm
+++ b/make.scm
@@ -163,7 +163,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
    "7a-struct-char-array"
    "7b-struct-int-array"
    "7c-dynarray"
-   "7d-cast-char"))
+   "7d-cast-char"
+   "7e-struct-array-access"))
 
 (add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))
 
index 6a6c4d8e83b1e81213ba3d6636dc8ee26be1e288..a5ce8b581643683e2448e359c8a3a5d2267c85bd 100644 (file)
                 (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array))))))
            (append-text info (wrap-as (i386:mem+n->accu offset)))))
 
-        ((i-sel (ident ,field) (p-expr (ident ,array)))
-         (let* ((type (ident->type info array))
+        ((i-sel (ident ,field) (p-expr (ident ,struct)))
+         (let* ((type (ident->type info struct))
                 (offset (field-offset info type field))
                 (ptr (field-pointer info type field)))
            (if (= ptr -1)
-               (append-text info (append ((ident-address->accu info) array)
+               (append-text info (append ((ident-address->accu info) struct)
                                          (wrap-as (i386:mem->accu))
                                          (wrap-as (i386:accu+value offset))))
-               (append-text info (append ((ident-address->accu info) array)
+               (append-text info (append ((ident-address->accu info) struct)
                                          (wrap-as (i386:mem->accu))
                                          (wrap-as (i386:mem+n->accu offset)))))))
 
 
         ;;foo[index]->bar
         ((i-sel (ident ,field) (array-ref ,index ,array))
-         (let ((info ((expr->accu* info) o)))
-           (append-text info (wrap-as (i386:mem->accu)))))
+         (let* ((info ((expr->accu* info) o))
+                (type (p-expr->type info array))
+                (ptr (field-pointer info type field)))
+           (if (< ptr 0) info
+               (append-text info (wrap-as (i386:mem->accu))))))
 
         ((de-ref (p-expr (ident ,name)))
          (let* ((type (ident->type info name))
       ((i-sel (ident ,field) (array-ref ,index (p-expr (ident ,array))))
        (let* ((type (ident->type info array))
               (offset (field-offset info type field))
-              (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array))))))
-         (append-text info (append (wrap-as (i386:mem->accu))
-                                   (wrap-as (i386:accu+value offset))))))
+              (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array)))))
+              (ptr (field-pointer info type field)))
+         (append-text info (wrap-as (append (i386:mem->accu)
+                                            (i386:accu+value offset))))))
 
       (_ (error "expr->accu*: unsupported: " o)))))
 
diff --git a/scaffold/tests/7e-struct-array-access.c b/scaffold/tests/7e-struct-array-access.c
new file mode 100644 (file)
index 0000000..a645df1
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*-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>
+#include <stdlib.h>
+#include <string.h>
+
+struct symbol {
+  int len;
+  char str[10];
+  //int len;
+};
+
+struct symbol *list[2];
+struct symbol s0;
+struct symbol s1;
+struct symbol** plist;
+
+char *
+find0 ()
+{
+  strcpy (s0.str,  "foo");
+  strcpy (s1.str,  "bar");
+  list[0] = &s0;
+  list[1] = &s1;
+  //return s0.str;
+  //struct symbol *s = &s0;
+  struct symbol *s = list[0];
+  return s->str;
+}
+
+char *
+find1 ()
+{
+  return list[1]->str;
+}
+
+char *
+find2 ()
+{
+  plist = malloc (8);
+  struct symbol *p0 = malloc (sizeof (struct symbol));
+  struct symbol *p1 = malloc (sizeof (struct symbol));
+  strcpy (p0->str, "pfoo");
+  strcpy (p1->str, "pbar");
+  plist[0] = p0;
+  plist[1] = p1;
+  int i = 3;
+  return plist[i - 2]->str;
+}
+
+int
+test ()
+{
+  char *s = find0 ();
+  eputs (s); eputs ("\n");
+  if (strcmp (s, "foo")) return 1;
+  if (strcmp (list[0]->str, "foo")) return 2;
+
+  s = find1 ();
+  eputs (s); eputs ("\n");
+  if (strcmp (s, "bar")) return 3;
+  if (strcmp (list[1]->str, "bar")) return 4;
+
+  s = find2 ();
+  eputs (s); eputs ("\n");
+  if (strcmp (s, "pbar")) return 5;
+
+  list[1]->len = 2;
+  if (list[1]->len != 2) return 6;
+
+  return 0;
+}