moving along with whitespace

This commit is contained in:
Jeremy Ashkenas
2009-12-28 23:08:02 -05:00
parent ddd52a1845
commit cea417de02
9 changed files with 91 additions and 107 deletions

View File

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

View File

@@ -3,6 +3,6 @@ results: n * 2 for n in nums.
# next: for n in [1, 2, 3] if n % 2 isnt 0 # next: for n in [1, 2, 3] if n % 2 isnt 0
# print('hi') if false # print('hi') if false
# n * n * 2. # n * n * 2
print(results.join(',') is '2,18') print(results.join(',') is '2,18')

View File

@@ -1,6 +1,6 @@
result: try result: try
nonexistent * missing nonexistent * missing
catch error catch error
true. true
print(result) print(result)

View File

@@ -1,21 +1,21 @@
Base: => . Base: =>
Base.prototype.func: string => Base.prototype.func: string =>
'zero/' + string. 'zero/' + string
FirstChild: => . FirstChild: =>
FirstChild extends Base FirstChild extends Base
FirstChild.prototype.func: string => FirstChild.prototype.func: string =>
super('one/') + string. super('one/') + string
SecondChild: => . SecondChild: =>
SecondChild extends FirstChild SecondChild extends FirstChild
SecondChild.prototype.func: string => SecondChild.prototype.func: string =>
super('two/') + string. super('two/') + string
ThirdChild: => . ThirdChild: =>
ThirdChild extends SecondChild ThirdChild extends SecondChild
ThirdChild.prototype.func: string => ThirdChild.prototype.func: string =>
super('three/') + string. super('three/') + string
result: (new ThirdChild()).func('four') result: (new ThirdChild()).func('four')

View File

@@ -1,4 +1,4 @@
identity_wrap: x => => x.. identity_wrap: x => => x
result: identity_wrap(identity_wrap(true))()() result: identity_wrap(identity_wrap(true))()()

View File

@@ -3,7 +3,7 @@ func: =>
b: [] b: []
while a >= 0 while a >= 0
b.push('o') b.push('o')
a--. a--
c: { c: {
"text": b "text": b
@@ -14,14 +14,14 @@ func: =>
c.text: if false c.text: if false
'error' 'error'
else else
c.text + '---'. c.text + '---'
d = { d = {
text = c.text text = c.text
} }
c.list: l for l in d.text.split('') if l is '-'. c.list: l for l in d.text.split('') if l is '-'
c.single: c.list[1..1][0]. c.single: c.list[1..1][0]
print(func() == '-') print(func() == '-')

View File

@@ -3,9 +3,8 @@ c: false
result: if a result: if a
if b if b
if c then false if c then false else
else
if d if d
true.... true
print(result) print(result)

View File

@@ -1,6 +1,6 @@
six: \ six: \
1 + \ 1 + \
2 + \ 2 + \
3 3
print(six is 6) print(six is 6)

View File

@@ -1,11 +1,13 @@
num: 10 num: 10
result: switch num result: switch num
when 5 then false when 5 then false
when 'a' when 'a'
false true
when 10 then true true
when 11 then false false
else false. when 10 then true
when 11 then false
else false
print(result) print(result)