mescc: Tinycc support: struct char array assignment.
authorJan Nieuwenhuizen <janneke@gnu.org>
Mon, 7 Aug 2017 17:43:59 +0000 (19:43 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Mon, 7 Aug 2017 17:43:59 +0000 (19:43 +0200)
* module/language/c99/compiler.mes (expr->accu): struct char array assignment.
* scaffold/tests/7a-struct-char-array.c (test): Test it.

module/language/c99/compiler.mes
scaffold/tests/7a-struct-char-array.c

index 02e66bfc9b8f0afcc665d6a7576f26694d95ac36..f96208493400831e4688bb174758d65d564e23df 100644 (file)
                 (size (if (or (= ptr 1) (= ptr -1)) (ast-type->size info type)
                           4))
                 (info ((expr->accu* info) o)))
-           (append-text info (wrap-as (append (case size
-                                                ((1) (i386:byte-mem->accu))
-                                                ((4) (i386:mem->accu))
-                                                (else '())))))))
+           (append-text info (wrap-as (case size
+                                        ((1) (i386:byte-mem->accu))
+                                        ((4) (i386:mem->accu))
+                                        (else '()))))))
 
         ;; foo.bar[baz])
         ((array-ref ,index (d-sel (ident ,field0) (p-expr (ident ,struct0))))
                 (type0 (ident->type info struct0))
                 (type1 (field-type info type0 field0))
                 (ptr (field-pointer info type0 field0))
-                (size (ast-type->size info type1)))
-           (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu)
-                                          (i386:mem->accu))))))
+                (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1)
+                          4)))
+           (append-text info (wrap-as (case size
+                                        ((1) (i386:byte-mem->accu))
+                                        (else (i386:mem->accu)))))))
 
         ;; foo->bar[baz])
         ((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0))))
                 (type0 (ident->type info struct0))
                 (type1 (field-type info type0 field0))
                 (ptr (field-pointer info type0 field0))
-                (size (ast-type->size info type1)))
-           (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu)
-                                          (i386:mem->accu))))))
+                (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1)
+                          4)))
+           (append-text info (wrap-as (case size
+                                        ((1) (i386:byte-mem->accu))
+                                        (else (i386:mem->accu)))))))
 
         ;; <expr>[baz]
         ((array-ref ,index ,array)
            (pmatch a
              ((p-expr (ident ,name))
               (append-text info ((accu->ident info) name)))
-             ((d-sel (ident ,field) ,p-expr)
-              (let* ((type (p-expr->type info p-expr))
-                     (offset (field-offset info type field))
-                     (info ((expr->base* info) a)))
-                (append-text info (wrap-as (i386:accu->base-mem))))) ; FIXME: size
+             ((d-sel (ident ,field) ,expr)
+              (let* ((info ((expr->base* info) a))
+                     (type (p-expr->type info expr))
+                     (ptr (field-pointer info type field))
+                     (type1 (field-type info type field))
+                     (size (if (= ptr 0) (ast-type->size info type1)
+                               4)))
+                (append-text info (case size
+                                    ((1) (wrap-as (i386:byte-accu->base-mem)))
+                                    ((2) (wrap-as (i386:word-accu->base-mem)))
+                                    (else (wrap-as (i386:accu->base-mem)))))))
+             ((i-sel (ident ,field) ,expr)
+              (let* ((info ((expr->base* info) a))
+                     (type (p-expr->type info expr))
+                     (ptr (field-pointer info type field))
+                     (type1 (field-type info type field))
+                     (size (if (= ptr 0) (ast-type->size info type1)
+                               4)))
+                (append-text info (case size
+                                    ((1) (wrap-as (i386:byte-accu->base-mem)))
+                                    ((2) (wrap-as (i386:word-accu->base-mem)))
+                                    (else (wrap-as (i386:accu->base-mem)))))))
              ((de-ref (p-expr (ident ,name)))
               (let* ((type (ident->type info name))
                      (ptr (ident->pointer info name))
                      (size (expr->size info expr)))
                 (append-text info (wrap-as (i386:accu->base-mem)))))
              ((array-ref ,index (d-sel (ident ,field) (p-expr (ident ,struct))))
-              (let ((info ((expr->base* info) a)))
-                (append-text info (wrap-as (i386:accu->base-mem)))))
+              (let* ((info ((expr->base* info) a))
+                     (type (ident->type info struct))
+                     (offset (field-offset info type field))
+                     (ptr (field-pointer info type field))
+                     (type1 (field-type info type field))
+                     (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1)
+                               4)))
+                (append-text info (case size
+                                    ((1) (wrap-as (i386:byte-accu->base-mem)))
+                                    ((2) (wrap-as (i386:word-accu->base-mem)))
+                                    (else (wrap-as (i386:accu->base-mem)))))))
              ((array-ref ,index (i-sel (ident ,field) (p-expr (ident ,struct))))
-              (let ((info ((expr->base* info) a)))
-                (append-text info (wrap-as (i386:accu->base-mem)))))
+              (let* ((info ((expr->base* info) a))
+                     (type (ident->type info struct))
+                     (offset (field-offset info type field))
+                     (ptr (field-pointer info type field))
+                     (type1 (field-type info type field))
+                     (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1)
+                               4)))
+                (append-text info (case size
+                                    ((1) (wrap-as (i386:byte-accu->base-mem)))
+                                    ((2) (wrap-as (i386:word-accu->base-mem)))
+                                    (else (wrap-as (i386:accu->base-mem)))))))
              ((array-ref ,index (p-expr (ident ,array)))
               (let* ((type (ident->type info array))
                      (ptr (ident->pointer info array))
-                     (size (if (or (= ptr 1) (= ptr -1)) (ast-type->size info type)
+                     (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type)
                           4))
                      (info ((expr->base* info) a)))
                 (append-text info
                                                (wrap-as (append (i386:accu+value 4)
                                                                 (i386:base+value 4)
                                                                 (i386:accu-mem->base-mem)))))))))))
