From: anton@mips.complang.tuwien.ac.at   
      
   dxf writes:   
   >On 4/05/2024 3:04 am, Anton Ertl wrote:   
   >> dxf writes:   
   [...]   
   >> It means: Gforth does not provide (D.) and does not have factors that   
   >> correspond to (D.) or (.). If it had such factors, you would have to   
   >> use them in the following way:   
   >>   
   >> ( d ) (D.) ( do something with the string, and when you are done:) #>>   
   >   
   >Standard Forth makes no such instruction.   
      
   Of course not, because standard Forth has no word (D.).   
      
   >>> ...   
   >>> \ Add commas to integer/float numeric string. Uses HOLD buffer   
   >>> : +COMMA ( a1 u1 -- a2 u2 )   
   >>> <# [char] . split 2swap shold   
   >>> 0 begin over while >r \char   
   >>> r> 2dup 3 = swap digit? and   
   >>> if [char] , hold drop 0 then   
   >>> swap hold 1+   
   >>> repeat drop #> ;   
   >>   
   >> : u._ ( u -- )   
   >> 0 <# begin   
   >> 3 0 do   
   >> # 2dup 0. d= if   
   >> #> type unloop exit then   
   >> loop   
   >> '_' hold   
   >> again ;   
   >>   
   >> The latter looks simpler to me.   
   >   
   >Will you write another separator function for floats?   
   >+COMMA handles both and is economic:   
   >   
   >355000000 113 / (.) >pad +comma cr type   
   >3,141,592 ok   
   >   
   >Pi 1e6 f* -1 (f.) >pad +comma cr type   
   >3,141,592.6535897932 ok   
   >   
   >1e 0e f/ -1 (f.) >pad +comma cr type   
   >+INF ok   
   >   
   >> ...   
   >> Let's see how +COMMA fares   
   >>   
   >> : +COMMA ( a1 u1 -- a2 u2 ) compiled   
   >> <# [char] . split 2swap shold   
   >> *the terminal*:12:16: error: Undefined word   
   >> <# [char] . >>>split<<< 2swap shold   
   >>   
   >> So it needs additional complexity. Anyway, assuming that is fixed,   
   >   
   >Requirements were: "a few string operators one likely already has"   
   >   
   >: SHOLD HOLDS ;   
   >   
   >: SPLIT ( a u c -- a2 u2 a3 u3 ) \ split at char   
   > >r 2dup r> scan 2swap 2 pick - ;   
   >   
   >: \CHAR ( a u -- a2 u2 c ) \ extract char from end   
   > 1- 2dup + c@ ;   
   >   
   >: DIGIT? ( char -- flag ) \ true if char is decimal digit   
   > [char] 0 - #10 u< ;   
   >   
   >Nothing there that forthers wouldn't have seen or used before.   
      
   So your complete setup is   
      
   : SHOLD HOLDS ;   
      
   : SPLIT ( a u c -- a2 u2 a3 u3 ) \ split at char   
    >r 2dup r> scan 2swap 2 pick - ;   
      
   : \CHAR ( a u -- a2 u2 c ) \ extract char from end   
    1- 2dup + c@ ;   
      
   : DIGIT? ( char -- flag ) \ true if char is decimal digit   
    [char] 0 - #10 u< ;   
      
   \ Add commas to integer/float numeric string. Uses HOLD buffer   
   : +COMMA ( a1 u1 -- a2 u2 )   
    <# [char] . split 2swap shold   
    0 begin over while >r \char   
    r> 2dup 3 = swap digit? and   
    if [char] , hold drop 0 then   
    swap hold 1+   
    repeat drop #> ;   
      
   And it works fine. Of course, because it uses <#, it does not work   
   with the nesting feature:   
      
   #12345. <<# #s #67890. <<# #s #> cr type #>> #> cr type #>>   
      
   prints   
      
   67890   
   12345   
      
   but   
      
   #12345. <<# #s #67890. <<# #s #> +comma cr type #>> #> cr type #>>   
      
   prints   
      
   67,890   
   *the terminal*:30:49: error: Result out of range   
   #12345. <<# #s #67890. <<# #s #> +comma cr type >>>#>><<< #> cr type #>>   
   Backtrace:   
   kernel/nio.fs:63:44: 0 $7FE0F9CB8690 throw   
      
   But that could be fixed by using <<# in +COMMA.   
      
   - anton   
   --   
   M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html   
   comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html   
    New standard: https://forth-standard.org/   
    EuroForth 2023: https://euro.theforth.net/2023   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|