Guest User

Self-checking numeric entry

a guest
Mar 3rd, 2023
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.84 KB | Source Code | 0 0
  1. \ Self-checking numeric entry. Input consists of either decimal
  2. \ byte values (hex if preceded by '$') separated by spaces, or
  3. \ the equivalent ASCII characters (including control-chars).
  4. \ Input is terminated by <RETURN> key.
  5. \
  6. \ Note:
  7. \ - editing is limited to numeric mode
  8. \ - first key determines whether mode is numeric or ASCII
  9. \ - the two modes cannot be mixed
  10. \
  11. \ Main words
  12. \ .STR GET# GET$
  13.  
  14. [undefined] DXFORTH [if]
  15. : END postpone exit postpone then ; immediate
  16. : NOT 0= ;
  17. : BETWEEN ( n1|u1 n2|u2 n3|u3 -- f ) 1+ swap within 0= ;
  18. : UPCASE ( c -- c' )
  19. dup [char] a [char] z between if $20 xor - then ;
  20. : >DIGIT ( c base -- u true | c false ) \ case-sensitive
  21. over [char] 0 - dup 10 16 within if drop else dup 16 u>
  22. if 7 - then dup rot u< if nip true end then drop false ;
  23. : BEEP ( 7 emit) ;
  24. [then]
  25.  
  26. 20 constant max$ \ input buffer size
  27.  
  28. create ibuf max$ allot \ input buffer
  29.  
  30. : .hb ( u -- ) hex s>d <# # # #> type space decimal ;
  31.  
  32. 8 constant <bs> 13 constant <cr>
  33.  
  34. : visible? ( c -- flag ) bl 127 within ;
  35.  
  36. : .chr ( c -- )
  37. case
  38. 10 of ." <LF>" endof <cr> of ." <CR>" endof
  39. 27 of ." <ESC>" endof bl of ." <SP>" endof
  40. 127 of ." <DEL>" endof
  41. dup bl < if ." Ctrl-" [char] @ + else
  42. dup visible? not if [char] $ emit .hb end then
  43. dup emit
  44. endcase space ;
  45.  
  46. : .dec ( adr len -- )
  47. ." (" begin dup while over c@ 0 .r 1 /string
  48. dup while space repeat then 2drop ." ) " ;
  49.  
  50. : .STR ( adr len -- )
  51. dup if
  52. 2dup bounds ?do i c@ .chr loop .dec
  53. end 2drop ." <none> " ;
  54.  
  55. variable #digit \ #digits entered
  56.  
  57. : /field ( -- )
  58. #digit @ begin dup while
  59. <bs> emit space <bs> emit 1-
  60. repeat #digit ! ;
  61.  
  62. : +digit ( u c -- u' err )
  63. base @ >digit if swap base @ * + dup 255 u> end
  64. drop true ;
  65.  
  66. : build# ( c -- n c2 ) \ cr or bl exits
  67. decimal 0 #digit ! 0 swap begin
  68. case [char] $ of ." $" hex key endof dup endcase
  69. upcase dup bl <> over <cr> <> and while
  70. dup visible? if dup emit 1 #digit +! then
  71. +digit if beep /field drop 0 then key
  72. repeat decimal ;
  73.  
  74. : GET# ( -- n ) key build# drop ;
  75.  
  76. variable len 0 value maxchr
  77.  
  78. : room? ( -- f ) len @ maxchr < ;
  79.  
  80. : +chr ( c -- ) ibuf len @ + c! 1 len +! ;
  81.  
  82. : do-num ( c -- )
  83. begin room? while
  84. build# swap #digit @ if +chr else drop then
  85. <cr> = if end space key
  86. repeat drop ;
  87.  
  88. : do-asc ( c -- )
  89. begin dup <cr> - room? and while
  90. dup .chr +chr key
  91. repeat drop ;
  92.  
  93. : digit? ( c -- f )
  94. dup [char] $ = swap [char] 0 [char] 9 between or ;
  95.  
  96. \ Input a string either as ASCII characters or decimal/hex
  97. \ bytes separated by spaces. Control characters allowed.
  98. : GET$ ( maxlen -- adr len )
  99. to maxchr len off
  100. key dup digit? if do-num else do-asc then
  101. ibuf len @ ;
  102.  
Advertisement
Add Comment
Please, Sign In to add comment