Skip to content

Commit

Permalink
added the conditional existence operator
Browse files Browse the repository at this point in the history
  • Loading branch information
jashkenas committed Jan 17, 2010
1 parent 0bc4da2 commit 95b3624
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 3 deletions.
3 changes: 2 additions & 1 deletion lib/coffee_script/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ prechigh
right WHEN LEADING_WHEN IN OF BY
right THROW FOR NEW SUPER
left EXTENDS
left ASSIGN '||=' '&&='
left ASSIGN '||=' '&&=' '?='
right RETURN
right '=>' '==>' UNLESS IF ELSE WHILE
preclow
Expand Down Expand Up @@ -187,6 +187,7 @@ rule
| 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 INSTANCEOF Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression IN Expression { result = OpNode.new(val[1], val[0], val[2]) }
Expand Down
2 changes: 1 addition & 1 deletion lib/coffee_script/lexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Lexer
STRING = /\A(""|''|"(.*?)([^\\]|\\\\)"|'(.*?)([^\\]|\\\\)')/m
HEREDOC = /\A("{6}|'{6}|"{3}\n?(.*?)\n?(\s*)"{3}|'{3}\n?(.*?)\n?(\s*)'{3})/m
JS = /\A(``|`(.*?)([^\\]|\\\\)`)/m
OPERATOR = /\A([+\*&|\/\-%=<>:!]+)/
OPERATOR = /\A([+\*&|\/\-%=<>:!?]+)/
WHITESPACE = /\A([ \t]+)/
COMMENT = /\A(((\n?[ \t]*)?#.*$)+)/
CODE = /\A(=?=>)/
Expand Down
4 changes: 3 additions & 1 deletion lib/coffee_script/nodes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ class OpNode < Node
:not => '!'
}
CHAINABLE = [:<, :>, :>=, :<=, :===, :'!===']
CONDITIONALS = [:'||=', :'&&=']
CONDITIONALS = [:'||=', :'&&=', :'?=']
PREFIX_OPERATORS = [:typeof, :delete]

def initialize(operator, first, second=nil, flip=false)
Expand Down Expand Up @@ -593,7 +593,9 @@ def compile_chain(o)

def compile_conditional(o)
first, second = @first.compile(o), @second.compile(o)
o[:scope].find(first) if @first.unwrap.is_a?(Value)
sym = @operator[0..1]
return "#{first} = (typeof #{first} !== \"undefined\" && #{first} !== null) ? #{first} : #{second}" if @operator == '?='
"#{first} = #{first} #{sym} #{second}"
end

Expand Down
10 changes: 10 additions & 0 deletions test/fixtures/execution/test_operations.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,13 @@ i: 0
func: => i++

print(1 > func() < 1)


# The conditional assignment based on existence.

a: 5
a: null
a ?= 10
b ?= 10

print(a is 10 and b is 10)

0 comments on commit 95b3624

Please sign in to comment.