\ FINPUT.F version 0.1 2009-05-07
\ A minimum yet compliant Forth-94 implementation of
\ >FLOAT. Works with separate or common stack float
\ models.
\ The code is intended as a model only. No particular
\ effort has been made to optimize for speed or
\ accuracy.
\ This code is PUBLIC DOMAIN. Use at your own risk.
\ History:
\ 0.1 Replaced .1E F* with 10E F/ for better accuracy.
\ Added conditional to allow leading decimal point
\ on forth text input.
\ 0.1a Adapted to ANS float for 4tH by Hans Bezemer
\ include ansfloat.4th
\ Loading FINPUT v0.1 2009-05-07
[UNDEFINED] >float [IF]
[UNDEFINED] f+ [IF] [ABORT] [THEN]
[UNDEFINED] >single [IF] include lib/tonumber.4th [THEN]
VARIABLE exp \ exponent
VARIABLE dpf \ decimal point
FLOAT array tmp
: getc ( a u -- a' u' c )
CHOP OVER CHAR- C@ ;
\ get sign
: gets ( a u -- a' u' n|0 )
DUP IF
getc DUP [CHAR] - = IF EXIT THEN
[CHAR] + <> IF -1 /STRING THEN
THEN 0 ;
: getdigs ( a u -- a' u' )
BEGIN DUP WHILE
getc [CHAR] 0 - max-n and DUP 9 > IF
DROP -1 /STRING EXIT
THEN
S>F tmp F@ 10 S>F F* F+ tmp F!
dpf @ exp +!
REPEAT ;
: getmant ( a u -- a' u' flag )
TUCK getdigs DUP IF
OVER C@ [CHAR] . = IF
-1 dpf ! CHOP getdigs
THEN
THEN ROT OVER - dpf @ + ;
: getexp ( a u -- a' u' )
DUP IF
OVER C@ bl or DUP [CHAR] e =
SWAP [CHAR] d = OR IF CHOP THEN
THEN
gets >R 0 -ROT >SINGLE ROT
R> IF NEGATE THEN exp @ +
BEGIN DUP IF DUP THEN WHILE DUP 0<
IF 1+ tmp F@ 10 S>F F/
ELSE 1- tmp F@ 10 S>F F* THEN tmp F!
REPEAT ;
: >FLOAT ( c-addr u -- r true | false )
0 S>F tmp F! 0 exp ! 0 dpf !
2DUP -TRAILING IF DROP ELSE DROP DUP XOR THEN
DUP IF
gets >R true >R getmant
IF R> DROP getexp DUP >R THEN R>
IF 2DROP R> DROP FALSE EXIT THEN
ELSE 0 >R
THEN 2DROP tmp F@ R> IF FNEGATE THEN TRUE ;
: S>FLOAT >float 0= abort" Bad float" ;
[DEFINED] 4TH# [IF]
hide exp
hide dpf
hide tmp
hide getc
hide gets
hide getexp
hide getmant
hide getdigs
[THEN]
[THEN]
\ Test Forth-94 compliance for >FLOAT
false [IF]
: CHK ( addr len flag )
>R CR [CHAR] " EMIT 2DUP TYPE [CHAR] " EMIT
8 OVER - SPACES >FLOAT DUP >R IF FDROP THEN R>
." --> " DUP IF ." TRUE " ELSE ." FALSE" THEN
R> - IF ." *fail* " ELSE ." pass " THEN ;
: TEST ( -- )
fclear 10 set-precision
CR ." Checking >FLOAT Forth-94 compliance ..." CR
S" ." FALSE CHK
S" E" FALSE CHK
S" .E" FALSE CHK
S" .E-" FALSE CHK
S" +" FALSE CHK
S" -" FALSE CHK
S" 9" FALSE CHK
S" 9 " FALSE CHK
0 0 TRUE CHK
S" " TRUE CHK
S" 1+1" TRUE CHK
S" 1-1" TRUE CHK
S" 9" TRUE CHK
S" 9." TRUE CHK
S" .9" TRUE CHK
S" 9E" TRUE CHK
S" 9e+" TRUE CHK
S" 9d-" TRUE CHK
;
TEST
[THEN]
\ end
|