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.
This commit is contained in:
Jan Nieuwenhuizen 2018-05-19 20:49:56 +02:00
parent b4d1c40aa8
commit 03ba0e18df
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
2 changed files with 64 additions and 4 deletions

View file

@ -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 " <t>")
(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 " <t>")
(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

View file

@ -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)];