From ad9f171c49f93653a39ea57d3a007ee6c71204c7 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sat, 12 May 2018 00:20:51 +0200 Subject: [PATCH] mescc: Tinycc support: Implement ((struct foo*)p)->bar. * module/language/c99/compiler.mes (expr->accu*): * scaffold/tests/7p-struct-cast.c: Test it. * build-aux/check-mescc.sh (tests): Run it. --- build-aux/check-mescc.sh | 1 + module/language/c99/compiler.mes | 50 ++++++++++++++++++++++++++++---- scaffold/tests/7p-struct-cast.c | 35 ++++++++++++++++++++++ 3 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 scaffold/tests/7p-struct-cast.c diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 59d2328d..094edae0 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -112,6 +112,7 @@ t 7m-struct-char-array-assign 7n-struct-struct-array 7o-struct-pre-post +7p-struct-cast 80-setjmp 81-qsort 82-define diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 947ab1df..82bb1b50 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -812,15 +812,47 @@ (info (expr->base array info))) (append-text info (wrap-as (i386:accu+base))))) - ;;((cast (type-name (decl-spec-list (type-spec (typename "Elf32_Rel"))) (abs-declr (pointer))) (add (i-sel (ident "data") (p-expr (ident "sr"))) (p-expr (ident "a"))))) - ((cast ,type ,expr) - (expr->accu expr info)) + (expr->accu `(ref-to ,expr) info)) - ;; ((post-dec (p-expr (ident "vtop")))) + ((add ,a ,b) + (let* ((rank (expr->rank info a)) + (rank-b (expr->rank info b)) + (type (ast->basic-type a info)) + (struct? (structured-type? type)) + (size (cond ((= rank 1) (ast-type->size info a)) + ((> rank 1) 4) + ((and struct? (= rank 2)) 4) + (else 1)))) + (if (or (= size 1)) ((binop->accu* info) a b (i386:accu+base)) + (let* ((info (expr->accu b info)) + (info (append-text info (wrap-as (append (i386:value->base size) + (i386:accu*base) + (i386:accu->base))))) + (info (expr->accu* a info))) + (append-text info (wrap-as (i386:accu+base))))))) - ;; ((cast ,type ,expr) - ;; (expr->accu `(ref-to ,expr) info)) + ((sub ,a ,b) + (let* ((rank (expr->rank info a)) + (rank-b (expr->rank info b)) + (type (ast->basic-type a info)) + (struct? (structured-type? type)) + (size (->size type)) + (size (cond ((= rank 1) size) + ((> rank 1) 4) + ((and struct? (= rank 2)) 4) + (else 1)))) + (if (or (= size 1) (or (= rank-b 2) (= rank-b 1))) + (let ((info ((binop->accu* info) a b (i386:accu-base)))) + (if (and (not (= rank-b 2)) (not (= rank-b 1))) info + (append-text info (wrap-as (append (i386:value->base size) + (i386:accu/base)))))) + (let* ((info (expr->accu* b info)) + (info (append-text info (wrap-as (append (i386:value->base size) + (i386:accu*base) + (i386:accu->base))))) + (info (expr->accu* a info))) + (append-text info (wrap-as (i386:accu-base))))))) ((pre-dec ,expr) (let* ((rank (expr->rank info expr)) @@ -1285,6 +1317,12 @@ (info (expr->base b info))) (append-text info (wrap-as c))))) +(define (binop->accu* info) + (lambda (a b c) + (let* ((info (expr->accu* a info)) + (info (expr->base b info))) + (append-text info (wrap-as c))))) + (define (wrap-as o . annotation) `(,@annotation ,o)) diff --git a/scaffold/tests/7p-struct-cast.c b/scaffold/tests/7p-struct-cast.c new file mode 100644 index 00000000..e3bb51a2 --- /dev/null +++ b/scaffold/tests/7p-struct-cast.c @@ -0,0 +1,35 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) 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 . + */ + +struct foo {int length; char* string;}; + +int +main () +{ + struct foo f = {3, "foo"}; + struct foo *pf = &f; + char *p = (char*)&f; + int i = 0; + i = ((struct foo*)p)->length; + i = 0; + i = ((struct foo*)(p + i))->length; + + return i - 3; +}