mescc: Support struct pointers.

* module/language/c99/compiler.mes (expr->accu): Support
  &struct.field, struct->field.
  (ast->info): Support struct *foo = &bar;
* scaffold/t.c (struct_test): Test it.
This commit is contained in:
Jan Nieuwenhuizen 2017-05-06 11:01:58 +02:00
parent 5246de5e39
commit 6272356959
2 changed files with 37 additions and 2 deletions

View file

@ -390,7 +390,8 @@
;; (i386:global->accu (+ (data-offset o g) d))))) ;; (i386:global->accu (+ (data-offset o g) d)))))
(else (list (lambda (f g ta t d) (else (list (lambda (f g ta t d)
(append (i386:value->accu (+ (data-offset o g) d)))))))) (append (i386:value->accu (+ (data-offset o g) d))))))))
(error "TODO ident-address->accu" o)))))) (list (lambda (f g ta t d)
(i386:global->accu (+ ta (function-offset o f))))))))))
(define (ident-address->base info) (define (ident-address->base info)
(lambda (o) (lambda (o)
@ -532,8 +533,20 @@
(append-text info ((ident->accu info) name))) (append-text info ((ident->accu info) name)))
((initzer ,initzer) ((expr->accu info) initzer)) ((initzer ,initzer) ((expr->accu info) initzer))
;; &foo
((ref-to (p-expr (ident ,name))) ((ref-to (p-expr (ident ,name)))
(append-text info ((ident->accu info) name))) (append-text info ((ident-address->accu info) name)))
;; &f.field
((ref-to (d-sel (ident ,field) (p-expr (ident ,array))))
(let* ((type (ident->type info array))
(fields (type->description info type))
(field-size 4) ;; FIXME:4, not fixed
(offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
(text (.text info)))
(append-text info (append ((ident->accu info) array)
(wrap-as (i386:accu+n offset))))))
((sizeof-type (type-name (decl-spec-list (type-spec (struct-ref (ident ,name)))))) ((sizeof-type (type-name (decl-spec-list (type-spec (struct-ref (ident ,name))))))
(let* ((type (list "struct" name)) (let* ((type (list "struct" name))
@ -576,6 +589,16 @@
(info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array)))))) (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array))))))
(append-text info (wrap-as (i386:mem+n->accu offset))))) (append-text info (wrap-as (i386:mem+n->accu offset)))))
((i-sel (ident ,field) (p-expr (ident ,array)))
(let* ((type (ident->type info array))
(fields (type->description info type))
(field-size 4) ;; FIXME:4, not fixed
(offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
(text (.text info)))
(append-text info (append ((ident-address->accu info) array)
(wrap-as (i386:mem->accu))
(wrap-as (i386:mem+n->accu offset))))))
;;; FIXME: FROM INFO ...only zero?! ;;; FIXME: FROM INFO ...only zero?!
((p-expr (fixed ,value)) ((p-expr (fixed ,value))
(let ((value (cstring->number value))) (let ((value (cstring->number value)))
@ -1690,6 +1713,14 @@
((ast->info info) ((ast->info info)
`(decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (ident ,name))))))) `(decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (ident ,name)))))))
;; struct foo* bar = expr;
((decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (ref-to (p-expr (ident ,value)))))))
(if (.function info) (let* ((locals (add-local locals name (list "struct" type) 1))
(info (clone info #:locals locals)))
(append-text info (append ((ident-address->accu info) value)
((accu->ident info) name))))
(error "ast->info: unsupported global:" o)))
;; char *p = &bla; ;; char *p = &bla;
((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (ref-to (p-expr (ident ,value))))))) ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ptr-declr (pointer) (ident ,name)) (initzer (ref-to (p-expr (ident ,value)))))))
(let ((type (decl->type type))) (let ((type (decl->type type)))

View file

@ -478,6 +478,10 @@ struct_test ()
puts ("t: g_functions[g_function++] = g_foo;\n"); puts ("t: g_functions[g_function++] = g_foo;\n");
g_functions[g_function++] = g_foo; g_functions[g_function++] = g_foo;
puts ("t: pbar->arity == 1\n");
struct function* barp = &g_bar;
if (barp->arity != 1) return 1;
int fn = 0; int fn = 0;
puts ("t: g_functions[g_cells[fn].cdr].arity\n"); puts ("t: g_functions[g_cells[fn].cdr].arity\n");
if (g_functions[g_cells[fn].cdr].arity) return 1; if (g_functions[g_cells[fn].cdr].arity) return 1;