mescc: Tinycc support: struct.struct.
* module/language/c99/compiler.mes (field:name): (field:pointer): (field:size): (field:type): (field-field): (field-offset): (struct-field): Support struct.struct. * scaffold/tests/7i-struct-struct.c: Test it. * make.scm (add-scaffold-test): Build it.
This commit is contained in:
parent
5230ddc93b
commit
3392f7241a
3
make.scm
3
make.scm
|
@ -167,7 +167,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
|
||||||
"7e-struct-array-access"
|
"7e-struct-array-access"
|
||||||
"7f-struct-pointer-arithmetic"
|
"7f-struct-pointer-arithmetic"
|
||||||
"7g-struct-byte-word-field"
|
"7g-struct-byte-word-field"
|
||||||
"7h-struct-assign"))
|
"7h-struct-assign"
|
||||||
|
"7i-struct-struct"))
|
||||||
|
|
||||||
(add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))
|
(add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))
|
||||||
|
|
||||||
|
|
|
@ -1290,29 +1290,28 @@
|
||||||
|
|
||||||
(define (field:name o)
|
(define (field:name o)
|
||||||
(pmatch o
|
(pmatch o
|
||||||
|
((struct (,name ,type ,size ,pointer) . ,rest) name)
|
||||||
((union (,name ,type ,size ,pointer) . ,rest) name)
|
((union (,name ,type ,size ,pointer) . ,rest) name)
|
||||||
;;((union (,name ,type ,size) . ,rest) name)
|
|
||||||
((,name ,type ,size ,pointer) name)
|
((,name ,type ,size ,pointer) name)
|
||||||
;;((,name ,type ,size) name)
|
|
||||||
(_ (error "field:name not supported:" o))))
|
(_ (error "field:name not supported:" o))))
|
||||||
|
|
||||||
(define (field:pointer o)
|
(define (field:pointer o)
|
||||||
(pmatch o
|
(pmatch o
|
||||||
|
((struct (,name ,type ,size ,pointer) . ,rest) pointer)
|
||||||
((union (,name ,type ,size ,pointer) . ,rest) pointer)
|
((union (,name ,type ,size ,pointer) . ,rest) pointer)
|
||||||
((,name ,type ,size ,pointer) pointer)
|
((,name ,type ,size ,pointer) pointer)
|
||||||
(_ (error "field:name not supported:" o))))
|
(_ (error "field:name not supported:" o))))
|
||||||
|
|
||||||
(define (field:size o)
|
(define (field:size o)
|
||||||
(pmatch o
|
(pmatch o
|
||||||
|
((struct . ,fields) (apply + (map field:size fields)))
|
||||||
((union . ,fields) 4) ;; FIXME
|
((union . ,fields) 4) ;; FIXME
|
||||||
((,name ,type ,size ,pointer) size)
|
((,name ,type ,size ,pointer) size)
|
||||||
;;((,name ,type ,size) size)
|
|
||||||
(_ 4)))
|
(_ 4)))
|
||||||
|
|
||||||
(define (field:type o)
|
(define (field:type o)
|
||||||
(pmatch o
|
(pmatch o
|
||||||
((,name ,type ,size ,pointer) type)
|
((,name ,type ,size ,pointer) type)
|
||||||
;;((,name ,type ,size) type)
|
|
||||||
(_ (error "field:type:" o))))
|
(_ (error "field:type:" o))))
|
||||||
|
|
||||||
(define (get-type types o)
|
(define (get-type types o)
|
||||||
|
@ -1375,7 +1374,7 @@
|
||||||
(if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
|
(if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
|
||||||
(let ((f (car fields)))
|
(let ((f (car fields)))
|
||||||
(cond ((equal? (car f) field) f)
|
(cond ((equal? (car f) field) f)
|
||||||
((and (eq? (car f) 'union)
|
((and (memq (car f) '(struct union))
|
||||||
(find (lambda (x) (equal? (car x) field)) (cdr f))))
|
(find (lambda (x) (equal? (car x) field)) (cdr f))))
|
||||||
(else (loop (cdr fields)))))))))
|
(else (loop (cdr fields)))))))))
|
||||||
|
|
||||||
|
@ -1388,6 +1387,13 @@
|
||||||
(if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
|
(if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
|
||||||
(let ((f (car fields)))
|
(let ((f (car fields)))
|
||||||
(cond ((equal? (car f) field) offset)
|
(cond ((equal? (car f) field) offset)
|
||||||
|
((and (eq? (car f) 'struct)
|
||||||
|
(find (lambda (x) (equal? (car x) field)) (cdr f))
|
||||||
|
(apply + (cons offset
|
||||||
|
(map field:size
|
||||||
|
(member field (reverse (cdr f))
|
||||||
|
(lambda (a b)
|
||||||
|
(equal? a (car b) field))))))))
|
||||||
((and (eq? (car f) 'union)
|
((and (eq? (car f) 'union)
|
||||||
(find (lambda (x) (equal? (car x) field)) (cdr f))
|
(find (lambda (x) (equal? (car x) field)) (cdr f))
|
||||||
offset))
|
offset))
|
||||||
|
@ -1656,6 +1662,9 @@
|
||||||
(let ((size (ast-type->size info `("tag" ,type))))
|
(let ((size (ast-type->size info `("tag" ,type))))
|
||||||
(list name `("tag" ,type) size 0)))
|
(list name `("tag" ,type) size 0)))
|
||||||
|
|
||||||
|
((comp-decl (decl-spec-list (type-spec (struct-def (field-list . ,fields)))))
|
||||||
|
`(struct ,@(map (struct-field info) fields)))
|
||||||
|
|
||||||
((comp-decl (decl-spec-list (type-spec (union-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name))))
|
((comp-decl (decl-spec-list (type-spec (union-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name))))
|
||||||
(let ((size (ast-type->size info `("tag" ,type))))
|
(let ((size (ast-type->size info `("tag" ,type))))
|
||||||
(list name `("tag" ,type) size 0)))
|
(list name `("tag" ,type) size 0)))
|
||||||
|
|
62
scaffold/tests/7i-struct-struct.c
Normal file
62
scaffold/tests/7i-struct-struct.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/* -*-comment-start: "//";comment-end:""-*-
|
||||||
|
* Mes --- Maxwell Equations of Software
|
||||||
|
* Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||||
|
*
|
||||||
|
* This file is part of Mes.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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 Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "30-test.i"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct s
|
||||||
|
{
|
||||||
|
int bar;
|
||||||
|
int baz;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct foo
|
||||||
|
{
|
||||||
|
struct s s;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct anon
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
int bar;
|
||||||
|
int baz;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
test ()
|
||||||
|
{
|
||||||
|
struct foo f = {1,2};
|
||||||
|
f.s.baz = 2; // FIXME
|
||||||
|
printf ("f.s.bar=%d\n", f.s.bar);
|
||||||
|
if (f.s.bar != 1) return 1;
|
||||||
|
printf ("f.s.baz=%d\n", f.s.baz);
|
||||||
|
if (f.s.baz != 2) return 2;
|
||||||
|
|
||||||
|
struct anon a = {3,4};
|
||||||
|
a.baz = 4; // FIXME
|
||||||
|
printf ("a.bar=%d\n", a.bar);
|
||||||
|
if (a.bar != 3) return 1;
|
||||||
|
printf ("a.baz=%d\n", a.baz);
|
||||||
|
if (a.baz != 4) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue