mescc: Tinycc support: Minimal float support.

* lib/libc+tcc.c (ldexp, strtod, strtof, strtold): New stub.
* include/math.h (ldexp): Declare.
* include/stdlib.h (strtod, strtof, strtold): Declare.
* module/mes/scm.mes (string->number): Minimal float support.
  (inexact->exact): New function.
* tests/math.test ("string->number"): Test it.
* module/language/c99/compiler.mes (ast->type): Handle float type.
  (type->info): Likewise.
  (cstring->int): Rename from cstring->number.  Update callers.
  (cstring->float): New function.
  (expr->accu): Use it.
This commit is contained in:
Jan Nieuwenhuizen 2018-05-18 15:28:05 +02:00
parent 7dfc88e22c
commit cfda148e1e
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
6 changed files with 95 additions and 35 deletions

View file

@ -23,7 +23,9 @@
#if __GNUC__ && POSIX #if __GNUC__ && POSIX
#undef __MES_MATH_H #undef __MES_MATH_H
#include_next <math.h> #include_next <math.h>
#endif // (__GNUC__ && POSIX) #else // !(__GNUC__ && POSIX)
double ldexp (double x, int exp);
#endif // !(__GNUC__ && POSIX)
#endif // __MES_MATH_H #endif // __MES_MATH_H

View file

@ -43,6 +43,9 @@ int setenv (char const* s, char const* v, int overwrite_p);
void *malloc (size_t); void *malloc (size_t);
void qsort (void *base, size_t nmemb, size_t size, int (*compar)(void const *, void const *)); void qsort (void *base, size_t nmemb, size_t size, int (*compar)(void const *, void const *));
void *realloc (void *p, size_t size); void *realloc (void *p, size_t size);
double strtod (char const *nptr, char **endptr);
float strtof (char const *nptr, char **endptr);
long double strtold (char const *nptr, char **endptr);
long strtol (char const *nptr, char **endptr, int base); long strtol (char const *nptr, char **endptr, int base);
long long strtoll (char const *nptr, char **endptr, int base); long long strtoll (char const *nptr, char **endptr, int base);
unsigned long strtoul (char const *nptr, char **endptr, int base); unsigned long strtoul (char const *nptr, char **endptr, int base);

View file

