mescc: Tinycc support: int foo[bar] = {baz,...}.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 30 Jul 2017 06:27:05 +0000 (08:27 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 30 Jul 2017 06:27:05 +0000 (08:27 +0200)
* scaffold/tests/79-int-array.c: Test it.
* make.scm (add-scaffold-test): Build it.
* module/language/c99/compiler.mes (init-declr->count): New function.
  (decl->info): Support int foo[bar] = {baz,...}.

make.scm
module/language/c99/compiler.mes
scaffold/tests/79-int-array.c [new file with mode: 0644]

index 22e13c92b92425fdfa43bcfff3e50528fb9776b4..354e38e301834ae8b30fc6123980aacc7d4f9384 100755 (executable)
--- a/make.scm
+++ b/make.scm
@@ -158,7 +158,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
    "75-struct-union"
    "76-pointer-arithmetic"
    "77-pointer-assign"
-   "78-union-struct"))
+   "78-union-struct"
+   "79-int-array"))
 
 (add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))
 
index 5b7263b0dac0960080b692f42719039a432bc30a..ce540bf5404ac6ea662846ef748390f462ab8856 100644 (file)
     ((ptr-declr (pointer) (array-of (ident ,name) (p-expr ,size))) name)
     (_ (error "init-declr->name unsupported: " o))))
 
+(define (init-declr->count info o)
+  (pmatch o
+    ((array-of (ident ,name) ,count) (p-expr->number info count))
+    (_ #f)))
+
 (define (init-declr->pointer o)
   (pmatch o
     ((ident ,name) 0)
                       (globals (append globals (list global))))
                  (clone info #:globals globals)))))
 
+        ;; int foo[2] = { ... }
+        ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (array-of (ident ,name) ,count) (initzer (initzer-list . ,initzers)))))
+         (let* ((info (type->info info type))
+                (xtype type)
+                (type (decl->ast-type type))
+                (pointer -1)
+                (initzer-globals (filter identity (append-map (initzer->globals globals) initzers)))
+                (global-names (map car globals))
+                (initzer-globals (filter (lambda (g) (and g (not (member (car g) global-names)))) initzer-globals))
+                (initzers ((initzer->non-const info) initzers))
+                (info (append-text info (ast->comment o)))
+                (globals (append globals initzer-globals))
+                (info (clone info #:globals globals))
+                (size 4)
+                (count (p-expr->number info count))
+                (size (* count size)))
+           (if (.function info)
+               (let* ((local (car (add-local locals name type 1)))
+                      (local (make-local-entry name type pointer (+ (local:id (cdr local)) -1 (quotient (+ size 3) 4))))
+                      (locals (cons local locals))
+                      (info (clone info #:locals locals))
+                      (info (let loop ((info info) (initzers initzers) (id (local:id (cdr local))))
+                              (if (null? initzers) info
+                                  (let* ((info ((initzer->accu info) (car initzers)))
+                                         (info (append-text info (wrap-as (i386:accu->local id)))))
+                                    (loop info (cdr initzers) (1- id)))))))
+                 info)
+               (let* ((global (make-global-entry name type pointer (append-map (initzer->data info) initzers)))
+                      (globals (append globals (list global))))
+                 (clone info #:globals globals)))))
+
         ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr ,init . ,initzer)))
          (let* ((info (type->info info type))
                 (xtype type)
                                   (memq (type:type (ast-type->type info xtype)) '(struct union)))))
                 (pointer (if struct? -1 pointer))
                 (size (if (<= pointer 0) (ast-type->size info type)
-                          4)))
+                          4))
+                (count (init-declr->count info init)) ; array... split me up?
+                (size (if count (* count size) size)))
            (if (.function info)
                (let* ((locals (if (or (> pointer 0) (<= size 4)) (add-local locals name type pointer)
                                   (let* ((local (car (add-local locals name type 1)))
                                     (cons local locals))))
                       (info (clone info #:locals locals))
                       (info (if (null? initzer) info ((initzer->accu info) (car initzer))))
+                      ;; FIXME array...struct?
                       (info (if (null? initzer) info (append-text info ((accu->ident info) name)))))
                  info)
                (let* ((global (make-global-entry name type pointer (if (null? initzer) (string->list (make-string size #\nul))
diff --git a/scaffold/tests/79-int-array.c b/scaffold/tests/79-int-array.c
new file mode 100644 (file)
index 0000000..2658187
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*-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 <stdint.h>
+
+struct foo {
+  int *bar;
+};
+
+struct foo f;
+
+void *
+memcpy (void *dest, void const *src, size_t n)
+{
+  char* p = dest;
+  char* q = src;
+  while (n--) *p++ = *q++;
+  return dest;
+}
+
+int bla[6] = {0,0,11223344, 55667788,0,0};
+int g_c[2] = {101, 111};
+
+int
+test ()
+{
+  f.bar = bla;
+  struct foo *pf = &f;
+  int *b = pf->bar;
+  if (bla[2] != 11223344) return 1;
+  if (bla[3] != 55667788) return 2;
+  if (b[2] != 11223344) return 3;
+  if (b[3] != 55667788) return 4;
+
+  eputs ("g_c[0]="); eputs (itoa (g_c[0])); eputs ("\n");
+  eputs ("g_c[1]="); eputs (itoa (g_c[1])); eputs ("\n");
+
+  memcpy (&b[2], g_c, 2 * sizeof (int));
+  eputs ("b[2]:"); eputs (itoa (b[2])); eputs ("\n");
+
+  if (b[2] != 101) return 5;
+  eputs ("b[3]:"); eputs (itoa (b[3])); eputs ("\n");
+  if (b[3] != 111) return 6;
+
+  int c[2] = {201, 211};
+  eputs ("c[0]="); eputs (itoa (c[0])); eputs ("\n");
+  eputs ("c[1]="); eputs (itoa (c[1])); eputs ("\n");
+
+  memcpy (&b[4], c, 2 * sizeof (int));
+  eputs ("b[4]:"); eputs (itoa (b[4])); eputs ("\n");
+
+  if (b[4] != 201) return 5;
+  eputs ("b[5]:"); eputs (itoa (b[5])); eputs ("\n");
+  if (b[5] != 211) return 6;
+
+  return 0;
+}