actionlanguage.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. Action Language
  2. ===============
  3. The primary language of the Modelverse, is its action language.
  4. This language serves as a nicer representation of the underlying Modelverse Graph Language, which is stored as a graph.
  5. The action language gets parsed by the parser, resulting in a kind of abstract syntax graph.
  6. This abstract syntax graph highly resembles an executable graph in the Modelverse Graph Language.
  7. Users will mainly use this language to write actions and constraints, but maybe also to implement their own interfaces, or override core functionality of the Modelverse.
  8. .. warning::
  9. The current parser is unable to handle whitespaces in a general way.
  10. As such, all indentation needs to be done using tabs, and the difference needs to be exactly 1.
  11. This is different from Python, where tabs and whitespaces can be mixed, and the number can even vary.
  12. Files
  13. -----
  14. There are two kinds of files: code files, and headers.
  15. This distinction is similar to C and related languages.
  16. Code in header files will always be copied throughout all including files.
  17. As such, it is a good idea to have header files which declare the signatures of functions, but leave the actual implementation to the code files.
  18. Code files do not need to import the headers they are implementing: all variable names are automatically shared.
  19. Language description
  20. --------------------
  21. The language is inspired by Python syntax, and highly resembles it.
  22. Nonetheless, it is a lot simpler.
  23. In the remainder of this subsection, we go over the different language constructs.
  24. If
  25. ^^
  26. The IF construct is similar to that found in other languages.
  27. Its structure is as follows::
  28. if condition1:
  29. do_when_condition1
  30. elif condition2:
  31. do_when_condition2
  32. else:
  33. do_otherwise
  34. Each condition can be an expression.
  35. The code blocks can be any other kind of code.
  36. Just like Python, indentation is the only way to structure code.
  37. Unlike Python, only tabs are allowed (thus no space), and the number of tabs must be exactly one higher for a deeper block.
  38. The presence of an "elif" and "else" is optional.
  39. While
  40. ^^^^^
  41. The WHILE construct is similar to that found in other languages.
  42. Contrary to Python, there is no support for the "else" construct.
  43. Its structure is as follows::
  44. while condition:
  45. action
  46. Conditions and actions are similar to the If construct.
  47. Break
  48. ^^^^^
  49. Whereas this is supported in the Modelverse, the parser currently does not consider this keyword.
  50. Continue
  51. ^^^^^^^^
  52. Whereas this is supported in the Modelverse, the parser currently does not consider this keyword.
  53. Return
  54. ^^^^^^
  55. The RETURN construct is again similar to how it is expected.
  56. To prevent ambiguity in the grammar, an exclamation mark should follow after the expression to return.
  57. Its structure is as follows::
  58. return expression!
  59. The expression can be any expression, similar to the condition in an If and While.
  60. Function call
  61. ^^^^^^^^^^^^^
  62. Function calls happen like usual, by appending an opening and closing parenthesis at the end.
  63. Its structure is as follows::
  64. my_function(argument_a, argument_b)
  65. Arguments can again be any kind of expression.
  66. Named parameters are not supported in the grammar, though the Modelverse can internally handle them.
  67. Function definition
  68. ^^^^^^^^^^^^^^^^^^^
  69. Defining a function makes the function available as a variable in the remainder of the context.
  70. Forward declaration is unnecessary: all function names are retrieved before going over the body of the functions.
  71. This makes mutual recursion easy.
  72. A function needs to define its return type, as well as the type of all its parameters.
  73. In case the type is unknown, or can be anything, *Element* can be used as a kind of "void pointer".
  74. Its structure is as follows::
  75. Element function function_name(parameter_a : Integer):
  76. body_of_the_function
  77. First comes the returntype, followed by the keyword "function".
  78. Again, indentation needs to happen using tabs.
  79. Assignment
  80. ^^^^^^^^^^
  81. Assignment is like usual.
  82. Its structure is::
  83. a = expression
  84. This assumes that a is already defined.
  85. Declaration
  86. ^^^^^^^^^^^
  87. All variables used in the Modelverse need to be defined statically.
  88. Defining a variable reserves a part of the Modelverse State to hold the value for this value.
  89. As such, variables cannot be used if they are not defined.
  90. Additionally, a declared variable will have a type defined with it.
  91. Again, if the type can vary or is unknown, this can be *Element*.
  92. .. warning::
  93. Contrary to other languages, declaring a variable does not equal defining the variable.
  94. Therefore, after a variable is declared, it can be used, but its contents will be non-existing.
  95. It is wise to always assign a value to a declared value right after declaration!
  96. Its structure is as follows::
  97. String abc
  98. There are two kinds of declaration: local declaration, and global declaration.
  99. Local declarations happen in the current block of the code, and their references get removed when exiting the block.
  100. Global declarations have identically the same syntax, but are specified at the top level (*i.e.*, they have no tabs in front of them).
  101. Global declarations do not assign a value and are thus external references, to be defined in the future or by some other module.
  102. Sharing between modules is possible this way, as all global names are linked together when linking the application together.
  103. A global declaration that is never defined is flagged as invalid by the compiler and will prevent compilation.
  104. Definition
  105. ^^^^^^^^^^
  106. Defining a variable is similar to a global declaration, but now there is an immediate assignment.
  107. Immediate assignment is only possible at the top level.
  108. Note that the assignment must be of a constant which requires no execution of functions or such.
  109. Also, it is impossible to assign the value of another variable.
  110. Its structure is as follows::
  111. String abc = "abc"
  112. It is possible that a definition does not yet know the value to assign, or is an empty element.
  113. To notify the other files that this is the defining element, use the import syntax to assign *?* to it::
  114. Element abc = ?
  115. This results in the Modelverse creating an empty node as placeholder for a value.
  116. The value will now be defined and accessible.
  117. Imports
  118. ^^^^^^^
  119. Direct imports in the Modelverse are possible, but are not recommended for ordinary users.
  120. This syntax allows a variable to be bound to an absolute location in the Modelverse, which is resolved at compile time.
  121. The primary use case for this is the creation of bootstrap files, but it is also possible for other purposes.
  122. Use with care!
  123. Its structure is as follows::
  124. String abc = ?path/in/modelverse
  125. A special case is when the path is empty, which indicates that a new (anonymous) node should be created for it::
  126. Element abc = ?
  127. Include
  128. ^^^^^^^
  129. Other files can easily be included using the include syntax.
  130. This is a raw include: the contents of the file are just copied inside the file at that exact spot.
  131. Generally, you should only include *.alh* files, unless you know what you are doing.
  132. Constants
  133. ^^^^^^^^^
  134. The Modelverse supports a set of constants that can be used.
  135. All constants can be assigned in a definition of globals.
  136. ============= ========================================================================== =======
  137. Constant type Values Example
  138. ============= ========================================================================== =======
  139. Integer Any possible integer, either positive (no prefix) or negative (- prefix) 1
  140. Float Any possible floating point value; scientific notation is not supported 1.0
  141. Boolean Either True or False True
  142. String Any possible string, enclosed with either double or single quotes "abc"
  143. Action An action construct from the Modelverse, prefixed with an exclamation mark !If
  144. ============= ========================================================================== =======
  145. Operators
  146. ^^^^^^^^^
  147. While operators are seemingly supported by the compiler, these are actually expanded to function calls to relevant functions.
  148. For example, *1 + 2*, is expanded to *integer_addition(1, 2)*
  149. User I/O
  150. ^^^^^^^^
  151. User input and output is done through the keyworded operations *input()* and *output(msg)*.
  152. *input()* returns the first message in the input queue of the current user.
  153. *output(msg)* places the value of the expression in the output queue of the current user.
  154. All I/O is done using queues: the value is only read and written to a specific place in the Modelverse.
  155. To actually read or write it at the client side, these special places should be accessed through dedicated Modelverse operations.
  156. Examples
  157. --------
  158. We now show some simple code fragments written in valid Action Language code.
  159. As this code is directly executable in the Modelverse, the main function is always called "main" and all includes are also present.
  160. We do not currently handle how to execute this code: this is explained further on.
  161. Fibonacci
  162. ^^^^^^^^^
  163. The Fibonacci code is fairly simple.
  164. First, the primitives are imported to make sure that we know about all operations on primitives.
  165. Then, a function *fib* is defined, which will recursively compute the specified Fibonacci number.
  166. This is wrapped by a *main* function, which takes input from the user and outputs the result of the *fib* function.
  167. This code looks as follows::
  168. include "primitives.alh"
  169. Integer function fib(param : Integer):
  170. if (param <= 2):
  171. return 1!
  172. else:
  173. return fib(param - 1) + fib(param - 2)!
  174. Void function main():
  175. while(True):
  176. output(fib(input()))
  177. Factorial
  178. ^^^^^^^^^
  179. Similarly, the code for computing a factorial is given below::
  180. include "primitives.alh"
  181. Integer function factorial(n : Integer):
  182. if(n <= 1):
  183. return 1!
  184. else:
  185. return n * factorial(n - 1)!
  186. Void function main():
  187. while(True):
  188. output(factorial(input()))
  189. Binary to decimal converter
  190. ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  191. A simple binary to decimal converter is given below::
  192. include "primitives.alh"
  193. Integer function b2d(param : String):
  194. Integer value
  195. value = 0
  196. Integer length
  197. length = string_len(param)
  198. Integer counter
  199. counter = integer_subtraction(length, 1)
  200. Integer accumul
  201. accumul = 1
  202. while (counter >= 0):
  203. if (string_get(param, counter) == "1"):
  204. value = integer_addition(value, accumul)
  205. accumul = integer_multiplication(accumul, 2)
  206. counter = integer_subtraction(counter, 1)
  207. return value!
  208. Void function main():
  209. while(True):
  210. output(b2d(input()))