design_muesli.muesli 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. {
  56. print "hello"
  57. print "world"
  58. }
  59. # Commands can also take blocks as parameters. Don't put a newline between } and {
  60. # 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 built 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. # Variables are nor part of the language but of the built in commands
  87. # Variables are set in the current scope with
  88. set a 10
  89. # And fetched in the current scope with get
  90. print (get a 10)
  91. # To acces a variable in the scope one above current use upset/upget.
  92. upset a 10
  93. # However, there is syntactic sugar:
  94. # =foo bar gets mapped to (set foo bar)
  95. =a 10
  96. # $foo means (get foo)
  97. print $a
  98. # combinations of = followed by $ are allowed for indirect variable assignment
  99. =foo a
  100. =$foo 20
  101. print $a
  102. # Control structures are merely built in functions.
  103. if (less a 10) {
  104. print "Less"
  105. } else {
  106. print "More"
  107. }
  108. # That's all there is to the syntax. Apart from the built in commands,
  109. # the semantics are up to you to implement as
  110. # embedded commands.
  111. # Do note that MUESLI uses dynamic scoping for ease of implementation
  112. #{
  113. BLOCK
  114. PUSHS "More"
  115. CALL print
  116. PUSHBLOCK
  117. PUSHW else
  118. BLOCK
  119. PUSHS "Less"
  120. CALL print
  121. PUSHBLOCK
  122. PUSHI 10
  123. PUSHW a
  124. CALL less
  125. CALL if
  126. }