PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/library/forth.rx

https://bitbucket.org/crcx/retro-language
Forth | 196 lines | 158 code | 29 blank | 9 comment | 20 complexity | bab886b85d459c81bc852ce1d12d7137 MD5 | raw file
Possible License(s): 0BSD, Apache-2.0
  1. chain: forth'
  2. ( loops ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  3. : for ( n- ) ` [ ; compile-only
  4. : next ( - ) ` ] ` times ; compile-only
  5. ( conditionals ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  6. : then ( - ) ` ] [ ` if ] [ ` ifTrue ] if ; compile-only
  7. : else ( - ) ` ] drop -1 ` [ ; compile-only
  8. : if ( n- ) 0 ` [ ; compile-only
  9. : 0< ( n-f ) 0 < ;
  10. : 0= ( n-f ) 0 = ;
  11. ( address stack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  12. : r@ ( -n ) ` pop ` dup ` push ; compile-only
  13. : >r ( n- ) ` push ; compile-only
  14. : r> ( -n ) ` pop ; compile-only
  15. ( data stack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  16. : 2dup ( xy-xyxy ) 2over ;
  17. : pick ( ...n-...m ) dup if swap [ 1- pick ] dip swap else drop dup then ;
  18. : roll ( xu xu-1 ... x0 u -- xu-1 ... x0 xu )
  19. dup 1 > if swap [ 1- roll ] dip swap else swap then ;
  20. ( console i/o ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  21. : emit ( c- ) putc ;
  22. : key ( -c ) getc ;
  23. : type ( an- ) [ @+ putc ] times drop ;
  24. : spaces ( n- ) &space times ;
  25. ( math and bitwise ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  26. : */mod ( abc-rq ) &* dip /mod ;
  27. : lshift ( ab-c ) << ;
  28. : rshift ( ab-c ) >> ;
  29. {{
  30. variable r
  31. ---reveal---
  32. : fm/mod ( ab-mq )
  33. 2over xor 0 <
  34. if dup !r /mod over [ 1- swap @r + swap ] ifTrue else /mod then ;
  35. : sm/mod ( ab-rq )
  36. /mod ;
  37. }}
  38. ( strings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  39. {{
  40. : keep ( $-a )
  41. ahead here tib withLength , [ @+ dup , ] while drop [ here swap ! ] dip ;
  42. ---reveal---
  43. : c" ( "-a ) '" accept keep .data ; immediate
  44. : s" ( "-an ) ` c" ` @+ ; immediate
  45. : count ( a-an ) @+ ;
  46. }}
  47. ( compiler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  48. : lateBinding ( "- )
  49. getToken "on" compare
  50. if [ default: : @last dup @ !last ] &: :is
  51. [ default: ; !last ] &; :is else &: :devector &; :devector then ;
  52. : [ ( - ) ` [[ ; immediate
  53. : ] ( - ) ]] ;
  54. : state ( -a ) compiler ;
  55. : ['] ( "-a ) ' .data ; compile-only
  56. : recurse ( - ) @last @d->xt , ; compile-only
  57. ( misc ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
  58. : char ( "-c ) @getToken ;
  59. : [char] ( "-c ) char .data ; compile-only
  60. ;chain
  61. doc{
  62. ======
  63. forth'
  64. ======
  65. --------
  66. Overview
  67. --------
  68. This vocabulary will make Retro closer to a traditional Forth system. When
  69. it is visible, some things will be significantly different than in a standard
  70. Retro system, but it will also be easier to port existing Forth code.
  71. Eventually this should provide a large subset of the ANS Forth standard, with
  72. the limitation that only lowercase function names are provided.
  73. -----
  74. Notes
  75. -----
  76. Strings
  77. =======
  78. Strings in ANS Forth are represented either as counted, or address and length
  79. pairs.
  80. This differs from the strings in Retro which are represented as null-terminated
  81. character arrays. So existing functions can't be directly used with strings
  82. created by the functions this vocabulary provides, and these functions can not
  83. be used freely with Retro strings.
  84. For counted strings, you get a pointer to a structure in memory that looks like:
  85. ::
  86. length,characters
  87. These can be unpacked into address/length pairs using **count**.
  88. ---------
  89. Functions
  90. ---------
  91. +-------------+----------+----------------------------------------------------+
  92. | Function | Stack | Usage |
  93. +=============+==========+====================================================+
  94. | if | f- | Start a conditional sequence |
  95. +-------------+----------+----------------------------------------------------+
  96. | else | ``-`` | Start the second half of a conditional sequence |
  97. +-------------+----------+----------------------------------------------------+
  98. | then | ``-`` | End a conditional sequence |
  99. +-------------+----------+----------------------------------------------------+
  100. | 0< | n-f | Return true flag if n is less than zero |
  101. +-------------+----------+----------------------------------------------------+
  102. | 0= | n-f | Return true flag if n is equal to zero |
  103. +-------------+----------+----------------------------------------------------+
  104. | for | n- | Start a counted loop |
  105. +-------------+----------+----------------------------------------------------+
  106. | next | ``-`` | End a counted loop |
  107. +-------------+----------+----------------------------------------------------+
  108. | r@ | -n | Return a copy of the top item on the address stack |
  109. +-------------+----------+----------------------------------------------------+
  110. | ``>r`` | n- | Push a value to the address stack |
  111. +-------------+----------+----------------------------------------------------+
  112. | ``r>`` | -n | Pop a value off the address stack |
  113. +-------------+----------+----------------------------------------------------+
  114. | 2dup | xy-xyxy | Duplicate the top two items on the stack |
  115. +-------------+----------+----------------------------------------------------+
  116. | emit | c- | Display a character |
  117. +-------------+----------+----------------------------------------------------+
  118. | key | -c | Read a keypress |
  119. +-------------+----------+----------------------------------------------------+
  120. | type | an- | Display n characters from string |
  121. +-------------+----------+----------------------------------------------------+
  122. | spaces | n- | Display a series of spaces |
  123. +-------------+----------+----------------------------------------------------+
  124. | state | -a | Same as **compiler** |
  125. +-------------+----------+----------------------------------------------------+
  126. | ``[']`` | "-a | Return the address of a function. Compile-time |
  127. | | | version of **'** |
  128. +-------------+----------+----------------------------------------------------+
  129. | recurse | ``-`` | Compile a call to the current function into the |
  130. | | | function |
  131. +-------------+----------+----------------------------------------------------+
  132. | ``*/mod`` | abc-rq | Multiply a by b, then divide the results by c. |
  133. | | | Returns the remainder and the quotient. |
  134. +-------------+----------+----------------------------------------------------+
  135. | rshift | ab-c | Shift bits right |
  136. +-------------+----------+----------------------------------------------------+
  137. | lshift | ab-c | Shift bits left |
  138. +-------------+----------+----------------------------------------------------+
  139. | fm/mod | ab-mq | Floored divide and remainder |
  140. +-------------+----------+----------------------------------------------------+
  141. | sm/mod | ab-mq | Symmetric divide and remainder |
  142. +-------------+----------+----------------------------------------------------+
  143. | ``c"`` | ``"-a`` | Parse and return a counted string |
  144. +-------------+----------+----------------------------------------------------+
  145. | ``s"`` | ``"-an`` | Parse and return a string and its length |
  146. +-------------+----------+----------------------------------------------------+
  147. | count | a-an | Convert a counted string to an addr/len pair |
  148. +-------------+----------+----------------------------------------------------+
  149. | ``[`` | ``-`` | Turn **compiler** off |
  150. +-------------+----------+----------------------------------------------------+
  151. | ``]`` | ``-`` | Turn **compiler** on |
  152. +-------------+----------+----------------------------------------------------+
  153. | char | ``"-c`` | Parse for and return an ASCII character |
  154. +-------------+----------+----------------------------------------------------+
  155. |``[char]`` | ``"-c`` | Compile-time version of **char** |
  156. +-------------+----------+----------------------------------------------------+
  157. | lateBinding | ``$-`` | "on" binds names to functions after execution of |
  158. | | | **;**, "off" binds immediately |
  159. +-------------+----------+----------------------------------------------------+
  160. | pick |...n-..m | Evil function to access arbitrary stack items |
  161. +-------------+----------+----------------------------------------------------+
  162. | roll | xu xu-1 | Remove u. Rotate u+1 items on the top of the stack |
  163. | | ... x0 u | |
  164. | | -- xu-1 | |
  165. | | ... x0 xu| |
  166. +-------------+----------+----------------------------------------------------+
  167. }doc