mescc: Tinycc support: fixes for foo.bar[baz].
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 5 Aug 2017 19:09:19 +0000 (21:09 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 5 Aug 2017 19:09:19 +0000 (21:09 +0200)
* module/language/c99/compiler.mes (expr->accu, expr->accu*): fixes for foo.bar[baz].
* scaffold/tests/7c-dynarray.c: Test it.

module/language/c99/compiler.mes
scaffold/tests/79-int-array.c
scaffold/tests/7c-dynarray.c
scaffold/tests/7f-struct-pointer-arithmetic.c

index a9209d2432e3f3fbe4eda8093126099e84a54ed6..9da74f3cd75d6404fca72eadb2e3b074bd12c77f 100644 (file)
          (let* ((info ((expr->accu* info) o))
                 (type0 (ident->type info struct0))
                 (type1 (field-type info type0 field0))
-                (struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
                 (ptr (field-pointer info type0 field0))
                 (size (ast-type->size info type1)))
-           (if (= ptr -3) info
-               (append-text info (wrap-as (append (if (and (= ptr -2) struct?) (i386:mem->accu) '())
-                                                  (if (= size 1) (i386:byte-mem->accu)
-                                                      (i386:mem->accu))))))))
+           (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu)
+                                          (i386:mem->accu))))))
 
         ;; foo->bar[baz])
         ((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0))))
          (let* ((info ((expr->accu* info) o))
                 (type0 (ident->type info struct0))
                 (type1 (field-type info type0 field0))
-                (struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
                 (ptr (field-pointer info type0 field0))
                 (size (ast-type->size info type1)))
-           (append-text info (wrap-as (append (if (and (= ptr -2) struct?) (i386:mem->accu) '())
-                                              (if (= size 1) (i386:byte-mem->accu)
-                                                  (i386:mem->accu)))))))
+           (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu)
+                                          (i386:mem->accu))))))
 
         ;; <expr>[baz]
         ((array-ref ,index ,array)
                 (size (cond ((= ptr 1) (expr->size info a))
                             ((> ptr 1) 4)
                             ((and struct? (= ptr -2)) 4)
+                            ((and struct? (= ptr 2)) 4)
                             (else 1)))
                 (info ((expr->accu info) a))
                 (value (cstring->number value))
                 (value (* size value)))
-           (stderr "ptr=~s\n" ptr)
-           (stderr "  size=~s\n" size)
-           (stderr "  struct?=~s\n" struct?)
-           (if (not (= size 1))
-               (warn (format #f "TODO: pointer arithmetic: ~s\n" o)))
            (append-text info (wrap-as (i386:accu+value value)))))
 
         ((add ,a ,b)
          (let* ((ptr (expr->pointer info a))
+                (type0 (p-expr->type info a))
+                (struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
                 (size (cond ((= ptr 1) (expr->size info a))
                             ((> ptr 1) 4)
                             ((and struct? (= ptr -2)) 4)
+                            ((and struct? (= ptr 2)) 4)
                             (else 1))))
-           (if (not (= size 1))
-               (warn (format #f "TODO: pointer arithmetic: ~s\n" o))))
-         ((binop->accu info) a b (i386:accu+base)))
+         ((binop->accu info) a b (i386:accu+base))))
 
         ((sub ,a (p-expr (fixed ,value)))
          (let* ((ptr (expr->pointer info a))
               (type1 (field-type info type0 field0))
               (offset (field-offset info type0 field0))
               (info ((expr->accu info) index))
-              (struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
+              (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)
                         4)))
-         (stderr "ACCU* o=~s\n" o)
-         (stderr "   ptr=~s\n" ptr)
-         (stderr "   size=~s\n" size)
          (append-text info (append (wrap-as (append (i386:accu->base)
                                                     (if (eq? size 1) '()
                                                         (append
                                                              (i386:accu+base))
                                                          (i386:accu-shl 2)))))
                                    (wrap-as (i386:push-accu))
-                                   ((ident-address->accu info) struct0)
-                                   (if (and struct? (= ptr -2)) (wrap-as (i386:mem->accu)) '())
+                                   ((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) '())
                                                     (i386:accu+base)))))))
 
       ;; foo->bar[baz]
               (type1 (field-type info type0 field0))
               (offset (field-offset info type0 field0))
               (info ((expr->accu info) index))
-              (struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
+              (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)
                         4)))
                                                          (i386:accu-shl 2)))))
                                    (wrap-as (i386:push-accu))
                                    ((ident->accu info) struct0)
