mescc: Tinycc support: int foo[bar] = {baz,...}.

* scaffold/tests/79-int-array.c: Test it.
* make.scm (add-scaffold-test): Build it.
* module/language/c99/compiler.mes (init-declr->count): New function.
  (decl->info): Support int foo[bar] = {baz,...}.
This commit is contained in:
Jan Nieuwenhuizen 2017-07-30 08:27:05 +02:00
parent bd3ab85e98
commit 9c4519af8d
3 changed files with 119 additions and 2 deletions

View File

@ -158,7 +158,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
"75-struct-union"
"76-pointer-arithmetic"
"77-pointer-assign"
"78-union-struct"))
"78-union-struct"
"79-int-array"))
(add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))

View File

@ -1663,6 +1663,11 @@
((ptr-declr (pointer) (array-of (ident ,name) (p-expr ,size))) name)
(_ (error "init-declr->name unsupported: " o))))
(define (init-declr->count info o)
(pmatch o
((array-of (ident ,name) ,count) (p-expr->number info count))
(_ #f)))
(define (init-declr->pointer o)
(pmatch o
((ident ,name) 0)
@ -2047,6 +2052,37 @@
(globals (append globals (list global))))
(clone info #:globals globals)))))
;; int foo[2] = { ... }
((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (array-of (ident ,name) ,count) (initzer (initzer-list . ,initzers)))))
(let* ((info (type->info info type))
(xtype type)
(type (decl->ast-type type))
(pointer -1)
(initzer-globals (filter identity (append-map (initzer->globals globals) initzers)))
(global-names (map car globals))
(initzer-globals (filter (lambda (g) (and g (not (member (car g) global-names)))) initzer-globals))
(initzers ((initzer->non-const info) initzers))
(info (append-text info (ast->comment o)))
(globals (append globals initzer-globals))
(info (clone info #:globals globals))
(size 4)
(count (p-expr->number info count))
(size (* count size)))
(if (.function info)
(let* ((local (car (add-local locals name type 1)))
(local (make-local-entry name type pointer (+ (local:id (cdr local)) -1 (quotient (+ size 3) 4))))
(locals (cons local locals))
(info (clone info #:locals locals))
(info (let loop ((info info) (initzers initzers) (id (local:id (cdr local))))
(if (null? initzers) info
(let* ((info ((initzer->accu info) (car initzers)))
(info (append-text info (wrap-as (i386:accu->local id)))))
(loop info (cdr initzers) (1- id)))))))
info)
(let* ((global (make-global-entry name type pointer (append-map (initzer->data info) initzers)))
(globals (append globals (list global))))
(clone info #:globals globals)))))
((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr ,init . ,initzer)))
(let* ((info (type->info info type))
(xtype type)
@ -2066,7 +2102,9 @@
(memq (type:type (ast-type->type info xtype)) '(struct union)))))
(pointer (if struct? -1 pointer))
(size (if (<= pointer 0) (ast-type->size info type)
4)))
4))
(count (init-declr->count info init)) ; array... split me up?
(size (if count (* count size) size)))
(if (.function info)
(let* ((locals (if (or (> pointer 0) (<= size 4)) (add-local locals name type pointer)
(let* ((local (car (add-local locals name type 1)))
@ -2074,6 +2112,7 @@
(cons local locals))))
(info (clone info #:locals locals))
(info (if (null? initzer) info ((initzer->accu info) (car initzer))))
;; FIXME array...struct?
(info (if (null? initzer) info (append-text info ((accu->ident info) name)))))
info)
(let* ((global (make-global-entry name type pointer (if (null? initzer) (string->list (make-string size #\nul))

View File

@ -0,0 +1,77 @@
/* -*-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 <stdio.h>
#include <stdint.h>
struct foo {
int *bar;
};
struct foo f;
void *
memcpy (void *dest, void const *src, size_t n)
{
char* p = dest;
char* q = src;
while (n--) *p++ = *q++;
return dest;
}
int bla[6] = {0,0,11223344, 55667788,0,0};
int g_c[2] = {101, 111};
int
test ()
{
f.bar = bla;
struct foo *pf = &f;
int *b = pf->bar;
if (bla[2] != 11223344) return 1;
if (bla[3] != 55667788) return 2;
if (b[2] != 11223344) return 3;
if (b[3] != 55667788) return 4;
eputs ("g_c[0]="); eputs (itoa (g_c[0])); eputs ("\n");
eputs ("g_c[1]="); eputs (itoa (g_c[1])); eputs ("\n");
memcpy (&b[2], g_c, 2 * sizeof (int));
eputs ("b[2]:"); eputs (itoa (b[2])); eputs ("\n");
if (b[2] != 101) return 5;
eputs ("b[3]:"); eputs (itoa (b[3])); eputs ("\n");
if (b[3] != 111) return 6;
int c[2] = {201, 211};
eputs ("c[0]="); eputs (itoa (c[0])); eputs ("\n");
eputs ("c[1]="); eputs (itoa (c[1])); eputs ("\n");
memcpy (&b[4], c, 2 * sizeof (int));
eputs ("b[4]:"); eputs (itoa (b[4])); eputs ("\n");
if (b[4] != 201) return 5;
eputs ("b[5]:"); eputs (itoa (b[5])); eputs ("\n");
if (b[5] != 211) return 6;
return 0;
}