mescc: Tinycc support: array[<const-expr>].
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 23 Jul 2017 19:58:34 +0000 (21:58 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Wed, 26 Jul 2017 09:36:44 +0000 (11:36 +0200)
* module/language/c99/compiler.mes (p-expr->number): New function.
  (struct-field, decl->info): Use it to support const expressions in array size.

module/language/c99/compiler.mes

index 832f196edccbafeb540b7f082f0b7cb0020138ee..f271ace6db5cd712ce1915e58c7fd362ca90ac9f 100644 (file)
           ((string-prefix? "0" s) (string->number s 8))
           (else (string->number s)))))
 
+(define (p-expr->number info o)
+  (pmatch o
+    ((p-expr (fixed ,a))
+     (cstring->number a))
+    ((neg ,a)
+     (- (p-expr->number info a)))
+    ((add ,a ,b)
+     (+ (p-expr->number info a) (p-expr->number info b)))
+    ((div ,a ,b)
+     (quotient (p-expr->number info a) (p-expr->number info b)))
+    ((mul ,a ,b)
+     (* (p-expr->number info a) (p-expr->number info b)))
+    ((sub ,a ,b)
+     (- (p-expr->number info a) (p-expr->number info b)))
+    ((sizeof-expr (i-sel (ident ,field) (p-expr (ident ,struct))))
+     (let ((type (ident->type info struct)))
+       (field-size info type field)))
+    (_  (error (format #f "p-expr->number: not supported: ~s\n" o)))))
+
 (define (struct-field info)
   (lambda (o)
     (pmatch o
        (list name '(void) 4))
       ((comp-decl (decl-spec-list (type-spec (typename ,type))) (comp-declr-list (comp-declr (ptr-declr (pointer) (ident ,name)))))
        (list name type 4))
-      ((comp-decl (decl-spec-list (type-spec (typename ,type))) (comp-declr-list (comp-declr (ptr-declr (pointer) (array-of (ident ,name) (p-expr (fixed ,count)))))))
+      ((comp-decl (decl-spec-list (type-spec (typename ,type))) (comp-declr-list (comp-declr (ptr-declr (pointer) (array-of (ident ,name) ,count)))))
        (let ((size 4)
-             (count (cstring->number count)))
+             (count (p-expr->number info count)))
          (list name type (* count size) 0)))
-      ((comp-decl (decl-spec-list (type-spec (fixed-type ,type))) (comp-declr-list (comp-declr (array-of (ident ,name) (p-expr (fixed ,count))))))
+      ((comp-decl (decl-spec-list (type-spec (fixed-type ,type))) (comp-declr-list (comp-declr (array-of (ident ,name) ,count))))
        (let ((size 4)
-             (count (cstring->number count)))
+             (count (p-expr->number info count)))
          (list name type (* count size) 0)))
-      ((comp-decl (decl-spec-list (type-spec (typename ,type))) (comp-declr-list (comp-declr (array-of (ident ,name) (p-expr (fixed ,count))))))
+      ((comp-decl (decl-spec-list (type-spec (typename ,type))) (comp-declr-list (comp-declr (array-of (ident ,name) ,count))))
        (let ((size 4)
-             (count (cstring->number count)))
+             (count (p-expr->number info count)))
          (list name type (* count size) 0)))
 
       ((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ptr-declr (pointer (pointer)) (ident ,name)))))
 
         ;; struct foo bar[2];
         ;; char arena[20000];
-        ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (array-of (ident ,name) (p-expr (fixed ,count))))))
+        ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (array-of (ident ,name) ,count))))
          (let ((type (ast->type type)))
            (if (.function info)
                (let* ((local (car (add-local locals name type -1)))
-                      (count (string->number count))
+                      (count (p-expr->number info count))
                       (size (ast-type->size info type))
                       (local (make-local-entry name type -1 (+ (local:id (cdr local)) -1 (quotient (+ (* count size) 3) 4))))                      
                       (locals (cons local locals))
                       (info (clone info #:locals locals)))
                  info)
                (let* ((globals (.globals info))
-                      (count (cstring->number count))
+                      (count (p-expr->number info count))
                       (size (ast-type->size info type))
                       (array (make-global-entry name type -1 (string->list (make-string (* count size) #\nul))))
                       (globals (append globals (list array))))