design_muesli.muesli 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. # First it will be an embeddable scripting language implemented in Go.
  5. # In what follows I will describe the design of the language though example.
  6. #
  7. # Why is there a # before these lines? # begins a comment, until the end of the
  8. # line. MUESLI does not execute comments but they are collected
  9. # for documentation purposes. More on that topic later
  10. # Muesli is a line based language.
  11. #
  12. # Muesli consists of newline separated statements, however, a newline
  13. # after { or the do keyword is ignored and does not count as a separator.
  14. #{ This is a block comment, it nests
  15. but the {} pairs must match.
  16. }
  17. # Empty lines are ignored.
  18. # ...
  19. # Muesli supports integer constants with type Int
  20. p 1
  21. p 2
  22. p 378
  23. p +108
  24. p -878
  25. # It also supports multi line string constants with escapes, with type String
  26. p "Hello world\"
  27. "
  28. # and multi line strings without escapes
  29. p `
  30. "Pop" goes the
  31. weasel's tail.
  32. `
  33. # Built in identfiers for type Bool or nil
  34. p !true !false !nil
  35. # And simple floating point constants, but no exponential notation, with type Float
  36. p +0.5
  37. p -7.000005
  38. # Lists can be created between [ ] and may be heterogenous or homogenous.
  39. # The [ ] must be space separated.
  40. # The type is Any[] if heterogenous,
  41. p [ foo "bar" ]
  42. # The type is Int[] below
  43. p [ 1 2 3 ]
  44. # A sequence of a lower case letter followed by anything that is not whitespace.
  45. # For example: this-IS*a/single+Word._
  46. # The value of a word is a string with the word itself.
  47. # If the word is at the beginning of the line it is invoked as a command.
  48. # Muesli's basic syntax is that of the command. Spaces separate the arguments.
  49. # of the command. The first word is the command, the rest are the arguments.
  50. print "hello" world 7 0.9
  51. # the previous command outputs: "hello world 7 0.9" to standard output
  52. # A command has one or more results that can be captured with a parenthesis
  53. print ( mul 3 ( sum 5 7 ) )
  54. # Commands can be grouped into blocks. The value of the block is that of it's last command.
  55. # block {
  56. # print "hello"
  57. # print "world"
  58. # }
  59. # Commands can also take blocks as parameters. Don't put a newline between
  60. # the open and close of the block to be sure multiple blocks get passed
  61. command {
  62. print "first block"
  63. } and also {
  64. print "second block"
  65. }
  66. # In Muesli all values are typed. Types can be defined by the builtin type command.
  67. type Door ( object locked Bool keys Item[] )
  68. # Commands can be defined by the built in 'to' command.
  69. # They can have many arguments and many results.
  70. to open[door Door key Item] Bool {
  71. if (contains (member door key) key) {
  72. set (member door open) true
  73. }
  74. }
  75. # Unlike TCL, MUESLI values are typed, and commands
  76. # can be overloaded based on the types the types of their arguments.
  77. # Types are much like words, but they begin with an upper case letter, up to the
  78. # next whitespace.
  79. # A type that end in [] is a list, [][] a list of lists, etc, and a type
  80. # that end in ... represents a variable argument, which must be last.
  81. # Muesli tries to match the types, from narrow to wide for objects in the order
  82. # Outer class, Embedded Class, Object, Any,
  83. # and for primitive types <Bool|Int|String|Float|Word|Type>, Primitive, Any
  84. # You can override commands with more specific ones but not existing ones
  85. # that have the same specificity.
  86. # To create such an overload you should create a "cover" with the builtin
  87. # cover command. Covers are commands that dispatch to other commands based on
  88. # the types of the arguments.
  89. cover open open[door Door key Item]
  90. # Variables are not part of the language but there arebuiltin commands
  91. # to define them. Variables are set in the current scope with
  92. set a 10
  93. # And fetched in the current scope with get
  94. print (get a 10)
  95. # To acces a variable in the scope one above current use upset/upget.
  96. upset a 10
  97. # However, there is syntactic sugar:
  98. # =foo bar gets mapped to (set foo bar)
  99. =a 10
  100. # $foo means (get foo)
  101. print $a
  102. # combinations of = followed by $ are allowed for indirect variable assignment
  103. =indirect a
  104. = ($indirect) 20
  105. =$indirect 20
  106. print $a
  107. # Or indirect getters
  108. print $$indirect
  109. # Control structures are merely builtin functions.
  110. if (less a 10) {
  111. print "Less"
  112. } else {
  113. print "More"
  114. }
  115. # That's all there is to the syntax. Apart from the built in commands,
  116. # the semantics are up to you to implement as
  117. # embedded commands.
  118. # Do note that MUESLI uses dynamic scoping for ease of implementation
  119. #{
  120. BLOCK
  121. PUSHS "More"
  122. CALL print
  123. PUSHBLOCK
  124. PUSHW else
  125. BLOCK
  126. PUSHS "Less"
  127. CALL print
  128. PUSHBLOCK
  129. PUSHI 10
  130. PUSHW a
  131. CALL less
  132. CALL if
  133. }