Mirror of CollapseOS
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

251 lignes
7.9KB

  1. # Forth Primer
  2. # First steps
  3. Before you read this primer, let's try a few commands, just for
  4. fun.
  5. 42 .
  6. This will push the number 42 to the stack, then print the number
  7. at the top of the stack.
  8. 4 2 + .
  9. This pushes 4, then 2 to the stack, then adds the 2 numbers on
  10. the top of the stack, then prints the result.
  11. 42 0x8000 C! 0x8000 C@ .
  12. This writes the byte "42" at address 0x8000, and then reads
  13. back that bytes from the same address and print it.
  14. # Interpreter loop
  15. Forth's main interpeter loop is very simple:
  16. 1. Read a word from input
  17. 2. Look it up in the dictionary
  18. 3. Found? Execute.
  19. 4. Not found?
  20. 4.1. Is it a number?
  21. 4.2. Yes? Parse and push on the Parameter Stack.
  22. 4.3. No? Error.
  23. 5. Repeat
  24. # Word
  25. A word is a string of non-whitepace characters. We consider that
  26. we're finished reading a word when we encounter a whitespace
  27. after having read at least one non-whitespace character
  28. # Character encoding
  29. Collapse OS doesn't support any other encoding than 7bit ASCII.
  30. A character smaller than 0x21 is considered a whitespace,
  31. others are considered non-whitespace.
  32. Characters above 0x7f have no special meaning and can be used in
  33. words (if your system has glyphs for them).
  34. # Dictionary
  35. Forth's dictionary link words to code. On boot, this dictionary
  36. contains the system's words (look in dict.txt for a list of
  37. them), but you can define new words with the ":" word. For
  38. example:
  39. : FOO 42 . ;
  40. defines a new word "FOO" with the code "42 ." linked to it. The
  41. word ";" closes the definition. Once defined, a word can be
  42. executed like any other word.
  43. You can define a word that already exists. In that case, the new
  44. definition will overshadow the old one. However, any word def-
  45. ined *before* the overshadowing took place will still use the
  46. old word.
  47. # Cell size
  48. The cell size in Collapse OS is 16 bit, that is, each item in
  49. stacks is 16 bit, @ and ! read and write 16 bit numbers.
  50. Whenever we refer to a number, a pointer, we speak of 16 bit.
  51. To read and write bytes, use C@ and C!.
  52. # Number literals
  53. Traditional Forth often uses HEX/DEC switches to go from deci-
  54. mal to hexadecimal parsing. Collapse OS parses literals in a
  55. way that is closer to C.
  56. Straight numbers are decimals, numbers starting with "0x"
  57. are hexadecimals (example "0x12ef"), "0b" prefixes indicate
  58. binary (example "0b1010"), char literals are single characters
  59. surrounded by ' (example 'X'). Char literals can't be used for
  60. whitespaces.
  61. # Parameter Stack
  62. Unlike most programming languages, Forth execute words directly,
  63. without arguments. The Parameter Stack (PS) replaces them. There
  64. is only one, and we're constantly pushing to and popping from
  65. it. All the time.
  66. For example, the word "+" pops the 2 number on the Top Of Stack
  67. (TOS), adds them, then pushes back the result on the same stack.
  68. It thus has the "stack signature" of "a b -- n". Every word in
  69. a dictionary specifies that signature because stack balance, as
  70. you can guess, is paramount. It's easy to get confused so you
  71. need to know the stack signature of words you use very well.
  72. # Return Stack
  73. There's a second stack, the Return Stack (RS), which is used to
  74. keep track of execution, that is, to know where to go back after
  75. we've executed a word. It is also used in other contexts, but
  76. this is outside of the scope of this primer.
  77. # Conditional execution
  78. Code can be executed conditionally with IF/ELSE/THEN. IF pops
  79. PS and checks whether its nonzero. If it is, it does nothing.
  80. If it's zero, it jumps to the following ELSE or the following
  81. THEN. Similarly, when ELSE is encountered in the context of a
  82. nonzero IF, we jump to the following THEN.
  83. Because IFs involve jumping, they only work inside word defin-
  84. itions. You can't use IF directly in the interpreter loop.
  85. Example usage:
  86. : FOO IF 42 ELSE 43 THEN . ;
  87. 0 FOO --> 42
  88. 1 FOO --> 43
  89. # Loops
  90. Loops work a bit like conditionals, and there's 3 forms:
  91. BEGIN..AGAIN --> Loop forever
  92. BEGIN..UNTIL --> Loop conditionally
  93. DO..LOOP --> Loop X times
  94. UNTIL works exactly like IF, but instead of jumping forward to
  95. THEN, it jumps backward to BEGIN.
  96. DO pops the lower, then the higher bounds of the loop to be
  97. executed, then pushes them on RS. Then, each time LOOP is
  98. encountered, RS' TOS is increased. As long as the 2 numbers at
  99. RS' TOS aren't equal, we jump back to DO.
  100. The word "I" copies RS' TOS to PS, which can be used to get our
  101. "loop counter".
  102. Beware: the bounds arguments for DO are unintuitive. We begin
  103. with the upper bound. Example:
  104. 42 0 DO I . SPC LOOP
  105. Will print numbers 0 to 41, separated by a space.
  106. # Memory access and HERE
  107. We can read and write to arbitrary memory address with @ and !
  108. (C@ and C! for bytes). For example, "1234 0x8000 !" writes the
  109. word 1234 to address 0x8000. We call the @ and ! actions
  110. "fetch" and "store".
  111. There's a 3rd kind of memory-related action: "," (write). This
  112. action stores value on PS at where a special variable called
  113. "HERE" points to, and then advances HERE by 2 (there's also
  114. "C," for bytes).
  115. Note that the HERE word returns the address containing the
  116. pointer (it doesn't change). There's a shortcut word for
  117. "HERE @" named "H@", which is used much more often.
  118. HERE is initialized at the first writable address in RAM, often
  119. directly following the latest entry in the dictionary. Explain-
  120. ing the "culture of HERE" is beyond the scope of this primer,
  121. but know that it's a very important concept in Forth. For examp-
  122. le, new word definitions are written to HERE.
  123. # Variables
  124. The word "VARIABLE" links a name to an address. For example,
  125. "VARIABLE FOO" defines the word "FOO" and "reserves" 2 bytes of
  126. memory. Then, when FOO is executed, it pushes the address of the
  127. "reserved" area to PS.
  128. For example, "1234 FOO !" writes 1234 to memory address reserved
  129. for FOO.
  130. Another way to create a variable is with the word CREATE, which
  131. creates a variable entry without reserving anything for it: it's
  132. your responsibility to reserve memory for it after you call it.
  133. It can be useful for arrays. For example, look at VARIABLE's
  134. definition:
  135. : VARIABLE CREATE 2 ALLOT ;
  136. # DOES>
  137. Calling DOES> makes the newly created entry into a special
  138. "does word" which behaves like a variable, that is, it pushes
  139. the address of the "reserved" space to PS, but with additional
  140. behavior attached to it.
  141. DOES> must be called in the context of a word definition and
  142. calling it stops the definition right there. Every word follow-
  143. ing the DOES> is our new entry's behavior. For example, let's
  144. look at CONSTANT's definition:
  145. : CONSTANT CREATE , DOES> @ ;
  146. A constant is created with "42 CONSTANT FOO" and FOO, instead
  147. of putting FOO's address on PS, puts 42 on it.
  148. You can see above that after we've created our FOO entry, we
  149. write it to HERE and then assign the behavior "@" to it, which
  150. means that it will transform the address currently on PS to its
  151. value.
  152. # IMMEDIATE
  153. We approach the end of our primer. So far, we've covered the
  154. "cute and cuddly" parts of the language. However, that's not
  155. what makes Forth powerful. Forth becomes mind-bending when we
  156. throw IMMEDIATE into the mix.
  157. A word can be declared immediate thus:
  158. : FOO ; IMMEDIATE
  159. That is, when the IMMEDIATE word is executed, it makes the
  160. latest defined word immediate.
  161. An immediate word, when used in a definition, is executed
  162. immediately instead of being compiled. This seemingly simple
  163. mechanism (and it *is* simple) has very wide implications.
  164. For example, The words "(" and ")" are comment indicators. In
  165. the definition:
  166. : FOO 42 ( this is a comment ) . ;
  167. The word "(" is read like any other word. What prevents us from
  168. trying to compile "this" and generate an error because the word
  169. doesn't exist? Because "(" is immediate. Then, that word reads
  170. from input stream until a ")" is met, and then returns to word
  171. compilation.
  172. Words like "IF", "DO", ";" are all regular Forth words, but
  173. their "power" come from the fact that they're immediate.
  174. Starting Forth by Leo Brodie explain all of this in details.
  175. Read this if you can. If you can't, well, let this sink in for
  176. a while, browse the dictionary (dict.txt) and try to understand
  177. why this or that word is immediate. Good luck!