1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

first draft of optional parentheses, with a couple tests ... more to follow

This commit is contained in:
Jeremy Ashkenas 2010-01-24 22:32:06 -05:00
parent 4b267b401a
commit 70e3a6ef2f
4 changed files with 38 additions and 15 deletions

View file

@ -17,6 +17,10 @@ module CoffeeScript
# Tokens that indicate the close of a clause of an expression.
EXPRESSION_CLOSE = [:CATCH, :WHEN, :ELSE, :FINALLY] + EXPRESSION_TAIL
# Tokens that, when immediately following an identifier, activate an
# implicit method call.
IMPLICIT_CALL = [:IDENTIFIER, :NUMBER, :STRING, :JS, :REGEX]
# The inverse mappings of token pairs we're trying to fix up.
INVERSES = BALANCED_PAIRS.inject({}) do |memo, pair|
memo[pair.first] = pair.last
@ -39,6 +43,7 @@ module CoffeeScript
remove_mid_expression_newlines
move_commas_outside_outdents
add_implicit_indentation
add_implicit_parentheses
ensure_balance(*BALANCED_PAIRS)
rewrite_closing_parens
@tokens
@ -140,6 +145,24 @@ module CoffeeScript
end
end
# Methods may be optionally called without parentheses, for simple cases.
# Insert the implicit parentheses here, so that the parser doesn't have to
# deal with them.
def add_implicit_parentheses
open = false
scan_tokens do |prev, token, post, i|
if open && token[0] == "\n"
@tokens.insert(i, [')', Value.new(')', token[1].line)])
open = false
next 2
end
next 1 unless prev[0] == :IDENTIFIER && IMPLICIT_CALL.include?(token[0])
@tokens.insert(i, ['(', Value.new('(', token[1].line)])
open = true
next 2
end
end
# Ensure that all listed pairs of tokens are correctly balanced throughout
# the course of the token stream.
def ensure_balance(*pairs)

View file

@ -4,7 +4,7 @@ area: x, y, x1, y1 =>
x: y: 10
x1: y1: 20
print(area(x, y, x1, y1) is 100)
print area(x, y, x1, y1) is 100
print(area(x, y,
x1, y1) is 100)
@ -19,9 +19,9 @@ print(area(
# Arguments are turned into arrays.
curried: =>
print(area.apply(this, arguments.concat(20, 20)) is 100)
print area.apply(this, arguments.concat(20, 20)) is 100
curried(10, 10)
curried 10, 10
# Arguments is not a special keyword -- it can be assigned to:
@ -29,4 +29,4 @@ func: =>
arguments: 25
arguments
print(func(100) is 25)
print func(100) is 25

View file

@ -1,15 +1,15 @@
nums: n * n for n in [1, 2, 3] when n % 2 isnt 0
results: n * 2 for n in nums
print(results.join(',') is '2,18')
print results.join(',') is '2,18'
obj: {one: 1, two: 2, three: 3}
names: prop + '!' for prop of obj
odds: prop + '!' for prop, value of obj when value % 2 isnt 0
print(names.join(' ') is "one! two! three!")
print(odds.join(' ') is "one! three!")
print names.join(' ') is "one! two! three!"
print odds.join(' ') is "one! three!"
evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
@ -17,12 +17,12 @@ evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
num -= 2
num * -1
print(evens.join(', ') is '4, 6, 8')
print evens.join(', ') is '4, 6, 8'
# Make sure that the "in" operator still works.
print(2 in evens)
print 2 in evens
# When functions are being defined within the body of a comprehension, make
@ -37,6 +37,6 @@ for method in methods
obj[name]: =>
"I'm " + name
print(obj.one() is "I'm one")
print(obj.two() is "I'm two")
print(obj.three() is "I'm three")
print obj.one() is "I'm one"
print obj.two() is "I'm two"
print obj.three() is "I'm three"

View file

@ -7,7 +7,7 @@ catch error
result2: try nonexistent * missing catch error then true
print(result is true and result2 is true)
print result is true and result2 is true
# Assign to conditional.
@ -16,8 +16,8 @@ get_x: => 10
if x: get_x() then 100
print(x is 10)
print x is 10
x: if get_x() then 100
print(x is 100)
print x is 100