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:
parent
31c69b8b00
commit
95f107282d
3
make.scm
3
make.scm
|
@ -164,7 +164,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
|
|||
"7b-struct-int-array"
|
||||
"7c-dynarray"
|
||||
"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)))
|
||||
|
||||
|
|
|
@ -812,18 +812,27 @@
|
|||
|
||||
((add ,a (p-expr (fixed ,value)))
|
||||
(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)
|
||||
((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))
|
||||
(size (cond ((= ptr 1) (expr->size info a))
|
||||
((> ptr 1) 4)
|
||||
((and struct? (= ptr -2)) 4)
|
||||
(else 1))))
|
||||
(if (not (= size 1))
|
||||
(warn (format #f "TODO: pointer arithmetic: ~s\n" o))))
|
||||
|
@ -837,6 +846,8 @@
|
|||
(info ((expr->accu info) a))
|
||||
(value (cstring->number 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))))))
|
||||
|
||||
((sub ,a ,b)
|
||||
|
@ -1137,9 +1148,13 @@
|
|||
(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
|
||||
|
@ -1150,6 +1165,7 @@
|
|||
(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)))))))
|
||||
|
@ -1160,6 +1176,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)))
|
||||
|
@ -1173,6 +1190,7 @@
|
|||
(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)
|
||||
(i386:accu+base)))))))
|
||||
|
@ -1663,6 +1681,12 @@
|
|||
((pre-dec ,a) (expr->pointer info a))
|
||||
((post-inc ,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)))
|
||||
(let* ((type (ast-type->type info type))
|
||||
(pointer0 (type:pointer type))
|
||||
|
@ -1701,6 +1725,12 @@
|
|||
(let* ((type0 (ident->type info array))
|
||||
(type0 (if (pair? type0) type0 `("tag" ,type0))))
|
||||
(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))))
|
||||
|
||||
(define (local-var? o) ;; formals < 0, locals > 0
|
||||
|
|
65
scaffold/tests/7f-struct-pointer-arithmetic.c
Normal file
65
scaffold/tests/7f-struct-pointer-arithmetic.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue