mescc: Tinycc support: fixes for foo.bar[baz].

* module/language/c99/compiler.mes (expr->accu, expr->accu*): fixes for foo.bar[baz].
* scaffold/tests/7c-dynarray.c: Test it.
This commit is contained in:
Jan Nieuwenhuizen 2017-08-05 21:09:19 +02:00
parent 95f107282d
commit dd66f9b5d2
4 changed files with 119 additions and 70 deletions

View file

@ -570,25 +570,20 @@
(let* ((info ((expr->accu* info) o)) (let* ((info ((expr->accu* info) o))
(type0 (ident->type info struct0)) (type0 (ident->type info struct0))
(type1 (field-type info type0 field0)) (type1 (field-type info type0 field0))
(struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
(ptr (field-pointer info type0 field0)) (ptr (field-pointer info type0 field0))
(size (ast-type->size info type1))) (size (ast-type->size info type1)))
(if (= ptr -3) info (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu)
(append-text info (wrap-as (append (if (and (= ptr -2) struct?) (i386:mem->accu) '()) (i386:mem->accu))))))
(if (= size 1) (i386:byte-mem->accu)
(i386:mem->accu))))))))
;; foo->bar[baz]) ;; foo->bar[baz])
((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0)))) ((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0))))
(let* ((info ((expr->accu* info) o)) (let* ((info ((expr->accu* info) o))
(type0 (ident->type info struct0)) (type0 (ident->type info struct0))
(type1 (field-type info type0 field0)) (type1 (field-type info type0 field0))
(struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
(ptr (field-pointer info type0 field0)) (ptr (field-pointer info type0 field0))
(size (ast-type->size info type1))) (size (ast-type->size info type1)))
(append-text info (wrap-as (append (if (and (= ptr -2) struct?) (i386:mem->accu) '()) (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu)
(if (= size 1) (i386:byte-mem->accu) (i386:mem->accu))))))
(i386:mem->accu)))))))
;; <expr>[baz] ;; <expr>[baz]
((array-ref ,index ,array) ((array-ref ,index ,array)
@ -817,26 +812,23 @@
(size (cond ((= ptr 1) (expr->size info a)) (size (cond ((= ptr 1) (expr->size info a))
((> ptr 1) 4) ((> ptr 1) 4)
((and struct? (= ptr -2)) 4) ((and struct? (= ptr -2)) 4)
((and struct? (= ptr 2)) 4)
(else 1))) (else 1)))
(info ((expr->accu info) a)) (info ((expr->accu info) a))
(value (cstring->number value)) (value (cstring->number value))
(value (* size value))) (value (* size value)))
(stderr "ptr=~s\n" ptr)
(stderr " size=~s\n" size)
(stderr " struct?=~s\n" struct?)
(if (not (= size 1))
(warn (format #f "TODO: pointer arithmetic: ~s\n" o)))
(append-text info (wrap-as (i386:accu+value value))))) (append-text info (wrap-as (i386:accu+value value)))))
((add ,a ,b) ((add ,a ,b)
(let* ((ptr (expr->pointer info a)) (let* ((ptr (expr->pointer info a))
(type0 (p-expr->type info a))
(struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
(size (cond ((= ptr 1) (expr->size info a)) (size (cond ((= ptr 1) (expr->size info a))
((> ptr 1) 4) ((> ptr 1) 4)
((and struct? (= ptr -2)) 4) ((and struct? (= ptr -2)) 4)
((and struct? (= ptr 2)) 4)
(else 1)))) (else 1))))
(if (not (= size 1)) ((binop->accu info) a b (i386:accu+base))))
(warn (format #f "TODO: pointer arithmetic: ~s\n" o))))
((binop->accu info) a b (i386:accu+base)))
((sub ,a (p-expr (fixed ,value))) ((sub ,a (p-expr (fixed ,value)))
(let* ((ptr (expr->pointer info a)) (let* ((ptr (expr->pointer info a))
@ -1148,35 +1140,7 @@
(type1 (field-type info type0 field0)) (type1 (field-type info type0 field0))
(offset (field-offset info type0 field0)) (offset (field-offset info type0 field0))
(info ((expr->accu info) index)) (info ((expr->accu info) index))
(struct? (memq (type:type (ast-type->type info type0)) '(struct union))) (struct? (or #t (memq (type:type (ast-type->type info type0)) '(struct union))))
(ptr (field-pointer info type0 field0))
(size (if (= ptr -1) (ast-type->size info type1)
4)))
(stderr "ACCU* o=~s\n" o)
(stderr " ptr=~s\n" ptr)
(stderr " size=~s\n" size)
(append-text info (append (wrap-as (append (i386:accu->base)
(if (eq? size 1) '()
(append
(if (<= size 4) '()
(i386:accu+accu))
(if (<= size 8) '()
(i386:accu+base))
(i386:accu-shl 2)))))
(wrap-as (i386:push-accu))
((ident-address->accu info) struct0)
(if (and struct? (= ptr -2)) (wrap-as (i386:mem->accu)) '())
(wrap-as (append (i386:accu+value offset)
(i386:pop-base)
(i386:accu+base)))))))
;; foo->bar[baz]
((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0))))
(let* ((type0 (ident->type info struct0))
(type1 (field-type info type0 field0))
(offset (field-offset info type0 field0))
(info ((expr->accu info) index))
(struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
(ptr (field-pointer info type0 field0)) (ptr (field-pointer info type0 field0))
(size (if (= ptr -1) (ast-type->size info type1) (size (if (= ptr -1) (ast-type->size info type1)
4))) 4)))
@ -1190,9 +1154,36 @@
(i386:accu-shl 2))))) (i386:accu-shl 2)))))
(wrap-as (i386:push-accu)) (wrap-as (i386:push-accu))
((ident->accu info) struct0) ((ident->accu info) struct0)
(if (and struct? (= ptr -2)) (wrap-as (i386:mem->accu)) '())
(wrap-as (append (i386:accu+value offset) (wrap-as (append (i386:accu+value offset)
(i386:pop-base) (i386:pop-base)
(if (and struct? (or (= ptr -2)
(= ptr 2))) (i386:mem->accu) '())
(i386:accu+base)))))))
;; foo->bar[baz]
((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0))))
(let* ((type0 (ident->type info struct0))
(type1 (field-type info type0 field0))
(offset (field-offset info type0 field0))
(info ((expr->accu info) index))
(struct? (or #t (memq (type:type (ast-type->type info type0)) '(struct union))))
(ptr (field-pointer info type0 field0))
(size (if (= ptr -1) (ast-type->size info type1)
4)))
(append-text info (append (wrap-as (append (i386:accu->base)
(if (eq? size 1) '()
(append
(if (<= size 4) '()
(i386:accu+accu))
(if (<= size 8) '()
(i386:accu+base))
(i386:accu-shl 2)))))
(wrap-as (i386:push-accu))
((ident->accu info) struct0)
(wrap-as (append (i386:accu+value offset)
(i386:pop-base)
(if (and struct? (or (= ptr -2)
(= ptr 2))) (i386:mem->accu) '())
(i386:accu+base))))))) (i386:accu+base)))))))
((array-ref ,index ,array) ((array-ref ,index ,array)
@ -1331,6 +1322,12 @@
((type-spec ,type) (ast-type->type info type)) ((type-spec ,type) (ast-type->type info type))
((fixed-type ,type) (ast-type->type info type)) ((fixed-type ,type) (ast-type->type info type))
((typename ,type) (ast-type->type info type)) ((typename ,type) (ast-type->type info type))
((d-sel (idend ,field) ,struct)
(let ((type0 (ast-type->type info struct)))
(field-type info type0 field)))
((i-sel (ident ,field) ,struct)
(let ((type0 (ast-type->type info struct)))
(field-type info type0 field)))
(_ (let ((type (get-type (.types info) o))) (_ (let ((type (get-type (.types info) o)))
(if type type (if type type
(begin (begin
@ -1338,15 +1335,20 @@
(error "ast-type->type: unsupported: " o))))))) (error "ast-type->type: unsupported: " o)))))))
(define (ast-type->description info o) (define (ast-type->description info o)
(let ((type (ast-type->type info o))) (let* ((type (ast-type->type info o))
(type:description type))) (xtype (if (type? type) type
(ast-type->type info type))))
(type:description xtype)))
(define (ast-type->size info o) (define (ast-type->size info o)
(let ((type (ast-type->type info o))) (let* ((type (ast-type->type info o))
(type:size type))) (xtype (if (type? type) type
(ast-type->type info type))))
(type:size xtype)))
(define (field-field info struct field) (define (field-field info struct field)
(let* ((xtype (ast-type->type info struct)) (let* ((xtype (if (type? struct) struct
(ast-type->type info struct)))
(fields (type:description xtype))) (fields (type:description xtype)))
(let loop ((fields fields)) (let loop ((fields fields))
(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))
@ -1357,7 +1359,8 @@
(else (loop (cdr fields))))))))) (else (loop (cdr fields)))))))))
(define (field-offset info struct field) (define (field-offset info struct field)
(let ((xtype (ast-type->type info struct))) (let ((xtype (if (type? struct) struct
(ast-type->type info struct))))
(if (eq? (type:type xtype) 'union) 0 (if (eq? (type:type xtype) 'union) 0
(let ((fields (type:description xtype))) (let ((fields (type:description xtype)))
(let loop ((fields fields) (offset 0)) (let loop ((fields fields) (offset 0))
@ -1370,20 +1373,19 @@
(else (loop (cdr fields) (+ offset (field:size f)))))))))))) (else (loop (cdr fields) (+ offset (field:size f))))))))))))
(define (field-pointer info struct field) (define (field-pointer info struct field)
(let ((xtype (ast-type->type info struct))) (let ((field (field-field info struct field)))
(let ((field (field-field info struct field))) (field:pointer field)))
(field:pointer field))))
(define (field-size info struct field) (define (field-size info struct field)
(let ((xtype (ast-type->type info struct))) (let ((xtype (if (type? struct) struct
(ast-type->type info struct))))
(if (eq? (type:type xtype) 'union) 0 (if (eq? (type:type xtype) 'union) 0
(let ((field (field-field info struct field))) (let ((field (field-field info struct field)))
(field:size field))))) (field:size field)))))
(define (field-type info struct field) (define (field-type info struct field)
(let ((xtype (ast-type->type info struct))) (let ((field (field-field info struct field)))
(let ((field (field-field info struct field))) (field:type field)))
(field:type field))))
(define (ast->type o) (define (ast->type o)
(pmatch o (pmatch o
@ -1673,9 +1675,11 @@
(define (expr->pointer info o) (define (expr->pointer info o)
(pmatch o (pmatch o
((p-expr (fixed ,value)) 0)
((p-expr (ident ,name)) (ident->pointer info name)) ((p-expr (ident ,name)) (ident->pointer info name))
((de-ref ,expr) (1- (expr->pointer info expr))) ((de-ref ,expr) (1- (expr->pointer info expr)))
((add ,a ,b) (expr->pointer info a)) ((add ,a ,b) (expr->pointer info a))
((neg ,a) (expr->pointer info a))
((sub ,a ,b) (expr->pointer info a)) ((sub ,a ,b) (expr->pointer info a))
((pre-inc ,a) (expr->pointer info a)) ((pre-inc ,a) (expr->pointer info a))
((pre-dec ,a) (expr->pointer info a)) ((pre-dec ,a) (expr->pointer info a))
@ -1727,11 +1731,18 @@
(field-type info type0 field))) (field-type info type0 field)))
((de-ref ,expr) (p-expr->type info expr)) ((de-ref ,expr) (p-expr->type info expr))
((ref-to ,expr) (p-expr->type info expr)) ((ref-to ,expr) (p-expr->type info expr))
((add ,a ,b) ((add ,a ,b) (p-expr->type info a))
(p-expr->type info a)) ((sub ,a ,b) (p-expr->type info a))
((sub ,a ,b) ((p-expr (fixed ,value)) "int")
(p-expr->type info a)) ((neg ,a) (p-expr->type info a))
(_ (error "p-expr->type: unsupported: " o)))) ((cast (type-name ,type (abs-declr ,pointer)) (p-expr (ident ,name)))
type)
((fctn-call (p-expr (ident ,name)))
(stderr "TODO: p-expr->type: unsupported: ~s\n" o)
"int")
(_ ;;(error (format #f "p-expr->type: unsupported: ~s") o)
(stderr "TODO: p-expr->type: unsupported: ~s\n" o)
"int")))
(define (local-var? o) ;; formals < 0, locals > 0 (define (local-var? o) ;; formals < 0, locals > 0
(positive? (local:id o))) (positive? (local:id o)))

View file

@ -20,8 +20,9 @@
#include "30-test.i" #include "30-test.i"
#include <mlibc.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <string.h>
struct foo { struct foo {
int *bar; int *bar;

View file

@ -81,7 +81,9 @@ test ()
eputs ("&PATHS="); eputs (itoa (&s->paths)); eputs ("\n"); eputs ("&PATHS="); eputs (itoa (&s->paths)); eputs ("\n");
eputs ("&FILES="); eputs (itoa (&s->files)); eputs ("\n"); eputs ("&FILES="); eputs (itoa (&s->files)); eputs ("\n");
struct file *fs = s->files[0]; struct file *fs;
eputs ("foo\n");
fs = s->files[0];
eputs ("add s= "); eputs (itoa (s)); eputs ("\n"); eputs ("add s= "); eputs (itoa (s)); eputs ("\n");
eputs ("add fs= "); eputs (itoa (fs)); eputs ("\n"); eputs ("add fs= "); eputs (itoa (fs)); eputs ("\n");
eputs ("&fs->[0]="); eputs (itoa (fs->name)); eputs ("\n"); eputs ("&fs->[0]="); eputs (itoa (fs->name)); eputs ("\n");
@ -90,13 +92,46 @@ test ()
eputs ("ps= "); eputs (itoa (s->paths)); eputs ("\n"); eputs ("ps= "); eputs (itoa (s->paths)); eputs ("\n");
eputs ("*ps "); eputs (*s->paths); eputs ("\n"); eputs ("*ps "); eputs (*s->paths); eputs ("\n");
if (strcmp (fs->name, file_name)) return 1; if (strcmp (fs->name, file_name)) return 2;
eputs ("&fs->[0]="); eputs (itoa (fs->name)); eputs ("\n"); eputs ("&fs->[0]="); eputs (itoa (fs->name)); eputs ("\n");
eputs ("fs->name="); eputs (fs->name); eputs ("\n"); eputs ("fs->name="); eputs (fs->name); eputs ("\n");
eputs ("ps= "); eputs (itoa (s->paths)); eputs ("\n"); eputs ("ps= "); eputs (itoa (s->paths)); eputs ("\n");
eputs ("*ps "); eputs (*s->paths); eputs ("\n"); eputs ("*ps "); eputs (*s->paths); eputs ("\n");
file = malloc (sizeof (struct file) + strlen (file_name));
file_name = "hallo";
strcpy (file->name, file_name);
add (&s->files, &s->file_count, file);
struct file **pf = s->files;
fs = pf[0];
eputs ("\n");
eputs ("&fs0*= "); eputs (itoa (&pf[0])); eputs ("\n");
eputs ("fs0*= "); eputs (itoa (fs)); eputs ("\n");
fs = s->files[0];
eputs ("fs0*= "); eputs (itoa (fs)); eputs ("\n");
eputs ("\n");
pf = s->files;
fs = pf[1];
eputs ("&fs1*= "); eputs (itoa (&pf[1])); eputs ("\n");
eputs ("fs1*= "); eputs (itoa (fs)); eputs ("\n");
fs = s->files[1];
eputs ("fs1*= "); eputs (itoa (fs)); eputs ("\n");
eputs ("\n");
if (strcmp (fs->name, file_name)) return 3;
fs = g_s.files[0];
eputs ("gfs0*= "); eputs (itoa (fs)); eputs ("\n");
fs = g_s.files[1];
eputs ("gfs1*= "); eputs (itoa (fs)); eputs ("\n");
eputs ("\n");
if (strcmp (fs->name, file_name)) return 3;
return 0; return 0;
} }

View file

@ -24,9 +24,11 @@
#include <stdio.h> #include <stdio.h>
struct foo; struct foo;
typedef struct foo foo_struct;
struct foo { struct foo {
struct foo **foo; //struct foo **foo;
foo_struct **foo;
}; };
struct foo g_foo[2]; struct foo g_foo[2];