exotic.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. Robotic revision ideas
  2. After gauging the response to a modestly altered Robotic language, it is is now
  3. my intention to include in a later version of MZX a language which is 100%
  4. compatible with Robotic as we know it now. It will, however, have several
  5. important extensions. Simplicity is a high priority. Syntax sensibility is
  6. also important, but it is more necessary to retain familiar style than to
  7. introduce new forms which may be deemed more writable for whatever reason. There
  8. will be no major attempt to make Robotic resemble any one specific known language;
  9. rather features will be added as a result of determined necessity.
  10. It should be noted that I have every intention of changing the Robotic bytecode
  11. dramatically. This has a few implications:
  12. - Source code will no longer have a one to one relationship with bytecode. This
  13. means that bytecode cannot be disassembled into source code without losing
  14. quite a bit of information; no attempt will be made to provide such a
  15. disassembler as part of MZX itself. MZX currently stores bytecode alone in
  16. its world files and to edit the robots this bytecode is disassembled. To edit
  17. robots created with the new format (or indeed, converted from existing worlds)
  18. the source code will have to be present. Since it is not necessary to have the
  19. source code present to execute the game, there will likely exist world versions
  20. that have had the source code stripped. These versions will be playable but
  21. will not be editable. This is not necessarily an intentional form of protection,
  22. but a way to reduce the size of the games tremendously.
  23. - The bytecode will be relatively simple to interpret. Most commands will be
  24. linked as function calls by the interpreter. The bytecode itself will most
  25. represent a relatively forth-like stack based machine. It will be lower level
  26. than the current bytecode, and thus lower level than the Robotic language itself
  27. (the current bytecode is merely a tokenization of Robotic code, and ensures
  28. correct syntax so that need not be checked at runtime).
  29. - The bytecode will be done with efficiency in mind. I intend to provide as many
  30. compile time optimizations to make code faster. Mainly, references that would
  31. otherwise have to be deduced at runtime (such as the location of a counter with
  32. a given name) will be hard linked if they can be deduced at compile time. These
  33. will be considered "static" references and ones that cannot be deduced will be
  34. considered "dynamic" or "run-time" references.
  35. With the last point in mind, I would like to point out that I intend to specifically
  36. document optimization ideas at some point, but that this will not be considered
  37. part of the language specification itself. However, since some language forms will
  38. inevitably be far more conducive to efficient optimization, it will often be in the
  39. programmer's best interest to code in a certain style.
  40. I'd also like to note that I intend for the language to be very simple to parse and
  41. compile (as it is now). This may add some extra overhead to writing the code, but I
  42. believe it is highly important that code can be quickly compiled on the fly. This is
  43. especially true for games that will import robots externally at run-time. Besides,
  44. I'm hardly interested in writing a full blown LALR table traversing or
  45. recursive-descent parser for MegaZeux at this time.
  46. Now, onto actual language specifications...
  47. A Robotic program will consist of several statements. A statement will be one of the
  48. following:
  49. A single command - this "does" something; as seen in Robotic currently.
  50. A compiler directive - this describes the code in some way, limits names, etc. It
  51. may allow for macros and comments will certainly fall under this category.
  52. A multi-command command - some commands may take, as a parameter, a command block.
  53. These will be clearly delimited in some way.
  54. All commands take a fixed number of parameters. Each parameter can be one of multiple
  55. types. For now it is best to consider a constant and a variable to be two different
  56. types; there are many instances where one will not be usable as another. For Robotic
  57. as we know it now, all types are basically analogous to either integers or strings.
  58. Thus I'll skip the existing types (such as character, direction, parameter) and give
  59. general types for variables. The type of a variable is denoted by its first character.
  60. integer variable - currently known as a "counter." Has no specific first character
  61. (thus anything which doesn't fall under the other categories falls here). Integers
  62. will have a size that is at LEAST 32bits, but you shouldn't rely on a certain size.
  63. string variable - contains a series of characters. Currently MZX has a form of
  64. slicing the string by using + and # operators in the name of the string (at the end).
  65. An individual character can be returned in integer form with the . operator.
  66. Denoted with a $ at the beginning of the name.
  67. real variable - values with decimal portions. Guaranteed to have at leat double
  68. precision (64bits), may have more. Denoted with a % at the beginning of the name.
  69. Now, using the name interpolation operators of MZX, it is possible to come to other
  70. more complicated types. These can be considered aggregate types. Consider the following:
  71. int&int2& - this is an integer indexed array of ints. Putting the subscript at the end
  72. will be preferable by convention and possibly for optimization issues.
  73. int&$string& - this is a string indexed or associative array (may be considered a
  74. dictionary or set as well).
  75. int&int2&,&int3& - multi-dimensional array of ints.
  76. $str&int& - array of stringgs
  77. etc.
  78. These are just some examples. Actually, I would like to make functions appear to be
  79. arrays! This is confusing, but a function is afterall a map from type a to type b,
  80. although there may side-effects to calling one. Nonetheless, it is quite possible to
  81. represent a function in exactly the same way a counter is represented. If you don't
  82. believe me, look at the current builtin functions such as cos and vco. They are used
  83. as counters but are actually functions! This is how I would like functions to be
  84. defined:
  85. : "<character denoting return type>name(parameter list)"
  86. As you can see they're like labels. Let me give some examples.
  87. : "#printme"
  88. * "~fhello!"
  89. goto #return
  90. OR
  91. : "#printme"
  92. * "~fhello!"
  93. return
  94. Notice the new return command - this is used to return a value. The # indicates that
  95. there is actually no return value at all. The consequences of such a thing have yet
  96. to be determined, but this does cover existing subroutines nicely.
  97. : "square(value)"
  98. return (value * value)
  99. Returns the square of int value. Lack of special first char indicates a return type of
  100. int.
  101. : "$concat($str1, $str2)"
  102. return ($str1 + $str2)
  103. Returns the concatenation of two strings. Pointless since this is a primitive
  104. operation, but nicely demonstrates the use of functions.
  105. There is a problem however - how to differentiate between functions and normal labels?
  106. Well, parentheses inside the label name will indicate that it has a parameter list. If
  107. there is no special type character (returns int) then it must have an empty parem list,
  108. otherwise the compiler will think it's a label. The reason why the compiler needs to be
  109. able to discern if it's a label or not is because a function is loaded into the counter
  110. list. Note that () in label names do NOT act as expressions, so you can't interpolate
  111. dynamic values into label names. This should come as no surprise because MZX 2.80 won't
  112. allow such a thing to work as it is. They're simply not efficient, and I don't believe
  113. anyone has ever required them, even though they were indeed possible in DOS MZX.
  114. Multi command commands:
  115. As noted earlier there will be some commands that take command blocks as parameters.
  116. This will be useful for flow control constructs, such as:
  117. if value
  118. ...
  119. ...
  120. Where the following indented lines are the code block. Value is anything that can be
  121. turned into an integer value (and as it stands now, anything can be). Most of the time
  122. it will be a variable or an expression, and if it evaluates to non-zero the block is
  123. done, otherwise if it evaluates to 0 it isn't. This should be clear to anyone who has
  124. used just about any imperatively based programming language.
  125. Some other constructs are loops:
  126. loop for x
  127. ...
  128. ...
  129. And for legacy's sake,
  130. loopstart
  131. ...
  132. loop for x
  133. Note that indentation is not necessary if something else ends the block such as this.
  134. while value
  135. ...
  136. ...
  137. Does the block while the value is true.
  138. dowhile value
  139. ...
  140. ...
  141. Does the block once, then repeated times while the value is true.
  142. for initial value increment
  143. ...
  144. A for loop. It should be noted here that while initial and increment are values, what
  145. they actually evaluate to isn't important! Actually, expressions will most likely be
  146. able to have side-effects. Mainly, an assignment operator and combinations of assignment
  147. and other operators. Since = is used for comparison, the assignment operator will
  148. probably be :=. Look at this example:
  149. for ((x := 0) a ($str := "")) (x < 10) (x++)
  150. set $str ($str + x + " ")
  151. * ~f&$str&
  152. This will print out..
  153. 0 1 2 3 4 5 6 7 8 9 10
  154. This was done in a Robotic familiar form, but more concise forms will probably be
  155. possible. Note that this allows string operations in expressions. This will probably be
  156. allowed, but I'm not yet completely certain. Expressions MAY be limited to integers.
  157. foreach pattern variable
  158. ...
  159. ...
  160. This one is rather interesting. I'm not totally sure how to approach it, really, but I
  161. think that pattern will be something of the form you would give in MZX (such as
  162. a&b& where the type of b is known) and the variable will be a temporary variable that
  163. the matching variables are stored in for each iteration. For now consider variable to
  164. be a reference, although I haven't formally touched on references. That means that it
  165. isn't a copy of the matching value but IS the value, just with a different name. So if
  166. you change it, you change the value. This can only really be made clear with an example..
  167. foreach str($strindex) $s
  168. set $s ($s + " blah")
  169. This will put " blah" at the end of every string str followed by a string. So let's say
  170. you have the string stra, strb, and str0.. those would all match. Note that this is a
  171. good way of doing something with respect to every element of an array, but it can be
  172. more powerful than that. The details are still up in the air, but I'd really like to
  173. have something like this.
  174. References
  175. I should at least mention the possability of these. References are important because
  176. otherwise it's tough to pass arrays and whatnot to functions. You can actually do
  177. references already using string interpolation in variable names:
  178. set $ref "name"
  179. set ($ref) 10
  180. Will set the variable named "name" to 10. $ref thus refers to name.
  181. However I would like a way to do this that the compiler does more for you. I believe
  182. that references will only be possible when calling functions. In case it wasn't clear,
  183. be mindful of the fact that the above functions described were "pass by value."
  184. Consider the following:
  185. : 'set to 10(&value)'
  186. set value 10
  187. return
  188. This will set something passed to it to 10:
  189. set counter 1
  190. do 'set to 10&counter&'
  191. * "~f&counter&"
  192. I should point out the "do" command which merely evaluates a supplied value, which
  193. can thus call any functions. This is useful if you want to call a function merely for
  194. its side-effect and not a return type. Also, if it wasn't clear before, note the
  195. method of calling functions - the parameter is merely interpolated into the function
  196. name itself. This may be changed, though. And then notice the parameter value with the
  197. & before it. This indicates pass by reference (stolen from C++)
  198. Anyway, this will print out 10. When you call the function "set to 10", it passes the
  199. variable named counter by reference, and "value" is thus bound to what's passed to it.
  200. Changing value changes whatever's passed to it. One note - you will not be able to
  201. refer to references with the traditional && way. That is to say, they don't exist as
  202. actual counters with names. Something that may be alarming - if you were to do, within
  203. that function, the following:
  204. set "value&index&" 10
  205. (let's say index has the value 100)
  206. This would actually set the counter named counter100 to 10! Thus the reference
  207. "replaces" the name of the counter passed. This is useful in many cases, but care must
  208. be taken not to accidentally use the name unintentionally within another name.