- Strings are enclosed in double-quotes. Any double-quotes within the string are escaped with backslash.
- Characters are enclosed in single-quotes. A single-quote must be escaped.
- Integers can be base 10 (42), base 16 (0x2A), or base 2 (0b101010).
- Symbols (used to name messages) begin with a hash mark (#) and can contain any legal message (see below).
- Arrays can contain any sequence of expressions, contained in #( ... ).
A normal set of control characters can be used in strings and characters using backslash (\n, \t, \e, etc.), plus Unicode hex escapes (\u002A).
All messages are sent to a receiver. There are three types of message sends: unary, binary (operator), and keyword.
receiver unaryMessagesends #unaryMessage to
receiver + argumentsends #+ to
receiverwith an argument (where + can be any sequence of Unicode operator characters)
receiver do: this with: thatsends #do:with: to
4 squared + 2 to: 12 + 8 factorial
is equivalent to
((4 squared) + 2) to: (12 + (8 factorial))
All operators have equal precedence.
Precedence can be overridden using parentheses.
A statement takes one of three forms: normal, assignment, and return.
A normal statement is simply a message send (which can have message sends as its receiver or arguments, recursively).
An assignment statement consists of a variable, the assignment symbol :=, and a message send, like
foo := bar value.
A return statement consists of the return symbol ^, and a message send, like
Statements are separated by a full stop.
Local variables are declared between vertical bars, like this:
| x |
| x. y. z. |
Thanks to a wee bit of context-sensitivity in the parser, | is still available as an operator.
Any non-whitespace, non-punctuation Unicode character (plus the underscore) is legal in an identifier. Identifiers must not start with a digit.
A block is a set of statements enclosed in square brackets ( [ ... ] ). Blocks may contain any mix of statements and variable declarations. A block can define arguments, which must appear in a declaration at the start of the block; arguments are indicated with colons, eg
[ | :x | x + 2]
Scoping is entirely lexical. There are no global variables. Specifically, scopes at this point nest as follows:
class variables -> method arguments -> method locals > block arguments/locals (-> block arguments/locals...)
Mongoose has three reserved words.
selfrefers to the object whose method is currently executing.
superis an alias for
selfthat starts method lookup at the parent class.
Self(capitalized, like a class) is a placeholder for the class of
self, whatever it may be (in descendants and the like).
selfis not a reserved word per se; it can be bound to any identifier within a method, but the compiler currently enforces
Self(capitalized) is likely to be renamed, due to the potential for confusion with
I'm considering a couple additional literal forms, but that's the entire language at the moment.
For writing classes in text format, there's a declarative format that lays out methods and such, but it's extrasyntactic right now.