From 1d996c71317e0cf50bab7aa65f0e72b5ee9249de Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sun, 23 Jul 2017 13:41:38 +0200 Subject: [PATCH] mescc: Tinycc support: struct.union. * module/language/c99/compiler.mes (struct-field): Add struct tag to struct/union types. (field-type, field-size, field-offset, field-field, ast-type->type): Ascertain struct tag with type. * (expr->accu*): Do not add struct tag. * scaffold/tests/75-struct-union.c: Test it. * scaffold/tests/71-struct-array.c: Update. --- module/language/c99/compiler.mes | 81 ++++++++++++++++++-------------- scaffold/tests/71-struct-array.c | 8 +++- scaffold/tests/75-struct-union.c | 25 ++++++++-- 3 files changed, 73 insertions(+), 41 deletions(-) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index e8d666dc..7ff333ed 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -954,18 +954,18 @@ ;; bar.foo.i ((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0)))) (let* ((type0 (ident->type info struct0)) - (type1 (field-type info `("struct" ,type0) field0)) - (offset (+ (field-offset info `("struct" ,type0) field0) - (field-offset info `("struct" ,type1) field1)))) + (type1 (field-type info type0 field0)) + (offset (+ (field-offset info type0 field0) + (field-offset info type1 field1)))) (append-text info (append ((ident->accu info) struct0) (wrap-as (i386:accu+value offset)))))) ;; bar.poo->i ((i-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0)))) (let* ((type0 (ident->type info struct0)) - (type1 (field-type info `("struct" ,type0) field0)) - (offset0 (field-offset info `("struct" ,type0) field0)) - (offset1 (field-offset info `("struct" ,type1) field1))) + (type1 (field-type info type0 field0)) + (offset0 (field-offset info type0 field0)) + (offset1 (field-offset info type1 field1))) (append-text info (append ((ident->accu info) struct0) (wrap-as (i386:accu+value offset0)) (wrap-as (i386:mem->accu)) @@ -974,27 +974,27 @@ ;; bar->foo.i ((d-sel (ident ,field1) (i-sel (ident ,field0) (p-expr (ident ,struct0)))) (let* ((type0 (ident->type info struct0)) - (type1 (field-type info `("struct" ,type0) field0)) - (offset (+ (field-offset info `("struct" ,type0) field0) - (field-offset info `("struct" ,type1) field1)))) + (type1 (field-type info type0 field0)) + (offset (+ (field-offset info type0 field0) + (field-offset info type1 field1)))) (append-text info (append ((ident-address->accu info) struct0) (wrap-as (i386:accu+value offset)))))) ;; bar->foo.i ((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0)))) (let* ((type0 (ident->type info struct0)) - (type1 (field-type info `("struct" ,type0) field0)) - (offset (+ (field-offset info `("struct" ,type0) field0) - (field-offset info `("struct" ,type1) field1)))) + (type1 (field-type info type0 field0)) + (offset (+ (field-offset info type0 field0) + (field-offset info type1 field1)))) (append-text info (append ((ident->accu info) struct0) (wrap-as (i386:accu+value offset)))))) ;;(i-sel (ident "i") (i-sel (ident "p") (p-expr (ident "p")))) ((i-sel (ident ,field1) (i-sel (ident ,field0) (p-expr (ident ,struct0)))) (let* ((type0 (ident->type info struct0)) - (type1 (field-type info `("struct" ,type0) field0)) - (offset0 (field-offset info `("struct" ,type0) field0)) - (offset1 (field-offset info `("struct" ,type1) field1))) + (type1 (field-type info type0 field0)) + (offset0 (field-offset info type0 field0)) + (offset1 (field-offset info type1 field1))) (append-text info (append ((ident->accu info) struct0) (wrap-as (i386:accu+value offset0)) (wrap-as (i386:mem->accu)) @@ -1003,9 +1003,9 @@ ;; (*pp)->bar.foo ((d-sel (ident ,field1) (i-sel (ident ,field0) (de-ref (p-expr (ident ,struct0))))) (let* ((type0 (ident->type info struct0)) - (type1 (field-type info `("struct" ,type0) field0)) - (offset (+ (field-offset info `("struct" ,type0) field0) - (field-offset info `("struct" ,type1) field1)))) + (type1 (field-type info type0 field0)) + (offset (+ (field-offset info type0 field0) + (field-offset info type1 field1)))) (append-text info (append ((ident->accu info) struct0) (wrap-as (i386:mem->accu)) (wrap-as (i386:accu+value offset)))))) @@ -1080,9 +1080,9 @@ ;; foo[i].bar.baz ((d-sel (ident ,field1) (d-sel (ident ,field0) (array-ref ,index (p-expr (ident ,array))))) (let* ((type0 (ident->type info array)) - (type1 (field-type info `("struct" ,type0) field0)) - (offset (+ (field-offset info `("struct" ,type0) field0) - (field-offset info `("struct" ,type1) field1))) + (type1 (field-type info type0 field0)) + (offset (+ (field-offset info type0 field0) + (field-offset info type1 field1))) (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array)))))) (append-text info (wrap-as (i386:accu+value offset))))) @@ -1159,11 +1159,14 @@ ((decl-spec-list (type-qual ,qual) (type-spec (fixed-type ,type))) (ast-type->type info type)) ((struct-ref (ident (,type))) - (ast-type->type info `("struct" ,type))) + (let ((struct (if (pair? type) type `("struct" ,type)))) + (ast-type->type info struct))) ((struct-ref (ident ,type)) - (ast-type->type info `("struct" ,type))) + (let ((struct (if (pair? type) type `("struct" ,type)))) + (ast-type->type info struct))) ((union-ref (ident ,type)) - (ast-type->type info `("struct" ,type))) + (let ((struct (if (pair? type) type `("struct" ,type)))) + (ast-type->type info struct))) ((void) (ast-type->type info "void")) ((type-spec (typename ,type)) (ast-type->type info type)) (_ (let ((type (get-type (.types info) o))) @@ -1181,7 +1184,8 @@ (type:size type))) (define (field-field info struct field) - (let* ((xtype (ast-type->type info struct)) + (let* ((struct (if (pair? struct) struct `("struct" ,struct))) + (xtype (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)) @@ -1192,7 +1196,8 @@ (else (loop (cdr fields))))))))) (define (field-offset info struct field) - (let ((xtype (ast-type->type info struct))) + (let* ((struct (if (pair? struct) struct `("struct" ,struct))) + (xtype (ast-type->type info struct))) (if (eq? (type:type xtype) 'union) 0 (let ((fields (type:description xtype))) (let loop ((fields fields) (offset 0)) @@ -1205,15 +1210,17 @@ (else (loop (cdr fields) (+ offset (field:size f)))))))))))) (define (field-size info struct field) - (let ((xtype (ast-type->type info struct))) + (let* ((struct (if (pair? struct) struct `("struct" ,struct))) + (xtype (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* ((struct (if (pair? struct) struct `("struct" ,struct))) + (xtype (ast-type->type info struct))) + (let ((field (field-field info struct field))) + (field:type field)))) (define (ast->type o) (pmatch o @@ -1415,23 +1422,27 @@ (list name type (* count size) 0))) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ptr-declr (pointer (pointer)) (ident ,name))))) - (list name type 4)) + (list name `("struct" ,type) 4)) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ptr-declr (pointer (pointer)) (ident ,name))))) - (list name type 4)) + (list name `("struct" ,type) 4)) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ptr-declr (pointer) (ident ,name))))) - (list name type 4)) + (list name `("struct" ,type) 4)) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ptr-declr (pointer) (ident ,name))))) - (list name type 4)) + (list name `("struct" ,type) 4)) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ident ,name)))) ((struct-field info) `(comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name)))))) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name)))) (let ((size (ast-type->size info `("struct" ,type)))) - (list name type size 0))) + (list name `("struct" ,type) size 0))) + + ((comp-decl (decl-spec-list (type-spec (union-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name)))) + (let ((size (ast-type->size info `("struct" ,type)))) + (list name `("struct" ,type) size 0))) ((comp-decl (decl-spec-list (type-spec (union-def (field-list . ,fields))))) `(union ,@(map (struct-field info) fields))) diff --git a/scaffold/tests/71-struct-array.c b/scaffold/tests/71-struct-array.c index 8ca5cda9..4e160c3c 100644 --- a/scaffold/tests/71-struct-array.c +++ b/scaffold/tests/71-struct-array.c @@ -25,7 +25,12 @@ struct foo; struct foo* krak; +#if 0 +//FIXME: TODO typedef struct foo foo_struct; +#else +typedef struct foo foo; +#endif struct foo { @@ -47,8 +52,7 @@ typedef struct baz int test () { - //struct foo f; - foo_struct f; + foo f; f.bar[0] = 0x22; f.bar[1] = 0x34; printf ("eentje: %d\n", f.bar[0]); diff --git a/scaffold/tests/75-struct-union.c b/scaffold/tests/75-struct-union.c index 0ba86309..57d9fe28 100644 --- a/scaffold/tests/75-struct-union.c +++ b/scaffold/tests/75-struct-union.c @@ -21,7 +21,17 @@ #include "30-test.i" #include +union u { + int bar; + int baz; +}; + struct foo +{ + union u u; +}; + +struct anon { union { int bar; @@ -29,14 +39,21 @@ struct foo }; }; + int test () { struct foo f = {2}; - printf ("f.bar=%d\n", f.bar); - if (f.bar != 2) return 1; - printf ("f.baz=%d\n", f.baz); - if (f.baz != 2) return 1; + printf ("f.u.bar=%d\n", f.u.bar); + if (f.u.bar != 2) return 1; + printf ("f.u.baz=%d\n", f.u.baz); + if (f.u.baz != 2) return 1; + + struct anon a = {2}; + printf ("a.bar=%d\n", a.bar); + if (a.bar != 2) return 1; + printf ("a.baz=%d\n", a.baz); + if (a.baz != 2) return 1; return 0; }