mescc: Enhance [int/pointer] array support.
authorJan Nieuwenhuizen <janneke@gnu.org>
Fri, 5 May 2017 07:24:19 +0000 (09:24 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Fri, 5 May 2017 07:24:19 +0000 (09:24 +0200)
* module/language/c99/compiler.mes (p-expr->type): Handle array-ref
  with any index.
  (ast->info): Support plain array declerations.
  (expr->accu): For size == 4, assume value in accu.  Fixes int/pointer arrays.
* scaffold/t.c: Test it.

module/language/c99/compiler.mes
scaffold/t.c

index 4a3008b96c28cab021aa9d33ca9a16945248d8c9..30980adccaba7f2dcb26829d9214154f210bee5b 100644 (file)
                      (info (append-text info (wrap-as (append (i386:pop-base))))))
                 (append-text info
                              (append (if (eq? size 1) (wrap-as (i386:byte-base->accu-address))
-                                         (append
-                                          (wrap-as (i386:base-address->accu-address))
-                                          (if (<= size 4) '()
-                                              (wrap-as (append (i386:accu+n 4)
-                                                               (i386:base+n 4)
-                                                               (i386:base-address->accu-address))))
-                                          (if (<= size 8) '()
-                                              (wrap-as (append (i386:accu+n 4)
-                                                               (i386:base+n 4)
-                                                               (i386:base-address->accu-address))))))))))
+                                         (if (<= size 4) (wrap-as (i386:base->accu-address))
+                                          (append
+                                           (wrap-as (i386:base-address->accu-address))
+                                           (wrap-as (append (i386:accu+n 4)
+                                                            (i386:base+n 4)
+                                                            (i386:base-address->accu-address)))
+                                           (if (<= size 8) '()
+                                               (wrap-as (append (i386:accu+n 4)
+                                                                (i386:base+n 4)
+                                                                (i386:base-address->accu-address)))))))))))
              (_ (error "expr->accu: unsupported assign: " a)))))
 
         (_ (error "expr->accu: unsupported: " o))))))
 (define (p-expr->type info o)
   (pmatch o
     ((p-expr (ident ,name)) (ident->type info name))
-    ((array-ref (p-expr (fixed ,index)) (p-expr (ident ,array)))
+    ((array-ref ,index (p-expr (ident ,array)))
      (ident->type info array))
     (_ (error "p-expr->type: unsupported: " o))))
 
              ))
 
         ;; struct foo bar[2];
-        ((decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (array-of (ident ,name) (p-expr (fixed ,count))))))
-         (let ((type (ast->type `(struct-ref (ident ,type)))))
+        ;; char arena[20000];
+        ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (array-of (ident ,name) (p-expr (fixed ,count))))))
+         (let ((type (ast->type type)))
            (if (.function info)
                (let* ((local (car (add-local locals name type -1)))
                       (count (string->number count))
                       (locals (cons local locals))
                       (info (clone info #:locals locals)))
                  info)
-               (error "ast->info: unsupported global: " o))))
-
-        ;; char arena[20000];
-        ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (array-of (ident ,name) (p-expr (fixed ,count))))))
-         (let ((type (ast->type type)))
-           (if (.function info) (error "ast->info: unsupported local: " o)
                (let* ((globals (.globals info))
                       (count (cstring->number count))
                       (size (type->size info type))
                       (globals (append globals (list array))))
                  (clone info #:globals globals)))))
 
+        ;; char* a[10];
+        ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (ptr-declr (pointer) (array-of (ident ,name) (p-expr (fixed ,count)))))))
+         (let ((type (ast->type type)))
+           (if (.function info)
+               (let* ((local (car (add-local locals name type -1)))
+                      (count (string->number count))
+                      (size (type->size info type))
+                      (local (make-local name type 1 (+ (local:id local) (* count size))))
+                      (locals (cons local locals))
+                      (info (clone info #:locals locals)))
+                 info)
+               (let* ((globals (.globals info))
+                      (count (cstring->number count))
+                      (size (type->size info type))
+                      (array (make-global name type 1 (string->list (make-string (* count size) #\nul))))
+                      (globals (append globals (list array))))
+                 (clone info #:globals globals)))))
 
         ;; struct foo bar;
         ((decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (ident ,name))))
index 80917998b19109231556e8d9ef3a6171620a534d..8e8fa8b21fce861ce9d67b502cf6df1553917e18 100644 (file)
@@ -190,6 +190,11 @@ array_test (char **e)
 {
   int i = 0;
 
+  puts ("a[i] = i-1\n");
+  int a[3];
+  for (int i=0; i < 3; i++) a[i] = i-1;
+  for (int i=0; i < 3; i++) if (a[i] != i-1) return 1;
+
   puts ("env [");
   puts (itoa (env));
   puts ("]\n");