home *** CD-ROM | disk | FTP | other *** search
- \ Original Date: September 12, 1988
- \ Last Modified: September 28, 1988
- \ Author: Jack W. Brown
- \ Function: Boiler plate, Bullet proof integer numeric input.
- \ Usage: <position cursor> #IN ( -- number )
-
- \ Overview:
- \ The idea is to allow only valid single signed integer input
- \ with editing by checking each key press as it arrives. All
- \ invalid key presses including function keys will be rejected.
- \ The value of the number is formed as valid digits are entered
- \ so that it is impossible to enter a number outside the range
- \ of -32767 through 32767. If the cursor is first positioned
- \ screen entry will be limited to 6 character positions from this
- \ initial cursor postion.
-
- \ Notes:
- \ 1) All word defintions have been author and date coded to
- \ reflect the date and author of the most recent change.
- \ 2) Revision history added to beginning of file.
- \ This is absolute requirement when a team of programmers
- \ is working on a very large application. Any change made
- \ is reflected in the revision history and with the actual
- \ word definition.
- \ 3) Only non-FORTH83 word used in #OUT
-
- \ Possible Improvements:
- \ 1) Modify code to allow single signed number input in any BASE.
- \ 2) Modify code or make a new version called D#IN for bullet proof
- \ input of signed double integers.
-
- \ Revision History:
- \ JWB 12 09 88 Converted from F83 Blocks to *.SEQ file for F-PC
- \ JWB 28 09 88 Commented out test for invalid interval in (IN)
- \ JWB 28 09 88 Inserted comment about non standard word #OUT.
- \ JWB 28 09 88 Added CONSTANTs to make code more readable and
- \ to avoid non standard ASCII and CONTROL.
- \ JWB 28 09 88 Clarified operation of RUBOUT.
- \ JWB 28 09 88 Clarified operation of +DIGIT.
- \ JWB 28 09 88 Renamed RESET? to CLEAR_SIGN? for readability.
- \ JWB 28 09 88 Changed . to _ in CORRECT.IT and PROCESS.IT
- \ JWB 28 09 88 Modified NEGATIVE? to include DUP
- \ JWB 28 09 88 Reformated #IN and removed DUP to accomodate above.
-
- \ Constants added for readablilty.
- 07 CONSTANT CONTROL_G \ Bell character
- 08 CONSTANT CONTROL_H \ Back space character.
- 48 CONSTANT ASCII_0 \ The digit " 0 "
- 57 CONSTANT ASCII_9 \ The digit " 9 "
- 45 CONSTANT ASCII_- \ The minus sign character.
- 13 CONSTANT CONTROL_M \ The carriage return character
-
- \ Interval testing words. Naming convention motivated by the
- \ mathematical intervals (a,b) [a,b] (a,b] and [a,b).
- \ Would better names be (A,B) [A,B] ... ?
- \ Application Note: In VP-Planner these four words were
- \ implemented in machine code and saved approximately 500 bytes,
- \ resulted in increased execution speed and better readability
- \ than when actual tests were coded inline in highlevel Forth.
-
- \ (IN) leaves a true flag if a < x < b
- : (IN) ( x a b -- flag ) ( JWB 28 09 88 )
- \ 2DUP < NOT ABORT" Invalid interval."
- -ROT OVER < -ROT > AND ;
-
- \ [IN] leaves a true flag if a <= x <= b , otherwise false.
- : [IN] ( x a b -- flag ) ( JWB 02 10 85 )
- 1+ SWAP 1- SWAP (IN) ;
-
- \ (IN] leaves a true flag if a < x <= b , otherwise false.
- : (IN] ( x a b -- flag ) ( JWB 02 10 85 )
- 1+ (IN) ;
-
- \ [IN) leaves a true flag if a <= x < b , otherwise false.
- : [IN) ( x a b -- flag ) ( JWB 02 10 85 )
- SWAP 1- SWAP (IN) ;
-
- \ Note #OUT is not in the FORTH83 standard. ( JWB 28 09 88 )
- \ #OUT is a variable that contains the number of charaters output since
- \ the last carriage return. Its value must be corrected so that words
- \ EMITing characters leave its value the same as the actual horizontal
- \ cursor position. If this is not done systems like L&P F83 may produce
- \ auto word wrap when #OUT exceeds 80.
-
- \ Sound alarm bell.
- : BELL ( -- ) ( JWB 07 10 85 )
- CONTROL_G EMIT -1 #OUT +! ;
-
- \ Leave true flag if valid digit.
- : DIGIT? ( n -- flag ) ( JWB 07 10 85 )
- ASCII_0 ASCII_9 [IN] ;
-
- \ Rub out most recent digit. Note that correction to #OUT is -4
- \ because three characters have been EMITed and the cursor ends
- \ up one character position to the left!
- : RUBOUT ( -- ) ( JWB 28 09 88 )
- CONTROL_H EMIT SPACE
- CONTROL_H EMIT
- -4 #OUT +! ;
-
- \ Erase digit from screen, adjust number being formed and
- \ decrement the digit count. Note:
- \ count = number of digits that have currently been entered.
- \ n = the value of the number currently on the screen.
- : -DIGIT ( count n -- count-1 n/10 ) ( JWB 28 09 88 )
- RUBOUT \ Remove character from screen.
- SWAP 1- SWAP \ Adjust digit count.
- 10 / ; \ Adjust value of number.
-
- \ Increment digit count and add in digit. This word is complicated
- \ by the fact that we must check to make sure that the digit entered
- \ must not allow the number formed to be outside the valid single
- \ signed integer range. Note: n'= 10n+key-48
- : +DIGIT ( count n key -- count+1 n' If valid key) ( JWB 28 09 88 )
- ( -- count n If invalid key )
- SWAP 10 UM* \ Scale number by 10 and leave as double#.
- 2 PICK ASCII_0 - \ Convert key to digit value.
- 0 D+ \ Extend to double, add to leave new value.
- 32767. 2OVER DU< \ Check for out of range single number.
- IF 10 UM/MOD \ Too big, restore original value.
- NIP NIP BELL \ remove remainder, and key.
- ELSE DROP \ convert double number to single number.
- SWAP EMIT \ Echo digit key to the screen.
- SWAP 1+ SWAP \ Increment the current digit count.
- THEN ;
-
- \ Reset sign flag to indicate non negative number if digit count
- \ is zero.
- : CLEAR_SIGN? ( flag count n -- ff count n ) ( JWB 28 09 88 )
- OVER 0= IF ROT DROP FALSE -ROT THEN ;
-
- \ Correct an error input.
- : CORRECT_IT ( flag count num key -- flag count num ) ( JWB 28 09 88 )
- DROP OVER 0<> \ Is digit count non zero?
- IF -DIGIT \ Remove most recent digit.
- ELSE BELL \ Sound warning.
- THEN
- CLEAR_SIGN? ; \ Clear numbers sign if count is 0.
-
- \ Process all other keystrokes.
- : PROCESS_IT ( flag count num key -- flag count num ) ( JWB 28 09 88 )
- DUP DIGIT? \ Check for digit.
- IF +DIGIT \ Echo & convert digit, inc count
- ELSE DROP BELL \ Invalid key or overflow.
- THEN ;
-
- \ Apply sign to number.
- : APPLY-SIGN ( flg count num key -- num ) ( JWB 28 09 88 )
- DROP NIP SWAP \ Drop key, nip count, get sign flag.
- IF NEGATE THEN ; \ Apply sign to number.
-
- \ Negative number?
- : NEGATIVE? ( count num key -- count num key flag ) ( JWB 28 09 88 )
- DUP ASCII_- = 3 PICK 0= AND ;
-
- \ Set sign flag to true indicating a negative number
- \ is being input.
- : SET-FLAG ( flg cnt num key -- flg cnt num ) ( JWB 07 10 85 )
- EMIT ROT DROP TRUE -ROT \ Set sign flag true.
- SWAP 1+ SWAP ; \ Increment digit count.
-
- \ This is the boiler plate, bullet proof interger number
- \ input routine. It supposedly only allows input of positive
- \ or negative 16 bit integers. Only valid digit keys are
- \ allowed.
- \ flag = sign flag, true means negative number being entered.
- \ false means positive number.
- \ count = current count of digits entered.
- \ number= current value of number on users screen.
- \ key = key press code from users input.
- : #IN ( -- number ) ( JWB 28 09 88 )
- FALSE 0 0 ( flag count number )
- BEGIN KEY ( flag count number key ) \ Fetch key press.
- NEGATIVE? \ Negative number?
- IF SET-FLAG \ Set sign flag true.
- ELSE DUP CONTROL_M = \ Return entered?
- IF APPLY-SIGN EXIT \ Apply sign to number and exit
- THEN
- DUP CONTROL_H = \ Correct error input?
- IF CORRECT_IT \ This does it.
- ELSE PROCESS_IT \ Process all other keys.
- THEN
- THEN
- AGAIN ;
-
- \ Word to test #IN
- : TEST ( -- )
- BEGIN
- CR #IN 3 SPACES DUP .
- 0= UNTIL ;
-
-
-