-
-             ((i-sel (ident ,field) ,array)
-              (let ((info ((expr->base* info) a)))
-                (append-text info (wrap-as (i386:accu->base-mem)))))
-
              (_ (error "expr->accu: unsupported assign: " a)))))
 
         (_ (error "expr->accu: unsupported: " o))))))
               (info ((expr->accu info) index))
               (struct? (or #t (memq (type:type (ast-type->type info type0)) '(struct union))))
               (ptr (field-pointer info type0 field0))
-              (size (if (= ptr -1) (ast-type->size info type1)
+              (size (if (or (= ptr -1)
+                            (= ptr 1)) (ast-type->size info type1)
                         4)))
          (append-text info (append (wrap-as (append (i386:accu->base)
                                                     (if (eq? size 1) '()
                                    ((ident->accu info) struct0)
                                    (wrap-as (append (i386:accu+value offset)
                                                     (i386:pop-base)
-                                                    (if (and struct? (or (= ptr -2)
-                                                                         (= ptr 2))) (i386:mem->accu) '())
+                                                    (if (and struct? (or (= ptr -2) (= ptr 2)
+                                                                         (= ptr 1)))
+                                                        (i386:mem->accu) '())
                                                     (i386:accu+base)))))))
 
       ;; foo->bar[baz]
               (info ((expr->accu info) index))
               (struct? (or #t (memq (type:type (ast-type->type info type0)) '(struct union))))
               (ptr (field-pointer info type0 field0))
-              (size (if (= ptr -1) (ast-type->size info type1)
+              (size (if (or (= ptr -1)
+                            (= ptr 1)) (ast-type->size info type1)
                         4)))
          (append-text info (append (wrap-as (append (i386:accu->base)
                                                     (if (eq? size 1) '()
                                    ((ident->accu info) struct0)
                                    (wrap-as (append (i386:accu+value offset)
                                                     (i386:pop-base)
-                                                    (if (and struct? (or (= ptr -2)
-                                                                         (= ptr 2))) (i386:mem->accu) '())
+                                                    (if (and struct? (or (= ptr -2) (= ptr 2)
+                                                                         (= ptr 1)))
+                                                        (i386:mem->accu) '())
                                                     (i386:accu+base)))))))
 
       ((array-ref ,index ,array)
 (define (expr->size info o)
   (pmatch o
     ((p-expr (ident ,name)) (ident->size info name))
+    ((d-sel (ident ,field) (p-expr (ident ,struct)))
+     (let* ((type (ident->type info struct))
+            (type1 (field-type info type field)))
+       (ast-type->size info type1)))
+    ((i-sel (ident ,field) (p-expr (ident ,struct)))
+     (let* ((type (ident->type info struct))
+            (type1 (field-type info type field)))
+       (ast-type->size info type1)))
     ((de-ref ,expr) (expr->size info expr))
     ((add ,a ,b) (expr->size info a))
     ((sub ,a ,b) (expr->size info a))
index ea33087a654a67485c2906b18e7fc6f8bc93c27f..9c0d0084e584d3d9dd359491427f0028efce457d 100644 (file)
  */
 
 #include "30-test.i"
+#include <stdio.h>
+#include <string.h>
 
 struct file {
-  unsigned char buffer[1];
+  char buffer[1];
 };
 
-int fill0;
-int fill1;
-int fill2;
-int fill3;
-int fill4;
+struct xfile {
+  char *buffer;
+};
 
 struct file file;
+struct xfile xfile;
 
-int fill5;
-int fill6;
-int fill7;
-int fill8;
-int fill9;
+char *buffer = "aaaaaaaaaaaa";
+char *bufzor = "bbbbbbbbbbbb";
 
 int
 test ()
 {
+  char *p;
+
   struct file *pfile = &file;
   strcpy (file.buffer, "0123456789\n");
   eputs (file.buffer);
-  char *p = pfile->buffer;
-  if (p[4] != '4') return 1;
-  if (file.buffer[4] != '4') return 2;
-  if (pfile->buffer[4] != '4') return 3;
+  p = pfile->buffer;
+  if (p[1] != '1') return 1;
+  if (file.buffer[1] != '1') return 2;
+  if (pfile->buffer[1] != '1') return 3;
+
+  strcpy (file.buffer, "0123456789\n");
+  eputs (file.buffer);
+  memcpy (pfile->buffer + 1, " ", 1);
+  eputs (file.buffer);
+  if (p[1] != ' ') return 4;
+  if (file.buffer[1] != ' ') return 5;
+  if (pfile->buffer[1] != ' ') return 6;
+
+  strcpy (file.buffer, "0123456789\n");
+  eputs (file.buffer);
+  p[2] = ' ';
+  eputs (file.buffer);
+  if (p[2] != ' ') return 7;
+  if (file.buffer[2] != ' ') return 8;
+  if (pfile->buffer[2] != ' ') return 9;
 
-  memcpy (pfile->buffer + 4, " ", 1);
+  strcpy (file.buffer, "0123456789\n");
+  eputs (file.buffer);
+  file.buffer[3] = ' ';
   eputs (file.buffer);
-  if (p[4] != ' ') return 4;
-  if (file.buffer[4] != ' ') return 5;
-  if (pfile->buffer[4] != ' ') return 6;
+  if (p[3] != ' ') return 10;
+  if (p[4] != '4') return 11;
 
   strcpy (file.buffer, "0123456789\n");
   eputs (file.buffer);
-  p[4] = 'A';
+  pfile->buffer[4] = ' ';
   eputs (file.buffer);
-  if (p[4] != 'A') return 7;
-  if (file.buffer[4] != 'A') return 8;
-  if (pfile->buffer[4] != 'A') return 9;
+  if (p[4] != ' ') return 12;
+  if (p[5] != '5') return 13;
+
+  xfile.buffer = &buffer;
+  struct xfile *pxfile = &xfile;
+  strcpy (xfile.buffer, "0123456789\n");
+  eputs (xfile.buffer);
+  p = pxfile->buffer;
+  if (p[5] != '5') return 20;
+  if (xfile.buffer[5] != '5') return 22;
+  if (pxfile->buffer[5] != '5') return 23;
+
+  strcpy (xfile.buffer, "0123456789\n");
+  eputs (xfile.buffer);
+  memcpy (pxfile->buffer + 5, " ", 1);
+  eputs (xfile.buffer);
+  if (p[5] != ' ') return 24;
+  if (xfile.buffer[5] != ' ') return 25;
+  if (pxfile->buffer[5] != ' ') return 26;
+
+  strcpy (xfile.buffer, "0123456789\n");
+  eputs (xfile.buffer);
+  p[6] = ' ';
+  eputs (xfile.buffer);
+  if (p[6] != ' ') return 27;
+  if (xfile.buffer[6] != ' ') return 28;
+  if (pxfile->buffer[6] != ' ') return 29;
+
+  strcpy (xfile.buffer, "0123456789\n");
+  eputs (xfile.buffer);
+  xfile.buffer[7] = ' ';
+  eputs (xfile.buffer);
+  if (p[7] != ' ') return 30;
+  if (p[8] != '8') return 31;
 
+  strcpy (xfile.buffer, "0123456789\n");
+  eputs (xfile.buffer);
+  pxfile->buffer[8] = ' ';
+  eputs (xfile.buffer);
+  if (p[8] != ' ') return 32;
+  if (p[9] != '9') return 33;
+  
   return 0;
 }