<Program> ::= <µExpression>An Agora-S program is a meta-message (a message to the interpreter). Meta messages are like lisp's special forms. They are used to reify interpreter processes to the language level. In lisp or scheme this is done by (define...) and (macro...) 'procedure calls'. Of course, these are not really procedure calls because this would cause their arguments to be evaluated. Instead, they can be seen as calls of procedures of the interpreter. The calls to the interpreter are literally reified in the language.<µExpression> ::= <µOperation> [ <µKeyword> <µExpression> ]
<µOperation> ::= <µUnary> [ <µOperator> <µOperation> ]
<µUnary> ::= <Expression> | <µUnary> <µName>
<Expression> ::= <Operation> [ <Keyword> <Expression> ]
<Operation> ::= <Unary> [ <Operator> <Operation> ]
<Unary> ::= <Factor> | <Unary> <Name>
<Factor> ::= <Name> | <Block> | <Literal> ) |
<µName> | '('<µExpression>')'
<Block> ::= '[' [ <<µExpressionList> ] ']'
<µExpressionList> ::= <µExpression> [ ';'<µExpressionList> ]
In the same way, an Agora (be it an Agora94 or an Agora-S) program is a mixture of ordinary messages and reifier messages. Both kinds of messages are subdivided in unary messages, operator messages and keyword messages. As in Smalltalk, unary messages have the highest precedence and keyword messages have the lowest precedence. Furthermore, ordinary messages have precedence over reifier messages. The precedence rules of the Agora-S syntax are therefore (from highest to lowest precedence):
The currently implemented reifier messages in Agora-S are defined below:
<ident> µvar
defines a new variable. This is an example of a unary reifier message
<ident> µvar: <exp>
defines a new variable with initial value <exp>. This is an example of a keyword reifier message.
<ident> <unary> µmethod: <body>
defines a new unary method (e.g. size, abs,...) with <body>
<ident> <operator> <ident> µmethod: <body>
defines a new operator method (e.g. +,-,...) with <body>
<ident> <keyword>:<ident> ... µmethod: <body>
defines a new keyword method (e.g. at:put: ) with <body>
µself
In Agora-S programs, every method is annotated with by a name for its receiver, e.g.
theReceiver doSomething: arg µmethod [...]Using 'theReceiver' in [...] precludes using stuff (e.g. methods) that is declared in [...] itself, because theReceiver does not contain that stuff. However, if a method is executed, a local extension of its receiver is created that contains all the declarations inside [...]. This local extension can be accessed by refering to µself. A consequence of returning µself is that the extended receiver is returned, which is precisely what mixin methods of Agora94 do.
<exp> µclone
clones the object <exp>.
<exp> µproto
<exp1> µ= <exp2>
checks if the receiver <exp1> is equal to <exp2>. This is an example of a reifier operator message.
<exp> µinspect
inspects the expression <exp>. For the moment, this is merely a pretty print of the object's internal state.
<string> µerror
shows the string as an error message.
<string> µdisplay
displays the receiver
<string> µscheme
executes the string as a scheme-expression
<exp> µnative
<exp> µnative: <string>
<ident> µload
load the file <ident> and substitute it at this place
<exp> µdump: <ident>
<block> µvalue
takes the block, evaluates it and returns the value returned by the block.
<ident> µ<- <exp>
assigns the <exp> to the variable <ident>
<boolExp> µthen: <expThen>
takes a boolean expression and a block. The block is executed if the expression is true. This is again an example of a keyword reifier message.
<boolExp> µthen: <expThen> µelse: <expElse>
When <boolExp> evaulates to true, the <expThen> is executed. Otherwise the <expElse> is executed.
<boolExp> µwhile: <expWhile>
executes <expWhile> while <boolExp> remains true.
<ident> µfrom: <expFrom> µto: <expTo> µdo: <expDo>
a for-loop with the usual semantics.