# Muesli is a Multi Use Embeddable Scripting Language Indeed. # It is a scripting language with a TCL or shell like syntax, but somewhat # OOP and LISP like semantics. # First it will be an embeddable scripting language implemented in Go. # In what follows I will describe the design of the language though example. # # Why is there a # before these lines? # begins a comment, until the end of the # line. MUESLI does not execute comments but they are collected # for documentation purposes. More on that topic later # Muesli is a line based language. # A newline preceded by a \ is ignored, even after a comment so \ this is still comment # Muesli consists of newline separated statements, however, a newline # after { or the do keyword is ignored and does not count as a separator. /* C style comments are also supported, and unlke C, they DO nest, but the comment indicator and the end of comment indicator must be the fist element on the line. Anything on the line of the end-of-comment indicator is also ignored /* so this is fine */ this is ignored too */ # Empty lines are ignored. # ... # Muesli supports integer constants with type Int 1 2 378 +108 -878 # ... Character constants with escapes with type Rune # This may also be unicode code points if above ascii range. 'a' # It also supports multi line string constants with escapes, with type String "Hello world\" " # and multi line strings without escapes ` "Pop" goes the weasel's tail. ` # And booleans constants of type Bool !true !false # And simple floating point constants, but no exponential notation, with type Float +0.5 -7.000005 # Lists can be created between [ ] and may be heterogenous or homogenous. # The [ ] must be space separated. # The type is Any[] if heterogenous, [ foo "bar" ] # The type is Int@ below [ 1 2 3 ] # A sequence of a lower case letter followed by anything that is not whitespace. # For example: this-IS*a/single+Word._ # The value of a word is a string with the word itself. # If the word is at the beginning of the line it is invoked as a command. # Muesli's basic syntax is that of the command. Spaces separate the arguments. # of the command. The first word is the command, the rest are the arguments. print "hello" world 7 0.9 # the previous command outputs: "hello world 7 0.9" to standard output # A command has one or more results that can be captured with a parenthesis print ( mul 3 ( sum 5 7 ) ) # Commands can be grouped into blocks. The value of the block is that of it's last command. { print "hello" print "world" } # Commands can also take blocks as parameters. Don't put a newline between } and { # to be sure multiple blocks get passed command { print "first block" } and also { print "second block" } # In Muesli all values are typed. Types can be defined by the built type command. type Door ( object locked Bool keys Item[] ) # Commands can be defined by the built in 'to' command. # They can have many arguments and many results. to open [door Door key Item] Bool { if (contains (member door key) key) { set } } # Unlike TCL, MUESLI values are typed, and commands # can be overloaded based on the types the types of their arguments. # Types are much like words, but they begin with an upper case letter, up to the # next whitespace. # A type that end in [] is a list, [][] a list of lists, etc, and a type # that end in ... represents a variable argument, which must be last. # Muesli tries to match the types, from narrow to wide for objects in the order # Outer class, Embedded Class, Object, Any, # and for primitive types , Primitive, Any # You can override commands with more specific ones but not existing ones # that have the same specificity. # Variables are nor part of the language but of the built in commands # Variables are set in the current scope with set a 10 # And fetched in the current scope with get print (get a 10) # To acces a variable in the scope one above current use upset/upget. upset a 10 # However, there is syntactic sugar: # =foo bar gets mapped to (set foo bar) =a 10 # $foo means (get foo) print $a # combinations of = followed by $ are allowed for indirect variable assignment =foo a =$foo 20 print $a # Control structures are merely built in functions. if (less a 10) { print "Less" } else { print "More" } # That's all there is to the syntax. Apart from the built in commands, # the semantics are up to you to implement as # embedded commands. /* BLOCK PUSHS "More" CALL print PUSHBLOCK PUSHW else BLOCK PUSHS "Less" CALL print PUSHBLOCK PUSHI 10 PUSHW a CALL less CALL if */