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:
Jan Nieuwenhuizen 2017-08-10 21:36:49 +02:00
parent 5230ddc93b
commit 3392f7241a
3 changed files with 78 additions and 6 deletions

View file

@ -167,7 +167,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
"7e-struct-array-access"
"7f-struct-pointer-arithmetic"
"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)))

View file

@ -1290,29 +1290,28 @@
(define (field:name o)
(pmatch o
((struct (,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) name)
(_ (error "field:name not supported:" o))))
(define (field:pointer o)
(pmatch o
((struct (,name ,type ,size ,pointer) . ,rest) pointer)
((union (,name ,type ,size ,pointer) . ,rest) pointer)
((,name ,type ,size ,pointer) pointer)
(_ (error "field:name not supported:" o))))
(define (field:size o)
(pmatch o
((struct . ,fields) (apply + (map field:size fields)))
((union . ,fields) 4) ;; FIXME
((,name ,type ,size ,pointer) size)
;;((,name ,type ,size) size)
(_ 4)))
(define (field:type o)
(pmatch o
((,name ,type ,size ,pointer) type)
;;((,name ,type ,size) type)
(_ (error "field:type:" o))))
(define (get-type types o)
@ -1375,7 +1374,7 @@
(if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
(let ((f (car fields)))
(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))))
(else (loop (cdr fields)))))))))
@ -1388,6 +1387,13 @@
(if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
(let ((f (car fields)))
(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)
(find (lambda (x) (equal? (car x) field)) (cdr f))
offset))
@ -1656,6 +1662,9 @@
(let ((size (ast-type->size info `("tag" ,type))))
(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))))
(let ((size (ast-type->size info `("tag" ,type))))
(list name `("tag" ,type) size 0)))

View 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;
}