mescc: Tinycc support: struct char array assignment.

* module/language/c99/compiler.mes (expr->accu): struct char array assignment.
* scaffold/tests/7a-struct-char-array.c (test): Test it.
This commit is contained in:
Jan Nieuwenhuizen 2017-08-07 19:43:59 +02:00
parent 11d240e756
commit 082c81dbbb
2 changed files with 157 additions and 56 deletions

View file

@ -558,10 +558,10 @@
(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)) 4))
(info ((expr->accu* info) o))) (info ((expr->accu* info) o)))
(append-text info (wrap-as (append (case size (append-text info (wrap-as (case size
((1) (i386:byte-mem->accu)) ((1) (i386:byte-mem->accu))
((4) (i386:mem->accu)) ((4) (i386:mem->accu))
(else '()))))))) (else '()))))))
;; foo.bar[baz]) ;; foo.bar[baz])
((array-ref ,index (d-sel (ident ,field0) (p-expr (ident ,struct0)))) ((array-ref ,index (d-sel (ident ,field0) (p-expr (ident ,struct0))))
@ -569,9 +569,11 @@
(type0 (ident->type info struct0)) (type0 (ident->type info struct0))
(type1 (field-type info type0 field0)) (type1 (field-type info type0 field0))
(ptr (field-pointer info type0 field0)) (ptr (field-pointer info type0 field0))
(size (ast-type->size info type1))) (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1)
(append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu) 4)))
(i386:mem->accu)))))) (append-text info (wrap-as (case size
((1) (i386:byte-mem->accu))
(else (i386:mem->accu)))))))
;; foo->bar[baz]) ;; foo->bar[baz])
((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0)))) ((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0))))
@ -579,9 +581,11 @@
(type0 (ident->type info struct0)) (type0 (ident->type info struct0))
(type1 (field-type info type0 field0)) (type1 (field-type info type0 field0))
(ptr (field-pointer info type0 field0)) (ptr (field-pointer info type0 field0))
(size (ast-type->size info type1))) (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1)
(append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu) 4)))
(i386:mem->accu)))))) (append-text info (wrap-as (case size
((1) (i386:byte-mem->accu))
(else (i386:mem->accu)))))))
;; <expr>[baz] ;; <expr>[baz]
((array-ref ,index ,array) ((array-ref ,index ,array)
@ -962,11 +966,28 @@
(pmatch a (pmatch a
((p-expr (ident ,name)) ((p-expr (ident ,name))
(append-text info ((accu->ident info) name))) (append-text info ((accu->ident info) name)))
((d-sel (ident ,field) ,p-expr) ((d-sel (ident ,field) ,expr)
(let* ((type (p-expr->type info p-expr)) (let* ((info ((expr->base* info) a))
(offset (field-offset info type field)) (type (p-expr->type info expr))
(info ((expr->base* info) a))) (ptr (field-pointer info type field))
(append-text info (wrap-as (i386:accu->base-mem))))) ; FIXME: size (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))) ((de-ref (p-expr (ident ,name)))
(let* ((type (ident->type info name)) (let* ((type (ident->type info name))
(ptr (ident->pointer info name)) (ptr (ident->pointer info name))
@ -980,15 +1001,33 @@
(size (expr->size info expr))) (size (expr->size info expr)))
(append-text info (wrap-as (i386:accu->base-mem))))) (append-text info (wrap-as (i386:accu->base-mem)))))
((array-ref ,index (d-sel (ident ,field) (p-expr (ident ,struct)))) ((array-ref ,index (d-sel (ident ,field) (p-expr (ident ,struct))))
(let ((info ((expr->base* info) a))) (let* ((info ((expr->base* info) a))
(append-text info (wrap-as (i386:accu->base-mem))))) (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)))) ((array-ref ,index (i-sel (ident ,field) (p-expr (ident ,struct))))
(let ((info ((expr->base* info) a))) (let* ((info ((expr->base* info) a))
(append-text info (wrap-as (i386:accu->base-mem))))) (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))) ((array-ref ,index (p-expr (ident ,array)))
(let* ((type (ident->type info array)) (let* ((type (ident->type info array))
(ptr (ident->pointer 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)) 4))
(info ((expr->base* info) a))) (info ((expr->base* info) a)))
(append-text info (append-text info
@ -1003,11 +1042,6 @@
(wrap-as (append (i386:accu+value 4) (wrap-as (append (i386:accu+value 4)
(i386:base+value 4) (i386:base+value 4)
(i386:accu-mem->base-mem))))))))))) (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 assign: " a)))))
(_ (error "expr->accu: unsupported: " o)))))) (_ (error "expr->accu: unsupported: " o))))))
@ -1151,7 +1185,8 @@
(info ((expr->accu info) index)) (info ((expr->accu info) index))
(struct? (or #t (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)) (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))) 4)))
(append-text info (append (wrap-as (append (i386:accu->base) (append-text info (append (wrap-as (append (i386:accu->base)
(if (eq? size 1) '() (if (eq? size 1) '()
@ -1165,8 +1200,9 @@
((ident->accu info) struct0) ((ident->accu info) struct0)
(wrap-as (append (i386:accu+value offset) (wrap-as (append (i386:accu+value offset)
(i386:pop-base) (i386:pop-base)
(if (and struct? (or (= ptr -2) (if (and struct? (or (= ptr -2) (= ptr 2)
(= ptr 2))) (i386:mem->accu) '()) (= ptr 1)))
(i386:mem->accu) '())
(i386:accu+base))))))) (i386:accu+base)))))))
;; foo->bar[baz] ;; foo->bar[baz]
@ -1177,7 +1213,8 @@
(info ((expr->accu info) index)) (info ((expr->accu info) index))
(struct? (or #t (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)) (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))) 4)))
(append-text info (append (wrap-as (append (i386:accu->base) (append-text info (append (wrap-as (append (i386:accu->base)
(if (eq? size 1) '() (if (eq? size 1) '()
@ -1191,8 +1228,9 @@
((ident->accu info) struct0) ((ident->accu info) struct0)
(wrap-as (append (i386:accu+value offset) (wrap-as (append (i386:accu+value offset)
(i386:pop-base) (i386:pop-base)
(if (and struct? (or (= ptr -2) (if (and struct? (or (= ptr -2) (= ptr 2)
(= ptr 2))) (i386:mem->accu) '()) (= ptr 1)))
(i386:mem->accu) '())
(i386:accu+base))))))) (i386:accu+base)))))))
((array-ref ,index ,array) ((array-ref ,index ,array)
@ -1710,6 +1748,14 @@
(define (expr->size info o) (define (expr->size info o)
(pmatch o (pmatch o
((p-expr (ident ,name)) (ident->size info name)) ((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)) ((de-ref ,expr) (expr->size info expr))
((add ,a ,b) (expr->size info a)) ((add ,a ,b) (expr->size info a))
((sub ,a ,b) (expr->size info a)) ((sub ,a ,b) (expr->size info a))

View file

@ -19,49 +19,104 @@
*/ */
#include "30-test.i" #include "30-test.i"
#include <stdio.h>
#include <string.h>
struct file { struct file {
unsigned char buffer[1]; char buffer[1];
}; };
int fill0; struct xfile {
int fill1; char *buffer;
int fill2; };
int fill3;
int fill4;
struct file file; struct file file;
struct xfile xfile;
int fill5; char *buffer = "aaaaaaaaaaaa";
int fill6; char *bufzor = "bbbbbbbbbbbb";
int fill7;
int fill8;
int fill9;
int int
test () test ()
{ {
char *p;
struct file *pfile = &file; struct file *pfile = &file;
strcpy (file.buffer, "0123456789\n"); strcpy (file.buffer, "0123456789\n");
eputs (file.buffer); eputs (file.buffer);
char *p = pfile->buffer; p = pfile->buffer;
if (p[4] != '4') return 1; if (p[1] != '1') return 1;
if (file.buffer[4] != '4') return 2; if (file.buffer[1] != '1') return 2;
if (pfile->buffer[4] != '4') return 3; if (pfile->buffer[1] != '1') return 3;
memcpy (pfile->buffer + 4, " ", 1);
eputs (file.buffer);
if (p[4] != ' ') return 4;
if (file.buffer[4] != ' ') return 5;
if (pfile->buffer[4] != ' ') return 6;
strcpy (file.buffer, "0123456789\n"); strcpy (file.buffer, "0123456789\n");
eputs (file.buffer); eputs (file.buffer);
p[4] = 'A'; memcpy (pfile->buffer + 1, " ", 1);
eputs (file.buffer); eputs (file.buffer);
if (p[4] != 'A') return 7; if (p[1] != ' ') return 4;
if (file.buffer[4] != 'A') return 8; if (file.buffer[1] != ' ') return 5;
if (pfile->buffer[4] != 'A') return 9; 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;
strcpy (file.buffer, "0123456789\n");
eputs (file.buffer);
file.buffer[3] = ' ';
eputs (file.buffer);
if (p[3] != ' ') return 10;
if (p[4] != '4') return 11;
strcpy (file.buffer, "0123456789\n");
eputs (file.buffer);
pfile->buffer[4] = ' ';
eputs (file.buffer);
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; return 0;
} }