@ -127,6 +127,13 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
return 0; return 0;
} }
double
ldexp (double x, int exp)
{
eputs ("ldexp stub\n");
return 0;
}
struct tm * struct tm *
localtime (time_t const *timep) localtime (time_t const *timep)
{ {
@ -285,6 +292,24 @@ strstr (char const *haystack, char const *needle)
return 0; return 0;
} }
double
strtod (char const *nptr, char **endptr)
{
eputs ("strtoul stub\n");
}
float
strtof (char const *nptr, char **endptr)
{
return strtod (nptr, endptr);
}
long double
strtold (char const *nptr, char **endptr)
{
return strtod (nptr, endptr);
}
long long
strtol (char const *nptr, char **endptr, int base) strtol (char const *nptr, char **endptr, int base)
{ {

View file

@ -189,6 +189,7 @@
((char ,value) (get-type "char" info)) ((char ,value) (get-type "char" info))
((enum-ref . _) (get-type "int" info)) ((enum-ref . _) (get-type "int" info))
((fixed ,value) (get-type "int" info)) ((fixed ,value) (get-type "int" info))
((float ,float) (get-type "float" info))
((void) (get-type "void" info)) ((void) (get-type "void" info))
((ident ,name) (ident->type info name)) ((ident ,name) (ident->type info name))
@ -949,11 +950,15 @@
(append-text info (list (i386:label->accu `(#:string ,string)))))) (append-text info (list (i386:label->accu `(#:string ,string))))))
((p-expr (fixed ,value)) ((p-expr (fixed ,value))
(let ((value (cstring->number value))) (let ((value (cstring->int value)))
(append-text info (wrap-as (i386:value->accu value)))))
((p-expr (float ,value))
(let ((value (cstring->float value)))
(append-text info (wrap-as (i386:value->accu value))))) (append-text info (wrap-as (i386:value->accu value)))))
((neg (p-expr (fixed ,value))) ((neg (p-expr (fixed ,value)))
(let ((value (- (cstring->number value)))) (let ((value (- (cstring->int value))))
(append-text info (wrap-as (i386:value->accu value))))) (append-text info (wrap-as (i386:value->accu value)))))
((p-expr (char ,char)) ((p-expr (char ,char))
@ -975,7 +980,7 @@
((ref-to (i-sel (ident ,field) (cast (type-name (decl-spec-list ,struct) (abs-declr (pointer))) (p-expr (fixed ,base))))) ((ref-to (i-sel (ident ,field) (cast (type-name (decl-spec-list ,struct) (abs-declr (pointer))) (p-expr (fixed ,base)))))
(let* ((type (ast->basic-type struct info)) (let* ((type (ast->basic-type struct info))
(offset (field-offset info type field)) (offset (field-offset info type field))
(base (cstring->number base))) (base (cstring->int base)))
(append-text info (wrap-as (i386:value->accu (+ base offset)))))) (append-text info (wrap-as (i386:value->accu (+ base offset))))))
;; &foo ;; &foo
@ -1124,7 +1129,7 @@
((and struct? (= rank 2)) 4) ((and struct? (= rank 2)) 4)
(else 1))) (else 1)))
(info (expr->accu a info)) (info (expr->accu a info))
(value (cstring->number value)) (value (cstring->int value))
(value (* size value))) (value (* size value)))
(append-text info (wrap-as (i386:accu+value value))))) (append-text info (wrap-as (i386:accu+value value)))))
@ -1155,7 +1160,7 @@
((and struct? (= rank 2)) 4) ((and struct? (= rank 2)) 4)
(else 1))) (else 1)))
(info (expr->accu a info)) (info (expr->accu a info))
(value (cstring->number value)) (value (cstring->int value))
(value (* size value))) (value (* size value)))
(append-text info (wrap-as (i386:accu+value (- value)))))) (append-text info (wrap-as (i386:accu+value (- value))))))
@ -1439,20 +1444,25 @@
(_ ((jump i386:jump-z (wrap-as (i386:accu-zero?))) o))))) (_ ((jump i386:jump-z (wrap-as (i386:accu-zero?))) o)))))
(define (cstring->number s) (define (cstring->int o)
(let ((s (cond ((string-suffix? "ULL" s) (string-drop-right s 3)) (let ((o (cond ((string-suffix? "ULL" o) (string-drop-right o 3))
((string-suffix? "UL" s) (string-drop-right s 2)) ((string-suffix? "UL" o) (string-drop-right o 2))
((string-suffix? "LL" s) (string-drop-right s 2)) ((string-suffix? "LL" o) (string-drop-right o 2))
((string-suffix? "L" s) (string-drop-right s 1)) ((string-suffix? "L" o) (string-drop-right o 1))
(else s)))) (else o))))
(cond ((string-prefix? "0x" s) (string->number (string-drop s 2) 16)) (or (cond ((string-prefix? "0x" o) (string->number (string-drop o 2) 16))
((string-prefix? "0b" s) (string->number (string-drop s 2) 2)) ((string-prefix? "0b" o) (string->number (string-drop o 2) 2))
((string-prefix? "0" s) (string->number s 8)) ((string-prefix? "0" o) (string->number o 8))
(else (string->number s))))) (else (string->number o)))
(error "cstring->int: not supported:" o))))
(define (cstring->float o)
(or (string->number o)
(error "cstring->float: not supported:" o)))
(define (try-expr->number info o) (define (try-expr->number info o)
(pmatch o (pmatch o
((fixed ,a) (cstring->number a)) ((fixed ,a) (cstring->int a))
((p-expr ,expr) (expr->number info expr)) ((p-expr ,expr) (expr->number info expr))
((neg ,a) ((neg ,a)
(- (expr->number info a))) (- (expr->number info a)))
@ -1485,7 +1495,7 @@
((cast ,type ,expr) (expr->number info expr)) ((cast ,type ,expr) (expr->number info expr))
((cond-expr ,test ,then ,else) ((cond-expr ,test ,then ,else)
(if (p-expr->bool info test) (expr->number info then) (expr->number info else))) (if (p-expr->bool info test) (expr->number info then) (expr->number info else)))
(,string (guard (string? string)) (cstring->number string)) (,string (guard (string? string)) (cstring->int string))
((ident ,name) (assoc-ref (.constants info) name)) ((ident ,name) (assoc-ref (.constants info) name))
(_ #f))) (_ #f)))
@ -1528,7 +1538,7 @@
(let ((field (car o))) (let ((field (car o)))
(pmatch field (pmatch field
((comp-declr (bit-field (ident ,name) (p-expr (fixed ,bits)))) ((comp-declr (bit-field (ident ,name) (p-expr (fixed ,bits))))
(let ((bits (cstring->number bits))) (let ((bits (cstring->int bits)))
(cons (cons name (make-bit-field type bit bits)) (cons (cons name (make-bit-field type bit bits))
(loop (cdr o) (+ bit bits))))) (loop (cdr o) (+ bit bits)))))
(_ (error "struct-field: not supported:" field o)))))))))) (_ (error "struct-field: not supported:" field o))))))))))
@ -1814,8 +1824,8 @@
(0 0) (0 0)
((p-expr (char ,value)) (char->integer (car (string->list value)))) ((p-expr (char ,value)) (char->integer (car (string->list value))))
((p-expr (ident ,constant)) (assoc-ref (.constants info) constant)) ((p-expr (ident ,constant)) (assoc-ref (.constants info) constant))
((p-expr (fixed ,value)) (cstring->number value)) ((p-expr (fixed ,value)) (cstring->int value))
((neg (p-expr (fixed ,value))) (- (cstring->number value))) ((neg (p-expr (fixed ,value))) (- (cstring->int value)))
(_ (error "case test: not supported: " test))))) (_ (error "case test: not supported: " test)))))
(append (wrap-as (i386:accu-cmp-value value)) (append (wrap-as (i386:accu-cmp-value value))
(jump-z body-label)))) (jump-z body-label))))
@ -2106,7 +2116,7 @@
(list->string (map (lambda (i) (pmatch i (list->string (map (lambda (i) (pmatch i
((initzer (p-expr (char ,c))) ((compose car string->list) c)) ((initzer (p-expr (char ,c))) ((compose car string->list) c))
((initzer (p-expr (fixed ,fixed))) ((initzer (p-expr (fixed ,fixed)))
(let ((value (cstring->number fixed))) (let ((value (cstring->int fixed)))
(if (and (>= value 0) (<= value 255)) (if (and (>= value 0) (<= value 255))
(integer->char value) (integer->char value)
(error "array-init->string: not supported:" i o)))) (error "array-init->string: not supported:" i o))))
@ -2208,7 +2218,7 @@
((ref-to (i-sel (ident ,field) (cast (type-name (decl-spec-list ,struct) (abs-declr (pointer))) (p-expr (fixed ,base))))) ((ref-to (i-sel (ident ,field) (cast (type-name (decl-spec-list ,struct) (abs-declr (pointer))) (p-expr (fixed ,base)))))
(let* ((type (ast->type struct info)) (let* ((type (ast->type struct info))
(offset (field-offset info type field)) (offset (field-offset info type field))
(base (cstring->number base))) (base (cstring->int base)))
(int->bv32 (+ base offset)))) (int->bv32 (+ base offset))))
((,char . _) (guard (char? char)) o) ((,char . _) (guard (char? char)) o)
((,number . _) (guard (number? number)) ((,number . _) (guard (number? number))
@ -2286,6 +2296,7 @@
((typename ,name) info) ((typename ,name) info)
((union-ref . _) info) ((union-ref . _) info)
((fixed-type . _) info) ((fixed-type . _) info)
((float-type . _) info)
((void) info) ((void) info)
(_ ;;(error "type->info: not supported:" o) (_ ;;(error "type->info: not supported:" o)

View file

@ -229,15 +229,31 @@
(equal? (substring string (- length suffix-length)) suffix)))) (equal? (substring string (- length suffix-length)) suffix))))
(define (string->number s . rest) (define (string->number s . rest)
(let* ((radix (if (null? rest) 10 (car rest))) (let ((lst (string->list s)))
(lst (string->list s)) (and (pair? lst)
(sign (if (char=? (car lst) #\-) -1 1)) (let* ((radix (if (null? rest) 10 (car rest)))
(lst (if (= sign -1) (cdr lst) lst))) (sign (if (and (pair? lst) (char=? (car lst) #\-)) -1 1))
(let loop ((lst lst) (n 0)) (lst (if (= sign -1) (cdr lst) lst)))
(if (null? lst) (* sign n) (let loop ((lst lst) (n 0))
(let ((i (char->integer (car lst)))) (if (null? lst) (* sign n)
(loop (cdr lst) (+ (* n radix) (- i (if (<= i (char->integer #\9)) (char->integer #\0) (let ((i (char->integer (car lst))))
(- (char->integer #\a) 10)))))))))) (cond ((and (>= i (char->integer #\0))
(<= i (char->integer #\9)))
(let ((d (char->integer #\0)))
(loop (cdr lst) (+ (* n radix) (- i d)))))
((and (= radix 16)
(>= i (char->integer #\a))
(<= i (char->integer #\f)))
(let ((d (char->integer #\a)))
(loop (cdr lst) (+ (* n radix) (- i (- d 10))))))
((= i (char->integer #\.)) ; minimal FLOAT support
(let ((fraction (cdr lst)))
(if (null? fraction) n
(let ((fraction ((compose string->number list->string) fraction)))
(and fraction n))))) ; FLOAT as integer
(else #f)))))))))
(define inexact->exact identity)
(define (number->string n . rest) (define (number->string n . rest)
(let* ((radix (if (null? rest) 10 (car rest))) (let* ((radix (if (null? rest) 10 (car rest)))

View file

@ -8,7 +8,7 @@ exit $?
;;; -*-scheme-*- ;;; -*-scheme-*-
;;; Mes --- Maxwell Equations of Software ;;; Mes --- Maxwell Equations of Software
;;; Copyright © 2016 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> ;;; Copyright © 2016,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;; ;;;
;;; This file is part of Mes. ;;; This file is part of Mes.
;;; ;;;
@ -25,9 +25,12 @@ exit $?
;;; You should have received a copy of the GNU General Public License ;;; You should have received a copy of the GNU General Public License
;;; along with Mes. If not, see <http://www.gnu.org/licenses/>. ;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
(mes-use-module (mes scm))
(mes-use-module (srfi srfi-0))
(mes-use-module (mes test)) (mes-use-module (mes test))
(pass-if-equal "string->number" 42 (string->number "42"))
(pass-if-equal "string->number neg" -42 (string->number "-42"))
(pass-if-not "string->number hex" (string->number "aa"))
(pass-if-equal "string->number hex" 170 (string->number "aa" 16))
(pass-if-equal "string->number float" 1 (inexact->exact (string->number "1.0")))
(pass-if-equal "+" 6 (+ 1 2 3)) (pass-if-equal "+" 6 (+ 1 2 3))
(pass-if-equal "*" 27 (* 3 3 3)) (pass-if-equal "*" 27 (* 3 3 3))