-                                   (if (and struct? (= ptr -2)) (wrap-as (i386:mem->accu)) '())
                                    (wrap-as (append (i386:accu+value offset)
                                                     (i386:pop-base)
+                                                    (if (and struct? (or (= ptr -2)
+                                                                         (= ptr 2))) (i386:mem->accu) '())
                                                     (i386:accu+base)))))))
 
       ((array-ref ,index ,array)
     ((type-spec ,type) (ast-type->type info type))
     ((fixed-type ,type) (ast-type->type info type))
     ((typename ,type) (ast-type->type info type))
+    ((d-sel (idend ,field) ,struct)
+     (let ((type0 (ast-type->type info struct)))
+       (field-type info type0 field)))
+    ((i-sel (ident ,field) ,struct)
+     (let ((type0 (ast-type->type info struct)))
+       (field-type info type0 field)))
     (_ (let ((type (get-type (.types info) o)))
          (if type type
              (begin
                (error "ast-type->type: unsupported: " o)))))))
 
 (define (ast-type->description info o)
-  (let ((type (ast-type->type info o)))
-    (type:description type)))
+  (let* ((type (ast-type->type info o))
+         (xtype (if (type? type) type
+                    (ast-type->type info type))))
+    (type:description xtype)))
 
 (define (ast-type->size info o)
-  (let ((type (ast-type->type info o)))
-    (type:size type)))
+  (let* ((type (ast-type->type info o))
+         (xtype (if (type? type) type
+                    (ast-type->type info type))))
+    (type:size xtype)))
 
 (define (field-field info struct field)
-  (let* ((xtype (ast-type->type info struct))
+  (let* ((xtype (if (type? struct) struct
+                    (ast-type->type info struct)))
          (fields (type:description xtype)))
     (let loop ((fields fields))
       (if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
                   (else (loop (cdr fields)))))))))
 
 (define (field-offset info struct field)
-  (let ((xtype (ast-type->type info struct)))
+  (let ((xtype (if (type? struct) struct
+                    (ast-type->type info struct))))
     (if (eq? (type:type xtype) 'union) 0
         (let ((fields (type:description xtype)))
           (let loop ((fields fields) (offset 0))
                         (else (loop (cdr fields) (+ offset (field:size f))))))))))))
 
 (define (field-pointer info struct field)
-  (let ((xtype (ast-type->type info struct)))
-    (let ((field (field-field info struct field)))
-      (field:pointer field))))
+  (let ((field (field-field info struct field)))
+    (field:pointer field)))
 
 (define (field-size info struct field)
-  (let ((xtype (ast-type->type info struct)))
+  (let ((xtype (if (type? struct) struct
+                   (ast-type->type info struct))))
     (if (eq? (type:type xtype) 'union) 0
         (let ((field (field-field info struct field)))
           (field:size field)))))
 
 (define (field-type info struct field)
-  (let ((xtype (ast-type->type info struct)))
-    (let ((field (field-field info struct field)))
-      (field:type field))))
+  (let ((field (field-field info struct field)))
+    (field:type field)))
 
 (define (ast->type o)
   (pmatch o
 
 (define (expr->pointer info o)
   (pmatch o
+    ((p-expr (fixed ,value)) 0)
     ((p-expr (ident ,name)) (ident->pointer info name))
     ((de-ref ,expr) (1- (expr->pointer info expr)))
     ((add ,a ,b) (expr->pointer info a))
+    ((neg ,a) (expr->pointer info a))
     ((sub ,a ,b) (expr->pointer info a))
     ((pre-inc ,a) (expr->pointer info a))
     ((pre-dec ,a) (expr->pointer info a))
        (field-type info type0 field)))
     ((de-ref ,expr) (p-expr->type info expr))
     ((ref-to ,expr) (p-expr->type info expr))
-    ((add ,a ,b)
-     (p-expr->type info a))
-    ((sub ,a ,b)
-     (p-expr->type info a))
-    (_ (error "p-expr->type: unsupported: " o))))
+    ((add ,a ,b) (p-expr->type info a))
+    ((sub ,a ,b) (p-expr->type info a))
+    ((p-expr (fixed ,value)) "int")
+    ((neg ,a) (p-expr->type info a))
+    ((cast (type-name ,type (abs-declr ,pointer)) (p-expr (ident ,name)))
+     type)
+    ((fctn-call (p-expr (ident ,name)))
+     (stderr "TODO: p-expr->type: unsupported: ~s\n" o)
+     "int")
+    (_ ;;(error (format #f "p-expr->type: unsupported: ~s") o)
+     (stderr "TODO: p-expr->type: unsupported: ~s\n" o)
+     "int")))
 
 (define (local-var? o) ;; formals < 0, locals > 0
   (positive? (local:id o)))
index 64b2758aab5987f5ced3244058293edbb21e4185..6834c14e05d6b1fc6d0fa3e9207453d7b6b7dd0b 100644 (file)
@@ -20,8 +20,9 @@
 
 #include "30-test.i"
 
+#include <mlibc.h>
 #include <stdio.h>
-#include <stdint.h>
+#include <string.h>
 
 struct foo {
   int *bar;
index b11196aa99be8f8b288d90bce12f412f8e7b4219..01a6b6bedd40c21e768263b0d45e7d7f9aef74cc 100644 (file)
@@ -81,7 +81,9 @@ test ()
   eputs ("&PATHS="); eputs (itoa (&s->paths)); eputs ("\n");
   eputs ("&FILES="); eputs (itoa (&s->files)); eputs ("\n");
 
-  struct file *fs = s->files[0];
+  struct file *fs;
+  eputs ("foo\n");
+  fs = s->files[0];
   eputs ("add s=   "); eputs (itoa (s)); eputs ("\n");
   eputs ("add fs=  "); eputs (itoa (fs)); eputs ("\n");
   eputs ("&fs->[0]="); eputs (itoa (fs->name)); eputs ("\n");
@@ -90,13 +92,46 @@ test ()
   eputs ("ps=      "); eputs (itoa (s->paths)); eputs ("\n");
   eputs ("*ps      "); eputs (*s->paths); eputs ("\n");
 
-  if (strcmp (fs->name, file_name)) return 1;
-  
+  if (strcmp (fs->name, file_name)) return 2;
+
   eputs ("&fs->[0]="); eputs (itoa (fs->name)); eputs ("\n");
   eputs ("fs->name="); eputs (fs->name); eputs ("\n");
 
   eputs ("ps=      "); eputs (itoa (s->paths)); eputs ("\n");
   eputs ("*ps      "); eputs (*s->paths); eputs ("\n");
 
+
+  file = malloc (sizeof (struct file) + strlen (file_name));
+  file_name = "hallo";
+  strcpy (file->name, file_name);
+  add (&s->files, &s->file_count, file);
+
+  struct file **pf = s->files;
+  fs = pf[0];
+  eputs ("\n");
+  eputs ("&fs0*=    "); eputs (itoa (&pf[0])); eputs ("\n");
+
+  eputs ("fs0*=     "); eputs (itoa (fs)); eputs ("\n");
+  fs = s->files[0];
+  eputs ("fs0*=     "); eputs (itoa (fs)); eputs ("\n");
+  eputs ("\n");
+
+  pf = s->files;
+  fs = pf[1];
+  eputs ("&fs1*=    "); eputs (itoa (&pf[1])); eputs ("\n");
+  eputs ("fs1*=     "); eputs (itoa (fs)); eputs ("\n");
+  fs = s->files[1];
+  eputs ("fs1*=     "); eputs (itoa (fs)); eputs ("\n");
+  eputs ("\n");
+  if (strcmp (fs->name, file_name)) return 3;
+
+  fs = g_s.files[0];
+  eputs ("gfs0*=    "); eputs (itoa (fs)); eputs ("\n");
+  fs = g_s.files[1];
+  eputs ("gfs1*=    "); eputs (itoa (fs)); eputs ("\n");
+  eputs ("\n");
+  if (strcmp (fs->name, file_name)) return 3;
+
+
   return 0;
 }
index 1a1e763c73f9c6d1c26ac9c8b1f4e2127f9e25e5..a231139fb975b553bb9fe170c4e36ff2d58851e0 100644 (file)
 #include <stdio.h>
 
 struct foo;
+typedef struct foo foo_struct;
 
 struct foo {
-    struct foo **foo;
+  //struct foo **foo;
+  foo_struct **foo;
 };
   
 struct foo g_foo[2];