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

* module/language/c99/compiler.mes (expr->accu, expr->accu*): fixes
  for foo->bar[baz].
  (expr->pointer): Support i-sel.
  (p-expr->type): Support add, sub, de-ref, ref-to.
* scaffold/tests/7f-struct-pointer-arithmetic.c: Test it.
* make.scm (add-scaffold-test): Build it.
This commit is contained in:
Jan Nieuwenhuizen 2017-08-05 19:10:00 +02:00
parent 31c69b8b00
commit 95f107282d
3 changed files with 98 additions and 2 deletions

View file

@ -164,7 +164,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
"7b-struct-int-array" "7b-struct-int-array"
"7c-dynarray" "7c-dynarray"
"7d-cast-char" "7d-cast-char"
"7e-struct-array-access")) "7e-struct-array-access"
"7f-struct-pointer-arithmetic"))
(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)))

View file

@ -812,18 +812,27 @@
((add ,a (p-expr (fixed ,value))) ((add ,a (p-expr (fixed ,value)))
(let* ((ptr (expr->pointer info a)) (let* ((ptr (expr->pointer info a))
(size (cond ((= ptr 1) (expr->size 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) ((> ptr 1) 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))
(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)
(else 1)))) (else 1))))
(if (not (= size 1)) (if (not (= size 1))
(warn (format #f "TODO: pointer arithmetic: ~s\n" o)))) (warn (format #f "TODO: pointer arithmetic: ~s\n" o))))
@ -837,6 +846,8 @@
(info ((expr->accu info) a)) (info ((expr->accu info) a))
(value (cstring->number value)) (value (cstring->number value))
(value (* size value))) (value (* size value)))
(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))))))
((sub ,a ,b) ((sub ,a ,b)
@ -1137,9 +1148,13 @@
(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)))
(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)))
(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) (append-text info (append (wrap-as (append (i386:accu->base)
(if (eq? size 1) '() (if (eq? size 1) '()
(append (append
@ -1150,6 +1165,7 @@
(i386:accu-shl 2))))) (i386:accu-shl 2)))))
(wrap-as (i386:push-accu)) (wrap-as (i386:push-accu))
((ident-address->accu info) struct0) ((ident-address->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)
(i386:accu+base))))))) (i386:accu+base)))))))
@ -1160,6 +1176,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)))
(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)))
@ -1173,6 +1190,7 @@
(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)
(i386:accu+base))))))) (i386:accu+base)))))))
@ -1663,6 +1681,12 @@
((pre-dec ,a) (expr->pointer info a)) ((pre-dec ,a) (expr->pointer info a))
((post-inc ,a) (expr->pointer info a)) ((post-inc ,a) (expr->pointer info a))
((post-dec ,a) (expr->pointer info a)) ((post-dec ,a) (expr->pointer info a))
((d-sel (ident ,field) (p-expr (ident ,struct)))
(let ((type (ident->type info struct)))
(field-pointer info type field)))
((i-sel (ident ,field) (p-expr (ident ,struct)))
(let ((type (ident->type info struct)))
(field-pointer info type field)))
((cast (type-name ,type (abs-declr ,pointer)) (p-expr (ident ,name))) ((cast (type-name ,type (abs-declr ,pointer)) (p-expr (ident ,name)))
(let* ((type (ast-type->type info type)) (let* ((type (ast-type->type info type))
(pointer0 (type:pointer type)) (pointer0 (type:pointer type))
@ -1701,6 +1725,12 @@
(let* ((type0 (ident->type info array)) (let* ((type0 (ident->type info array))
(type0 (if (pair? type0) type0 `("tag" ,type0)))) (type0 (if (pair? type0) type0 `("tag" ,type0))))
(field-type info type0 field))) (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)))) (_ (error "p-expr->type: unsupported: " o))))
(define (local-var? o) ;; formals < 0, locals > 0 (define (local-var? o) ;; formals < 0, locals > 0

View file

@ -0,0 +1,65 @@
/* -*-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 <mlibc.h>
#include <stdio.h>
struct foo;
struct foo {
struct foo **foo;
};
struct foo g_foo[2];
int
test ()
{
struct foo foo;
foo.foo = g_foo;
void *p;
void *q;
p = &foo.foo[0];
q = foo.foo;
eputs ("f:"); eputs (itoa (foo.foo)); eputs ("\n");
eputs ("p:"); eputs (itoa (p)); eputs ("\n");
eputs ("q:"); eputs (itoa (q)); eputs ("\n");
if (q != p) return 1;
p = &foo.foo[1];
q = foo.foo + 1;
eputs ("f:"); eputs (itoa (foo.foo)); eputs ("\n");
eputs ("p:"); eputs (itoa (p)); eputs ("\n");
eputs ("q:"); eputs (itoa (q)); eputs ("\n");
if (q != p) return 2;
struct foo *pfoo = &foo;
p = &pfoo->foo[1];
q = pfoo->foo + 1;
eputs ("f:"); eputs (itoa (pfoo->foo)); eputs ("\n");
eputs ("p:"); eputs (itoa (p)); eputs ("\n");
eputs ("q:"); eputs (itoa (q)); eputs ("\n");
if (q != p) return 3;
return 0;
}