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

View file

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

View file

@ -81,7 +81,9 @@ test ()
eputs ("&PATHS="); eputs (itoa (&s->paths)); 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 fs= "); eputs (itoa (fs)); eputs ("\n");
eputs ("&fs->[0]="); eputs (itoa (fs->name)); eputs ("\n");
@ -90,7 +92,7 @@ test ()
eputs ("ps= "); eputs (itoa (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->name="); eputs (fs->name); eputs ("\n");
@ -98,5 +100,38 @@ test ()
eputs ("ps= "); eputs (itoa (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;
}

View file

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