diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 522ed775..c745b33f 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -180,6 +180,7 @@ lib/tests/scaffold/7u-inc-byte-word.c lib/tests/scaffold/7u-struct-func.c lib/tests/scaffold/7u-struct-size10.c lib/tests/scaffold/7u-vstack.c +lib/tests/scaffold/70-array-in-struct-init.c lib/tests/setjmp/80-setjmp.c lib/tests/stdio/80-sscanf.c lib/tests/stdlib/80-qsort.c diff --git a/lib/tests/scaffold/70-array-in-struct-init.c b/lib/tests/scaffold/70-array-in-struct-init.c new file mode 100644 index 00000000..08767a30 --- /dev/null +++ b/lib/tests/scaffold/70-array-in-struct-init.c @@ -0,0 +1,56 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2019 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include + +struct foo +{ + int field; + int array[3]; +}; + +struct foo foes[] = + { + {10, {11, 12, 13}}, + {20, {21, 22}}, + {30, {31}}, + {40, {41}}, + {0} + }; + +int +main () +{ + for (struct foo *p = foes; p->field; p++) + { + oputs ("{"); + oputs (itoa (p->field)); oputs (","); + oputs ("{"); + oputs (itoa (p->array[0])); oputs (","); + oputs (itoa (p->array[1])); oputs (","); + oputs (itoa (p->array[2])); + oputs ("}"); + oputs ("},\n"); + } + oputs ("{0}\n"); + oputs ("};\n"); + + return 0; +} diff --git a/lib/tests/scaffold/70-array-in-struct-init.stdout b/lib/tests/scaffold/70-array-in-struct-init.stdout new file mode 100644 index 00000000..a2ec8dca --- /dev/null +++ b/lib/tests/scaffold/70-array-in-struct-init.stdout @@ -0,0 +1,6 @@ +{10,{11,12,13}}, +{20,{21,22,0}}, +{30,{31,0,0}}, +{40,{41,0,0}}, +{0} +}; diff --git a/module/mescc/compile.scm b/module/mescc/compile.scm index 5118ff51..a7362f77 100644 --- a/module/mescc/compile.scm +++ b/module/mescc/compile.scm @@ -349,7 +349,7 @@ ((bits . ,bits) bits) (_ (list o)))) -(define (struct->init-fields o) +(define (struct->init-fields o) ;; FIXME REMOVEME: non-recursive unroll (pmatch o (_ (guard (and (type? o) (eq? (type:type o) 'struct))) (append-map struct->init-fields (type:description o))) @@ -2230,16 +2230,21 @@ (int->bv type (expr->number info fixed) info)) (int->bv type (expr->number info fixed) info))) ((initzer (initzer-list . ,inits)) - (if (structured-type? type) - (let* ((fields (map cdr (struct->init-fields type))) - (missing (max 0 (- (length fields) (length inits)))) - (inits (append inits - (map (const '(fixed "0")) (iota missing))))) - (map (cut init->data <> <> info) fields inits)) - (begin - (stderr "array-init-element->data: oops:~s\n" o) - (stderr "type:~s\n" type) - (error "array-init-element->data: unstructured not supported: " o)))) + (cond ((structured-type? type) + (let* ((fields (map cdr (struct->init-fields type))) + (missing (max 0 (- (length fields) (length inits)))) + (inits (append inits + (map (const '(fixed "0")) (iota missing))))) + (map (cut array-init-element->data <> <> info) fields inits))) + ((c-array? type) + (let* ((missing (max 0 (- (c-array:count type) (length inits)))) + (inits (append inits + (map (const '(fixed "0")) (iota missing))))) + (map (cut array-init-element->data (c-array:type type) <> info) inits))) + (else + (stderr "array-init-element->data: oops:~s\n" o) + (stderr "type:~s\n" type) + (error "array-init-element->data: not supported: " o)))) (_ (init->data type o info)) (_ (error "array-init-element->data: not supported: " o)))) @@ -2248,7 +2253,8 @@ ((initzer (initzer-list . ,inits)) (let ((type (c-array:type type))) (if (structured-type? type) - (let* ((fields (length (struct->init-fields type)))) + (let* ((init-fields (struct->init-fields type)) ;; FIXME + (count (length init-fields))) (let loop ((inits inits)) (if (null? inits) '() (let ((init (car inits))) @@ -2256,10 +2262,11 @@ ((initzer (initzer-list . ,car-inits)) (append (array-init-element->data type init info) (loop (cdr inits)))) - (_ (let* ((count (min (length inits) fields)) + (_ + (let* ((count (min (length inits) (length init-fields))) (field-inits (list-head inits count))) - (append (array-init-element->data type `(initzer-list ,@field-inits) info) - (loop (list-tail inits count)))))))))) + (append (array-init-element->data type `(initzer-list ,@field-inits) info) + (loop (list-tail inits count)))))))))) (map (cut array-init-element->data type <> info) inits)))) (((initzer (initzer-list . ,inits)))