Category:Smalltalk: Difference between revisions

Line 34:
 
=== Grammar ===
This is an informal description (1); a formal (and correct) description is found eg. in the ANSI spec.
... to be added ... (for now follow the link at the right...)
 
====Lexical Tokens (should/cannot be used as message names) (2)====
<pre> ":=" assignment
"ˆ" return from method
"(" ")" parentheses for grouping in expressions
"." period; statement/expression separator
"|" vert. bar; var/arg declaration separator
";" cascaded message (NOT a statement separator)</pre>
 
====Comment====
<pre> "..." any text in double quotes
"/ ... an EOL comment (not all dialects support this)
"<<TOKEN an token comment (not all dialects support this)
...
TOKEN</pre>
====Predefined (reserved) identifiers====
<pre> "self" pseudo variable (receiver of current message)
"super" pseudo variable (for super sends)
"thisContext" current continuation (stack frame)</pre>
 
====Syntax (in Pseudo BNF)====
<br>Text in double quotes are lexical tokens.
<br>"[..]" means: optional.
<br>"*" means: repeat (0..n)
 
<pre>
method ::= <methodSpec> <methodBody>
 
methodSpec ::= <unarySelector>
| <binarySelector> <argName>
| <keyword> <argName> [ <keyword> <argName> ]*
 
methodBody ::= [ <localVarDecl> ] <statementList>
 
localVarDecl ::= "|" [ <varName> ]* "|"
 
statementList ::= [ <statement> [ "." <statement> ] *
 
statement ::= <expression>
| "ˆ" <expression>. // return from method (3);
 
//
// expressions
//
expression ::= <assignment>
| <messageSend>
 
assignment ::= <variable> "::=" <expression>
 
messageSend ::= <singleMessage>
| <cascadedMessage>
 
singleMessage ::= <unaryMessage>
| <binaryMessage>
| <keywordMessage>
 
unaryExpression ::= <unaryMessage>
| <primary>
 
binaryExpression ::= <binaryMessage>
| <unaryExpression>
 
keywordExpression ::= <keywordMessage>
| <binaryExpression>
 
unaryMessage ::= <unaryExpression> <unarySelector>. (4)
 
binaryMessage ::= <binaryExpression> <binarySelector> <unaryExpression> (4)
 
keywordMessage ::= <binaryExpression> <keyword> <binaryExpression> [ <keyword> <binaryExpression> ]*
 
cascadedMessage ::= <messageSend> ";" <unarySelector> (5)
| <messageSend> ";" <binarySelector> <unaryExpression>
| <messageSend> ";" <keyword> <binaryExpression> [ <keyword> <binaryExpression> ]*
 
primary ::= <variable>
| <block>
| <literal>
| <constructedArray>
| "(" <expression> ")"
 
<variable> ::= (<underline>|<letter>)[<underline>|<letter>|digit]*
 
<block> ::= "[" [ <blockArgs> "|" [ <statementList> ]
 
constructedArray ::= "{" [ <expression> [ "." <expression> ]* "}"
 
//
// selectors (message names)
//
selector ::= < unarySelector> | <binarySelector> | <keywordSelector>
 
unarySelector ::= (<underline>|<letter>)[<underline>|<letter>|digit]*
 
binarySelector ::= <anyAllowedNonDigitNonLetterChar>*
 
keywordSelector ::= <keyword> [ <keyword> ]*
 
keyword ::= (<underline>|<letter>)[<underline>|<letter>|digit]*":"
// i.e. a "word" immediately. followed by colon
 
//
// constants
//
literal ::= <number>
| <stringConst>
| <symbolConst>
| <characterConst>
| <arrayConst>
| <byteArrayConst>
 
number ::= <integerConst>
| <floatConst>
| <fractionConst> (6)
| <scaledDecimalConst>
stringConst ::= "'" [ <anyChar> | <doubledQuote> ]* "'"
 
doubledQuote ::= "'" "'"
 
symbolConst ::= "#" <stringConst>
| '#' <selector>
 
characterConst ::= "$" <anyChar>
 
floatConst ::= [<sign>] <digits> [ "." <digits> ] ["e" [<sign>] <digits> ] (7)
 
integerConst ::= [ <radix> "r" ] [<sign>] [ <digit> ]*
 
radix ::= <digit>[<digit>] // value in [2..36]
 
fractionConst ::= [<sign>] "(" <integerConst> "/" <integerConst> ")"
 
scaledDecimalConst ::= [<sign>] <digits> "s" <scaleDigits>
 
arrayConst ::= "#" <arrayElementList>
 
arrayElementList ::= "(" [ <arrayElement> | ]* ")"
 
arrayElement ::= <literal>
| <arrayElementList> // i.e. you can omit the "#" for arrays of arrays
 
byteArrayConst ::= "#[" [ <byteArrayElement> ]* "]"
 
byteArrayElement ::= <integerConst> // must be in 0..255
 
 
(1) typed in from memory. No warranty whatsoever for correctness.
 
(2) some dialects allow eg. "|" , "ˆ" or "#" to be used as message selector or as part of a message selector. For portable code, these should not be used. For details, consult the specific dialect's documentation.
 
(3) a return always returns from the current method. Especially if a return statement is inside a block (!).
 
(4) left to right
 
(5) a cascade message is "another message sent to the previous receiver".
 
(6) the syntax for fraction constants is the same as an expression to create one (i.e. a parenthesized message send of "/"). Thus, implementations which doe not support fraction constants will evaluate the fraction at execution time (usually, the jitter will detect that constant expression and optimize it away)
 
(7) most dialects allow for multiple precision floats (i.e. single precision, double precision, extendend precision IEEE) to be specified using different expo characters (eg. "1e5" vs. "1f5" vs. "1q5")
</pre>
 
== Language Semantic ==
Anonymous user