Talk About Network



Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Forth > Implementing >F...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 1 Topic 4034 of 4053
Post > Topic >>

Implementing >FLOAT

by "Ed" <nospam@[EMAIL PROTECTED] > May 3, 2008 at 08:39 PM

I needed a high-level >FLOAT implementation.  Looking around,
existing examples were found to be bulky.  Few were fully
compliant with the Forth-94 spec.

So the challenge was to make a compliant >FLOAT ... and keep
code to a minimum.  Below is one such attempt.  Numeric
conversion is kept basic.  Speed could be improved using tables
instead of calculating powers of 10 etc.

There is an equate STRICT.  When set to FALSE it will compile
a shorter, somewhat less compliant, version.

I've included a syntax checker for >FLOAT.  Those who already
have >FLOAT may wish to extract the checker and see how well
theirs performs.

The code is version 0.0 because it's only had limited testing.
Should anyone find bugs/mistakes, or see how it could be
shortened, post them.

I note Forth-94 requires floats processed by the text interpreter
to have a digit before a decimal point  i.e.  0.9E  is legal, but  .9E
isn't.  This rule seems unnecessary, adding complication and code.
It also contradicts what the FVG standard previously allowed.

--

\ FINPUT.F  version 0.0  2008-05-02
\
\ A minimum yet compliant Forth-94 implementation of
\ >FLOAT. Works with separate or common stack float
\ models.
\
\ Also provided are routines which condition the
\ text for forth input.
\
\ Assumptions:
\   2's complement arithmetic
\   1 char = 1 addr unit
\
\ This code is PUBLIC DOMAIN.  Use at your own risk.

( EMPTY ) FORTH DEFINITIONS DECIMAL

CR .( Loading FINPUT ... )

TRUE CONSTANT STRICT  \ FALSE = short version

\ ###  MODIFY THESE AS REQUIRED  ###

HEX
: UPCHAR ( c -- C )  \ make char uppercase
  DUP [CHAR] a [CHAR] z 1+ WITHIN IF 20 XOR THEN ;
DECIMAL

\ Implement this to allow 'E' or 'e' on forth input
: CAPS-SEARCH  SEARCH ;  \ case-insensitive SEARCH

\ ###  END  ###

STRICT [IF] .( strict ) [ELSE] .( short ) [THEN]
..( version ) CR

HERE

VARIABLE exp  \ exponent
VARIABLE dpf  \ decimal point

FVARIABLE tmp

10 0 D>F FCONSTANT ften  \ 10.E0

: getc ( a u -- a' u' c )
  1 /STRING  OVER 1- C@[EMAIL PROTECTED]
 ;

\ get sign
: gets ( a u -- a' u' n|0 )
  DUP IF
    getc  DUP [CHAR] - = IF EXIT THEN
              [CHAR] + <> /STRING
  THEN 0 ;

: getdigs ( a u -- a' u' )
  BEGIN  DUP  WHILE
    getc  [CHAR] 0 -  DUP 9 U> IF
      DROP  -1 /STRING  EXIT
    THEN
    0 D>F  tmp F@[EMAIL PROTECTED]
  ften F*  F+  tmp F!
    dpf @[EMAIL PROTECTED]
  exp +!
  REPEAT ;

: getmant ( a u -- a' u' flag )
  [ STRICT ] [IF] TUCK [THEN]
  getdigs  DUP IF
    OVER C@[EMAIL PROTECTED]
 [CHAR] . = IF
      -1 dpf !  1 /STRING  getdigs
    THEN
  THEN
  [ STRICT ] [IF] ROT OVER - dpf @[EMAIL PROTECTED]
 + [THEN] ;

: getexp ( a u -- a' u' )
  DUP IF
    OVER C@[EMAIL PROTECTED]
 UPCHAR  DUP [CHAR] E =
    SWAP [CHAR] D = OR  1 AND /STRING
  THEN
  gets >R  0 0 2SWAP >NUMBER 2SWAP
  R> IF DNEGATE THEN  exp @[EMAIL PROTECTED]
 M+
  D>S  BEGIN  ?DUP WHILE  DUP 0<
  IF  1+  [ 1 0 D>F ften F/ ] FLITERAL
  ELSE  1-  ften  THEN  tmp F@[EMAIL PROTECTED]
  F*  tmp F!  REPEAT
  ;

STRICT [IF]

\ ANS function
: >FLOAT ( c-addr u -- r true | false )
  [ 0 0 D>F ] FLITERAL tmp F!  0 exp !  0 dpf !
  2DUP  -TRAILING  NIP 0<> AND DUP IF
  gets >R  getmant IF
    getexp DUP WHILE
  THEN  2DROP  R> DROP  0 EXIT
  THEN  ELSE  0 >R
  THEN  2DROP  tmp F@[EMAIL PROTECTED]
  R> IF FNEGATE THEN  TRUE ;

[ELSE]

\ ANS function
: >FLOAT ( a u -- r true | false )
  [ 0 0 D>F ] FLITERAL tmp F!  0 exp !  0 dpf !
  -TRAILING
  gets >R  getmant
  getexp IF  R> 2DROP 0 EXIT  THEN
  DROP  tmp F@[EMAIL PROTECTED]
  R> IF FNEGATE THEN  TRUE ;

[THEN]

HERE SWAP - CR . .( bytes )

\ Forth float input. Floating-point numbers can be
\ entered via F# .

: fnumber ( c-addr u -- [r] flag )
  DUP 1 > IF ( at least 2 chars )
    OVER  DUP C@[EMAIL PROTECTED]
 [CHAR] . < -  ( skip sign)
    C@[EMAIL PROTECTED]
 [CHAR] . >  >R          ( 1st char can't be .)
    2DUP  S" E" CAPS-SEARCH >R  2DROP
    2R> AND  BASE @[EMAIL PROTECTED]
 10 = AND  0= WHILE
  THEN  2DROP 0  ELSE  >FLOAT  THEN
  DUP >R  STATE @[EMAIL PROTECTED]
 AND IF  POSTPONE FLITERAL  THEN R> ;

: F# ( <number> )
  BL WORD COUNT fnumber 0= ABORT" bad float" ; IMMEDIATE

\ discard heads
0 [IF]
EXCISE sgn getexp
EXCISE fnumber fnumber
[THEN]

1 [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 ( -- )
  CR ." Checking >FLOAT syntax ..."
  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
  S" "     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




 1 Posts in Topic:
Implementing >FLOAT
"Ed" <nospam  2008-05-03 20:39:10 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Wed May 14 21:36:45 CDT 2008.