mescc: Tinycc support: struct char array assignment.
[mes.git] / module / language / c99 / compiler.mes
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))