From 1e37c9d9eac8ef83edcb6fa9d2381f45dffd2f91 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Mon, 31 Jul 2017 12:19:23 +0200 Subject: [PATCH] mescc: Tinycc support: ((foo*) p) + n. * module/language/c99/compiler.mes init-declr->pointer, expr->pointer, expr->size): support: ((foo*) p) + n. (expr->accu*): Consider field size for foo.bar[baz]. * scaffold/tests/7b-struct-int-array.c: Test it. * make.scm (add-scaffold-test): Build it. --- make.scm | 3 +- module/language/c99/compiler.mes | 29 ++++++--- scaffold/tests/7a-struct-char-array.c | 10 ++- scaffold/tests/7b-struct-int-array.c | 87 +++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 scaffold/tests/7b-struct-int-array.c diff --git a/make.scm b/make.scm index 65c0710e..f86dc99d 100755 --- a/make.scm +++ b/make.scm @@ -160,7 +160,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$ "77-pointer-assign" "78-union-struct" "79-int-array" - "7a-struct-char-array")) + "7a-struct-char-array" + "7b-struct-int-array")) (add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets))) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index b3b46409..55bea4a8 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -822,7 +822,6 @@ (info ((expr->accu info) a)) (value (cstring->number value)) (value (* size value))) - (stderr "sub[~s]: ~s + ~s\n" size a value) (append-text info (wrap-as (i386:accu+value (- value)))))) ((sub ,a ,b) @@ -1123,7 +1122,9 @@ (type1 (field-type info type0 field0)) (offset (field-offset info type0 field0)) (info ((expr->accu info) index)) - (size (ast-type->size info type1))) + (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 @@ -1131,8 +1132,8 @@ (i386:accu+accu)) (if (<= size 8) '() (i386:accu+base)) - (i386:accu-shl 2)))) - (i386:push-accu)) + (i386:accu-shl 2))))) + (wrap-as (i386:push-accu)) ((ident-address->accu info) struct0) (wrap-as (append (i386:accu+value offset) (i386:pop-base) @@ -1144,7 +1145,9 @@ (type1 (field-type info type0 field0)) (offset (field-offset info type0 field0)) (info ((expr->accu info) index)) - (size (ast-type->size info type1))) + (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 @@ -1152,8 +1155,8 @@ (i386:accu+accu)) (if (<= size 8) '() (i386:accu+base)) - (i386:accu-shl 2)))) - (i386:push-accu)) + (i386:accu-shl 2))))) + (wrap-as (i386:push-accu)) ((ident->accu info) struct0) (wrap-as (append (i386:accu+value offset) (i386:pop-base) @@ -1273,8 +1276,8 @@ (define (ast-type->type info o) (pmatch o ((p-expr ,expr) (ast-type->type info (p-expr->type info o))) - ((decl-spec-list (type-spec (fixed-type ,type))) - (ast-type->type info type)) + ((decl-spec-list ,type-spec) + (ast-type->type info type-spec)) ((decl-spec-list (type-qual ,qual) (type-spec (fixed-type ,type))) (ast-type->type info type)) ((struct-ref (ident (,type))) @@ -1640,6 +1643,11 @@ ((pre-dec ,a) (expr->pointer info a)) ((post-inc ,a) (expr->pointer info a)) ((post-dec ,a) (expr->pointer info a)) + ((cast (type-name ,type (abs-declr ,pointer)) (p-expr (ident ,name))) + (let* ((type (ast-type->type info type)) + (pointer0 (type:pointer type)) + (pointer1 (ptr-declr->pointer pointer))) + (+ pointer0 pointer1))) (_ (stderr "expr->pointer: unsupported: ~s\n" o) 0))) (define (expr->size info o) @@ -1652,6 +1660,9 @@ ((pre-dec ,a) (expr->size info a)) ((post-inc ,a) (expr->size info a)) ((post-dec ,a) (expr->size info a)) + ((cast (type-name ,type (abs-declr ,pointer)) (p-expr (ident ,name))) + (let ((type (ast-type->type info type))) + (type:size type))) (_ (stderr "expr->size: unsupported: ~s\n" o) 4))) (define (p-expr->type info o) diff --git a/scaffold/tests/7a-struct-char-array.c b/scaffold/tests/7a-struct-char-array.c index ef5e11e5..3d9c45b2 100644 --- a/scaffold/tests/7a-struct-char-array.c +++ b/scaffold/tests/7a-struct-char-array.c @@ -70,14 +70,18 @@ test () if (pfile->buffer[4] != '4') return 3; memcpy (pfile->buffer + 4, " ", 1); + eputs (file.buffer); + if (p[4] != ' ') return 4; + if (file.buffer[4] != ' ') return 5; + if (pfile->buffer[4] != ' ') return 6; strcpy (file.buffer, "0123456789\n"); eputs (file.buffer); p[4] = 'A'; eputs (file.buffer); - if (p[4] != 'A') return 4; - if (file.buffer[4] != 'A') return 5; - if (pfile->buffer[4] != 'A') return 6; + if (p[4] != 'A') return 7; + if (file.buffer[4] != 'A') return 8; + if (pfile->buffer[4] != 'A') return 9; return 0; } diff --git a/scaffold/tests/7b-struct-int-array.c b/scaffold/tests/7b-struct-int-array.c new file mode 100644 index 00000000..e402716d --- /dev/null +++ b/scaffold/tests/7b-struct-int-array.c @@ -0,0 +1,87 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2017 Jan Nieuwenhuizen + * + * 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 . + */ + +#include "30-test.i" + +struct foo { + int a; + int b; +}; + +struct foo g_foo[2] = {0,1,2,3}; + +struct bar +{ + int bar[4]; +}; + +struct bar g_bar = {101,102}; +typedef struct bar bar_struct; +typedef struct bar foo_struct; + +int +test () +{ + if (g_foo[0].a != 0) return 1; + if (g_foo[0].b != 1) return 2; + if (g_foo[1].a != 2) return 3; + if (g_foo[1].b != 3) return 4; + + void *p = &g_foo; + struct foo* pfoo = (((struct foo *)p) + 1); + if (pfoo->a != 2) return 5; + if (pfoo->b != 3) return 6; + + int *pi = &g_foo; + if (*pi != 0) return 5; + + pi = &g_bar; + if (*pi != 101) return 6; + + struct bar bar = {0x22, 0x33}; + pi = &bar; + if (*pi != 0x22) return 6; + + bar_struct bs; + bs.bar[0] = 102; + pi = &bs; + if (*pi != 102) return 7; + + foo_struct fs; + fs.bar[0] = 0x22; + fs.bar[1] = 0x33; + + pi = &fs; + if (*pi != 0x22) return 7; + pi++; + + if (*pi != 0x33) return 8; + + foo_struct *pfs = &fs; + pfs->bar[3] = 0x44; + pfs->bar[4] = 0x55; + + pi = &fs.bar[3]; + if (*pi != 0x44) return 9; + pi++; + if (*pi != 0x55) return 10; + + return 0; +}