design_muesli.muesli 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. # Muesli is a Multi Use Embeddable Scripting Language Interpreter.
  2. # It is a scripting language with a TCL or shell like syntax, but somewhat
  3. # OOP and LISP like semantics.
  4. #
  5. # First it will be an embeddable scripting language implemented in Go.
  6. # In what follows I will describe the design of the language though example.
  7. #
  8. # Why is there a # before these lines? # begins a comment, until the end of the
  9. # line. MUESLI does not execute comments but skips them in stead.
  10. # Muesli is a line based language.
  11. #
  12. # Muesli consists of newline separated statements, however, a newline
  13. # after { is ignored and does not count as a separator.
  14. #
  15. # There are also bock comments:
  16. #{ This is a block comment, it nests
  17. but the {} pairs must match.
  18. }
  19. # Empty lines are ignored.
  20. # Muesly supports a whole range of typed values.
  21. # Muesli supports integer constants of type Int
  22. p 1
  23. p 2
  24. p 378
  25. p +108
  26. p -878
  27. # It also supports multi line string constants with escapes, of type String
  28. p "Hello world\"
  29. "
  30. # Muesli also supports multi line strings without escapes
  31. p `
  32. "Pop" goes the
  33. weasel's tail.
  34. `
  35. # There are built in identifiers for type Bool or nil
  36. p !true !false !nil
  37. # Museli has simple floating point constants, but no exponential notation,
  38. # of type Float
  39. p +0.5
  40. p -7.000005
  41. # Lists can be created between [ ] and may be heterogenous or homogenous.
  42. # The [ ] must be space separated.
  43. # The type is Any[] if the list is heterogenous.
  44. p [ foo "bar" ]
  45. # The type is Int[] below
  46. p [ 1 2 3 ]
  47. # A sequence of a lower case letter followed by anything that is not whitespace.
  48. # For example: this-IS*a/single+Word._
  49. # The value of a word is a string with the word itself.
  50. # If the word is at the beginning of the line it is invoked as a command.
  51. # Muesli's basic syntax is that of the command chain. Spaces separate the
  52. # arguments of the command. The first word is the command,
  53. # the rest are the arguments.
  54. print "hello" world 7 0.9
  55. # the previous command outputs: "hello world 7 0.9" to command output
  56. # A command has one or more results that can be captured with a parenthesis.
  57. print ( mul 3 ( sum 5 7 ) )
  58. # Commands can be grouped into blocks. The value of the block is that of it's last command.
  59. # block {
  60. # print "hello"
  61. # print "world"
  62. # }
  63. # Commands can also take blocks as parameters. Don't put a newline between
  64. # the open and close of the block to be sure multiple blocks get passed
  65. command {
  66. print "first block"
  67. } and also {
  68. print "second block"
  69. }
  70. # In Muesli all values are typed. Types can be defined by the builtin type
  71. # command. User defined types always are derived from Object or from another
  72. # built in type. They add the fields mentioned with their given types.
  73. type Door Object name String locked Bool keys Int[]
  74. # A value of defined type can be created using the new command
  75. set door1 (new Door "red door" true [])
  76. # Commands can be defined by the built in 'to' command.
  77. # They can have many arguments and many results.
  78. to openDoor [door Door key Item] Bool {
  79. if (contains (member door key) key) {
  80. set (member door open) true
  81. }
  82. }
  83. # Methods can be also defined with the to command
  84. to Door open [key Item] Bool {
  85. if (contains (member door key) key) {
  86. set (member door open) true
  87. }
  88. }
  89. # Unlike TCL, MUESLI values are typed, and commands
  90. # can be overloaded based on the types the types of their arguments.
  91. # Types are much like words, but they begin with an upper case letter, up to the
  92. # next whitespace.
  93. # A type that end in [] is a list, [][] a list of lists, etc, and a type
  94. # that end in ... represents a variable argument, which must be last.
  95. # Muesli tries to match the types, from narrow to wide for objects in the order
  96. # Outer class, Embedded Class, Object, Any,
  97. # and for primitive types <Bool|Int|String|Float|Word|Type>, Primitive, Any
  98. # You can override commands with more specific ones but not existing ones
  99. # that have the same specificity.
  100. # To create such an overload you should create a "cover" with the builtin
  101. # cover command. Covers are commands that dispatch to other commands based on
  102. # the types of the arguments.
  103. cover open openDoor[door Door key Item]
  104. # Variables are not part of the language but there are builtin commands
  105. # to define them. Variables are set in the current scope with
  106. set a 10
  107. # And fetched in the current scope with get
  108. print (get a 10)
  109. # To acces a variable in the scope one above current use upset/upget.
  110. upset a 10
  111. # However, there is syntactic sugar:
  112. # =foo bar gets mapped to (set foo bar)
  113. =a 10
  114. # $foo means (get foo)
  115. print $a
  116. # combinations of = followed by $ are allowed for indirect variable assignment
  117. =indirect a
  118. = ($indirect) 20
  119. =$indirect 20
  120. print $a
  121. # Or indirect getters
  122. print $$indirect
  123. # Control structures are merely builtin functions.
  124. if (less a 10) {
  125. print "Less"
  126. } else {
  127. print "More"
  128. }
  129. # A literal command evaluates to itself and writes it's value to command output.
  130. 5
  131. # Commands can be chained together using operators.
  132. # Operators in muesli are always binary. There are no unary or ternary
  133. # operators.
  134. # An operator is any token that starts with -+*/|>< and contains no
  135. # alphanumeric characters.
  136. # The semantics of operators is that the operator is called as if it was
  137. # a command, with the first operand as the first argument and the second
  138. # operand as the second argument.
  139. =foo ( sqrt 2.0 + 3.14 - 2.1 )
  140. # Means the same as
  141. # =foo ( sub ( add ( sqrt 2.0) 2.1 ) )
  142. $foo
  143. #
  144. # There are built in functions for getting, setting the fields and for
  145. # sending messages to objects in Smalltalk style.
  146. # of object valued types:
  147. take $door1 name # "red door"
  148. make $door1 name "green door"
  149. send $door1 open $key
  150. # /*-+&|@#'(^!,?.;=~
  151. # Since these three are common, there is syntax available to
  152. # abbreviate this.
  153. ?door1 's name # same as (take $door1 name)
  154. ?name , door1 (take $door1 name)
  155. @door1's name "green door" # same as (make $door1 name "green door")
  156. >door1, open $key1 # same as send $door1 open $key1, open must be a
  157. # callable method
  158. # Muesli default syntax heavily uses "line noise" characters to signify meaning
  159. # through a prefix, and has no key words in itself. However, is possible to
  160. # define keywords. These get replaced by a single token to reduce the line noise.
  161. # This allows to have an English-like or other natural language-like syntax.
  162. # For example, with the default English key word list openDoor above can also
  163. # be defined as follows:
  164. to openDoor list door Door key Item done Bool do
  165. if as contains as the door's key so a key so do
  166. make a door open true
  167. end
  168. end
  169. # That's all there is to the syntax. Apart from the built in commands,
  170. # the semantics are up to you to implement as
  171. # embedded commands or operators.
  172. # Do note that MUESLI uses dynamic scoping for ease of implementation