home *** CD-ROM | disk | FTP | other *** search
- ╔════════════════════════════════════════════════════╗
- ║ Lesson 6 Part 070 F-PC 3.5 Tutorial by Jack Brown ║
- ╚════════════════════════════════════════════════════╝
-
- ┌───────────────────────────────┐
- │ Number Formatting Operators. │
- └───────────────────────────────┘
-
- We are going to redefine Forth's number formatting primitives using our
- own output buffer. Most Forth systems prepare numbers for output by
- placing the ASCII digits in a buffer that grows grows towards low memory
- from a location called PAD which is normally defined to be a hundred or
- so bytes beyond the end of the dictionary. You can SEE or VIEW PAD to
- see exactly where it is located.
-
- Note: The code which follows requires the the colon definitions of
- Lesson 6 Part 060 to be loaded first.
-
- \ Double Number Conversion Primitives
-
- CREATE PADBUF 40 ALLOT \ Buffer to hold output string.
-
- : PAD ( -- addr ) \ Return address for output string.
- PADBUF 16 + ;
-
- \ The variable HLD points to the current position in the output buffer.
- \ HLD is initialized to PAD by <# below and is decremented by 1 just
- \ before another ASCII digit is added to the output.
-
- VARIABLE HLD \ Current output address in below PAD .
- VARIABLE S&PAD \ Used to control inspection dump.
- S&PAD ON \ Set to true to see operation of # and HOLD
-
- \ Display Stack and Pad if S&PAD is true.
- : .S&PAD ( -- )
- S&PAD @ IF CR .S PADBUF 1LINE THEN ;
-
- \ Add character n to string being formed.
- : HOLD ( n -- )
- -1 HLD +! HLD @ C! .S&PAD ;
-
- \ Start numeric conversion.
- : <# ( -- ) \ Initialize HLD for new output.
- PADBUF 32 ERASE
- PAD HLD ! .S&PAD ;
-
- \ Terminate numeric conversion.
- : #> ( dn -- addr len )
- 2DROP \ Drop double number.
- HLD @ \ Address of string.
- PAD OVER - \ Compute length of string.
- .S&PAD ;
-
- \ If n is negative insert a -ve sign in the output string.
- : SIGN ( n -- )
- 0< IF ASCII - HOLD THEN ;
-
- \ Convert a single digit using the current number BASE.
- : # ( dn -- dn' )
- BASE @ MU/MOD \ Divide dn by current base.
- ROT 9 OVER < \ Digit greater than 9 ?
- IF 7 + THEN \ Add offset of letter A for hex etc
- ASCII 0 + HOLD ; \ Add offset to digit zero and save.
-
- \ MU/MOD is a mixed mode division operator. It divides a
- \ double number dn by a single divisor n leaving a single
- \ remainder r and a double quotient dq.
-
- \ MU/MOD ( dn n -- r dq ) \ dn = dq*n + r
-
- : #S ( dn -- dn') \ Convert a number until finished.
- BEGIN # 2DUP OR 0= UNTIL ;
-
- ┌─────────────────────────────┐
- │ Interactive Demonstration │
- └─────────────────────────────┘
-
- HEX 12345. <enter> ok \ Hex mode and place number on the stack.
- <# <enter> \ Set up for numeric conversion.
- [2] 2345 1 \ Note Stack and Buffer DUMP below.
- 7575 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ok
- # <enter> \ Convert one digit see below
- [2] 1234 0 \ \/ \/
- 7575 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 35 5 ok
- # <enter> \ Convert another digit
- [2] 123 0 \ \/ \/
- 7575 00 00 00 00 00 00 00 00 00 00 00 00 00 00 34 35 45 ok
- #S <enter> \ Convert all remaining digits
- [2] 12 0 \ \/ \/
- 7575 00 00 00 00 00 00 00 00 00 00 00 00 00 33 34 35 345
- [2] 1 0 \/ \/
- 7575 00 00 00 00 00 00 00 00 00 00 00 00 32 33 34 35 2345
- [2] 0 0 \/ \/
- 7575 00 00 00 00 00 00 00 00 00 00 00 31 32 33 34 35 12345 ok
- #> <enter> \ terminate conversion
- [2] 7580 5 \ Note string address and count left on stack
- 7575 00 00 00 00 00 00 00 00 00 00 00 31 32 33 34 35 12345 ok
- TYPE <enter> 12345 ok \ and that's the way she works.
-
- You should appreciate that Forth continually uses the area above and
- below the actual PAD and we can only see what is happening here because
- we have redefined the operators. In the next screen we redefine the
- standard output operators.
-
- ┌────────────────────────────────────┐
- │ Please Move to Lesson 6 Part 080 │
- └────────────────────────────────────┘
-