From 03ba0e18df1d32fe39a33b1842fef50656fe4363 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sat, 19 May 2018 20:49:56 +0200 Subject: [PATCH] mescc: Tinycc support: Export nested struct definitions. * module/language/c99/compiler.mes (struct-field): Support nested, named and anonymous enums. (field->info): New function. (type->info): Use it to reap nestedly defined enums, structs, unions. (decl->info): Likewise. * scaffold/tests/t.c: Test it. --- module/language/c99/compiler.mes | 41 ++++++++++++++++++++++++++++---- scaffold/tests/t.c | 27 +++++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index ce29ea7c..fd1f2fc3 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -1544,7 +1544,15 @@ (define (struct-field info) (lambda (o) (pmatch o - ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ident ,name)))) + ((comp-decl (decl-spec-list (type-spec (enum-def (ident ,name) (enum-def-list . ,fields)))) (comp-declr-list . ,decls)) + (let ( + ;;(constants (enum-def-list->constants (.constants info) fields)) + ;;(type-entry (enum->type-entry name fields)) + ) + (append-map (lambda (o) + ((struct-field info) `(comp-decl (decl-spec-list (type-spec "int")) (comp-declr-list ,o)))) + decls))) + ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ident ,name)))) (list (cons name (ast->type type info)))) ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ptr-declr ,pointer (ident ,name))))) (let ((rank (pointer->rank pointer))) @@ -1934,7 +1942,8 @@ (type (rank+= type rank))) (clone info #:types (acons name type (.types info))))) (((decl-spec-list (stor-spec (,store)) (type-spec ,type)) (init-declr-list . ,inits)) - (let* ((type (ast->type type info)) + (let* ((info (type->info type #f info)) + (type (ast->type type info)) (function (.function info))) (if (not function) (fold (cut init-declr->info type <> <>) info (map cdr inits)) (let* ((tmp (clone info #:function #f #:globals '())) @@ -2290,12 +2299,14 @@ ((struct-def (field-list . ,fields)) (mescc:trace name " ") - (let ((type-entry (struct->type-entry name (append-map (struct-field info) fields)))) + (let* ((info (fold field->info info fields)) + (type-entry (struct->type-entry name (append-map (struct-field info) fields)))) (clone info #:types (cons type-entry (.types info))))) ((struct-def (ident ,name) (field-list . ,fields)) (mescc:trace name " ") - (let ((type-entry (struct->type-entry name (append-map (struct-field info) fields)))) + (let* ((info (fold field->info info fields)) + (type-entry (struct->type-entry name (append-map (struct-field info) fields)))) (clone info #:types (cons type-entry (.types info))))) ((union-def (ident ,name) (field-list . ,fields)) @@ -2321,6 +2332,28 @@ info ))) +(define (field->info o info) + (pmatch o + ((comp-decl (decl-spec-list (type-spec (struct-def (ident ,name) (field-list . ,fields)))) . _) + (let* ((fields (append-map (struct-field info) fields)) + (struct (make-type 'struct (apply + (map field:size fields)) fields))) + (clone info #:types (acons `(tag ,name) struct (.types info))))) + ((comp-decl (decl-spec-list (type-spec (union-def (ident ,name) (field-list . ,fields)))) . _) + (let* ((fields (append-map (struct-field info) fields)) + (union (make-type 'union (apply + (map field:size fields)) fields))) + (clone info #:types (acons `(tag ,name) union (.types info))) )) + ((comp-decl (decl-spec-list (type-spec (enum-def (enum-def-list . ,fields)))) . _) + (let ((constants (enum-def-list->constants (.constants info) fields))) + (clone info + #:constants (append constants (.constants info))))) + ((comp-decl (decl-spec-list (type-spec (enum-def (ident ,name) (enum-def-list . ,fields)))) . _) + (let ((constants (enum-def-list->constants (.constants info) fields)) + (type-entry (enum->type-entry name fields))) + (clone info + #:types (cons type-entry (.types info)) + #:constants (append constants (.constants info))))) + (_ info))) + ;;; fctn-defn (define (param-decl:get-name o) (pmatch o diff --git a/scaffold/tests/t.c b/scaffold/tests/t.c index 9dad4c89..884a2a87 100644 --- a/scaffold/tests/t.c +++ b/scaffold/tests/t.c @@ -49,6 +49,23 @@ int_array_t bar; typedef struct foo *foo_pointer_t; foo_pointer_t foep; +struct nest +{ + struct bar + { + int baz; + } bar; + int i; + enum baz + { + bla + } baz; + enum + { + blub = 33, + } blub; +}; + int test (struct foo* p) { @@ -134,6 +151,16 @@ main (int argc, char* argv[]) if (u.foo != 3) return 24; if (u.bla != 4) return 25; + struct nest n = {0}; + if (n.bar.baz) + return 26; + + if (bla != 0) + return 27; + + if (blub != 33) + return 28; + char buf[sizeof (g_f.string)]; char buf1[sizeof (g_g->string)];