mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-18 19:34:27 -05:00
moving along with whitespace
This commit is contained in:
@@ -30,11 +30,12 @@ prechigh
|
||||
right '-=' '+=' '/=' '*=' '%='
|
||||
right DELETE INSTANCEOF TYPEOF
|
||||
left '.'
|
||||
right INDENT
|
||||
left OUTDENT
|
||||
right THROW FOR IN WHILE NEW SUPER
|
||||
left UNLESS IF ELSE EXTENDS
|
||||
left ASSIGN '||=' '&&='
|
||||
right RETURN INDENT
|
||||
left OUTDENT
|
||||
right RETURN
|
||||
preclow
|
||||
|
||||
# We expect 3 shift/reduce errors for optional syntax.
|
||||
@@ -88,8 +89,7 @@ rule
|
||||
;
|
||||
|
||||
Block:
|
||||
Then Expression { result = Expressions.new([val[1]]) }
|
||||
| INDENT Expressions OUTDENT { result = val[1] }
|
||||
INDENT Expressions OUTDENT { result = val[1] }
|
||||
;
|
||||
|
||||
# All tokens that can terminate an expression.
|
||||
@@ -98,12 +98,6 @@ rule
|
||||
| ";"
|
||||
;
|
||||
|
||||
# All tokens that can serve to begin the second block of a multi-part expression.
|
||||
Then:
|
||||
THEN
|
||||
| Terminator
|
||||
;
|
||||
|
||||
# All hard-coded values.
|
||||
Literal:
|
||||
NUMBER { result = LiteralNode.new(val[0]) }
|
||||
@@ -122,13 +116,13 @@ rule
|
||||
|
||||
# Assignment to a variable.
|
||||
Assign:
|
||||
Value ASSIGN Expression { result = AssignNode.new(val[0], val[2]) }
|
||||
Value ASSIGN Expression { result = AssignNode.new(val[0], val[2]) }
|
||||
;
|
||||
|
||||
# Assignment within an object literal.
|
||||
AssignObj:
|
||||
IDENTIFIER ASSIGN Expression { result = AssignNode.new(ValueNode.new(val[0]), val[2], :object) }
|
||||
| STRING ASSIGN Expression { result = AssignNode.new(ValueNode.new(LiteralNode.new(val[0])), val[2], :object) }
|
||||
IDENTIFIER ASSIGN Expression { result = AssignNode.new(ValueNode.new(val[0]), val[2], :object) }
|
||||
| STRING ASSIGN Expression { result = AssignNode.new(ValueNode.new(LiteralNode.new(val[0])), val[2], :object) }
|
||||
| Comment { result = val[0] }
|
||||
;
|
||||
|
||||
@@ -146,69 +140,45 @@ rule
|
||||
# For Ruby's Operator precedence, see:
|
||||
# https://www.cs.auckland.ac.nz/references/ruby/ProgrammingRuby/language.html
|
||||
Operation:
|
||||
'!' Expression { result = OpNode.new(val[0], val[1]) }
|
||||
| '!!' Expression { result = OpNode.new(val[0], val[1]) }
|
||||
| '-' Expression = UMINUS { result = OpNode.new(val[0], val[1]) }
|
||||
| NOT Expression { result = OpNode.new(val[0], val[1]) }
|
||||
| '~' Expression { result = OpNode.new(val[0], val[1]) }
|
||||
| '--' Expression { result = OpNode.new(val[0], val[1]) }
|
||||
| '++' Expression { result = OpNode.new(val[0], val[1]) }
|
||||
| Expression '--' { result = OpNode.new(val[1], val[0], nil, true) }
|
||||
| Expression '++' { result = OpNode.new(val[1], val[0], nil, true) }
|
||||
PrefixOperation
|
||||
| InfixOperation
|
||||
| PostfixOperation
|
||||
;
|
||||
|
||||
| Expression '*' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '/' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '%' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
PrefixOperation:
|
||||
PrefixSymbol PureExpression { result = OpNode.new(val[0], val[1]) }
|
||||
;
|
||||
|
||||
| Expression '+' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '-' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
PostfixOperation:
|
||||
PureExpression PostfixSymbol { result = OpNode.new(val[1], val[0], nil, true) }
|
||||
;
|
||||
|
||||
| Expression '<<' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '>>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '>>>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
InfixOperation:
|
||||
PureExpression
|
||||
InfixSymbol PureExpression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
;
|
||||
|
||||
| Expression '&' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '|' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '^' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
PrefixSymbol:
|
||||
'!' | '!!' | '-' = UMINUS | NOT | '~' | '--' | '++' | DELETE | TYPEOF
|
||||
;
|
||||
|
||||
| Expression '<=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '<' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '>=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
PostfixSymbol:
|
||||
'--' | '++'
|
||||
;
|
||||
|
||||
| Expression '==' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '!=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression IS Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression ISNT Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
|
||||
| Expression '&&' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '||' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression AND Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression OR Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
|
||||
| Expression '-=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '+=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '/=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '*=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '%=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '||=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
| Expression '&&=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
|
||||
| DELETE Expression { result = OpNode.new(val[0], val[1]) }
|
||||
| TYPEOF Expression { result = OpNode.new(val[0], val[1]) }
|
||||
| Expression INSTANCEOF Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
||||
InfixSymbol:
|
||||
'*' | '/' | '%' | '+' | '-' | '<<' | '>>' | '>>>' | '&' | '|' | '^'
|
||||
| '<=' | '<' | '>' | '>=' | '==' | '!=' | IS | ISNT | '&&' | '||'
|
||||
| AND | OR | '-=' | '+=' | '/=' | '*=' | '%=' | '||=' | '&&=' | INSTANCEOF
|
||||
;
|
||||
|
||||
# Function definition.
|
||||
Code:
|
||||
ParamList "=>" CodeBody { result = CodeNode.new(val[0], val[2]) }
|
||||
| "=>" CodeBody { result = CodeNode.new([], val[1]) }
|
||||
;
|
||||
|
||||
# The body of a function.
|
||||
CodeBody:
|
||||
/* nothing */ { result = Expressions.new([]) }
|
||||
| Block { result = val[0] }
|
||||
ParamList "=>" Block { result = CodeNode.new(val[0], val[2]) }
|
||||
| ParamList "=>" Expression { result = CodeNode.new(val[0], Expressions.new([val[2]])) }
|
||||
| "=>" Block { result = CodeNode.new([], val[1]) }
|
||||
| "=>" Expression { result = CodeNode.new([], Expressions.new([val[1]])) }
|
||||
| "=>" { result = CodeNode.new([], nil) }
|
||||
;
|
||||
|
||||
# The parameters to a function definition.
|
||||
@@ -299,7 +269,7 @@ rule
|
||||
Try:
|
||||
TRY Block Catch { result = TryNode.new(val[1], val[2][0], val[2][1]) }
|
||||
| TRY Block Catch
|
||||
FINALLY Block { result = TryNode.new(val[1], val[2][0], val[2][1], val[4]) }
|
||||
FINALLY Block { result = TryNode.new(val[1], val[2][0], val[2][1], val[4]) }
|
||||
;
|
||||
|
||||
# A catch clause.
|
||||
@@ -310,7 +280,7 @@ rule
|
||||
|
||||
# Throw an exception.
|
||||
Throw:
|
||||
THROW Expression { result = ThrowNode.new(val[1]) }
|
||||
THROW PureExpression { result = ThrowNode.new(val[1]) }
|
||||
;
|
||||
|
||||
# Parenthetical expressions.
|
||||
@@ -320,7 +290,7 @@ rule
|
||||
|
||||
# The while loop. (there is no do..while).
|
||||
While:
|
||||
WHILE Expression Block { result = WhileNode.new(val[1], val[3]) }
|
||||
WHILE PureExpression Block { result = WhileNode.new(val[1], val[3]) }
|
||||
;
|
||||
|
||||
# Array comprehensions, including guard and current index.
|
||||
@@ -328,8 +298,7 @@ rule
|
||||
For:
|
||||
Expression FOR
|
||||
ForVariables ForSource "." { result = ForNode.new(val[0], val[3][0], val[2][0], val[3][1], val[2][1]) }
|
||||
| FOR ForVariables ForSource
|
||||
Terminator Expressions "." { result = ForNode.new(val[4], val[2][0], val[1][0], val[2][1], val[1][1]) }
|
||||
| FOR ForVariables ForSource Block { result = ForNode.new(val[3], val[2][0], val[1][0], val[2][1], val[1][1]) }
|
||||
;
|
||||
|
||||
# An array comprehension has variables for the current element and index.
|
||||
@@ -347,10 +316,12 @@ rule
|
||||
|
||||
# Switch/When blocks.
|
||||
Switch:
|
||||
SWITCH Expression Then
|
||||
Whens { result = val[3].rewrite_condition(val[1]) }
|
||||
| SWITCH Expression Then
|
||||
Whens ELSE Block { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
|
||||
SWITCH Expression INDENT
|
||||
Whens OUTDENT { result = val[3].rewrite_condition(val[1]) }
|
||||
| SWITCH Expression INDENT
|
||||
Whens ELSE Block OUTDENT { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
|
||||
| SWITCH Expression INDENT
|
||||
Whens ELSE Expression OUTDENT { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
|
||||
;
|
||||
|
||||
# The inner list of whens.
|
||||
@@ -361,15 +332,27 @@ rule
|
||||
|
||||
# An individual when.
|
||||
When:
|
||||
WHEN Expression Then Block { result = IfNode.new(val[1], val[3]) }
|
||||
WHEN PureExpression Block { result = IfNode.new(val[1], val[2], nil, {:statement => true}) }
|
||||
| WHEN PureExpression
|
||||
THEN Expression Terminator { result = IfNode.new(val[1], val[3], nil, {:statement => true}) }
|
||||
;
|
||||
|
||||
# All of the following nutso if-else destructuring is to make the
|
||||
# grammar expand unambiguously.
|
||||
|
||||
# The condition itself.
|
||||
IfClause:
|
||||
IF PureExpression { result = val[1] }
|
||||
;
|
||||
|
||||
IfBlock:
|
||||
IfClause Block { result = IfNode.new(val[0], val[1]) }
|
||||
| IfClause THEN Expression { result = IfNode.new(val[0], val[2]) }
|
||||
;
|
||||
|
||||
# An elsif portion of an if-else block.
|
||||
ElsIf:
|
||||
ELSE IF Expression Block { result = IfNode.new(val[2], val[4]) }
|
||||
ELSE IfBlock { result = val[1] }
|
||||
;
|
||||
|
||||
# Multiple elsifs can be chained together.
|
||||
@@ -392,9 +375,9 @@ rule
|
||||
|
||||
# The full complement of if blocks, including postfix one-liner ifs and unlesses.
|
||||
If:
|
||||
IF Expression Block IfEnd { result = IfNode.new(val[1], val[2], val[3]) }
|
||||
| Expression IF Expression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true}) }
|
||||
| Expression UNLESS Expression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true, :invert => true}) }
|
||||
IfBlock IfEnd { result = val[0].add_else(val[1]) }
|
||||
| Block IfClause { result = IfNode.new(val[1], Expressions.new([val[0]]), nil, {:statement => true}) }
|
||||
| Block UNLESS PureExpression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true, :invert => true}) }
|
||||
;
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user