mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
removing the last traces of half-assignments. Issue #541.
This commit is contained in:
parent
980a663c19
commit
b18d7fb550
11 changed files with 36 additions and 41 deletions
|
@ -8,4 +8,4 @@ else
|
||||||
|
|
||||||
date = if friday then sue else jill
|
date = if friday then sue else jill
|
||||||
|
|
||||||
options = or defaults
|
options or= defaults
|
|
@ -60,8 +60,8 @@ race = ->
|
||||||
race()
|
race()
|
||||||
|
|
||||||
# Conditional assignment:
|
# Conditional assignment:
|
||||||
good = or evil
|
good or= evil
|
||||||
wine = and cheese
|
wine and= cheese
|
||||||
|
|
||||||
# Nested property access and calls.
|
# Nested property access and calls.
|
||||||
((moon.turn(360))).shapes[3].move({x: 45, y: 30}).position['top'].offset('x')
|
((moon.turn(360))).shapes[3].move({x: 45, y: 30}).position['top'].offset('x')
|
||||||
|
|
|
@ -12,7 +12,7 @@ class LinkedList
|
||||||
# Create a new node object to wrap the data.
|
# Create a new node object to wrap the data.
|
||||||
node = data: data, next: null
|
node = data: data, next: null
|
||||||
|
|
||||||
current = this._head = or node
|
current = this._head or= node
|
||||||
|
|
||||||
if this._head isnt node
|
if this._head isnt node
|
||||||
(current = current.next) while current.next
|
(current = current.next) while current.next
|
||||||
|
|
|
@ -46,7 +46,7 @@ LotteryDraw =
|
||||||
ticket_list.each (ticket) ->
|
ticket_list.each (ticket) ->
|
||||||
score = ticket.score result
|
score = ticket.score result
|
||||||
return if score is 0
|
return if score is 0
|
||||||
winners[buyer] = or []
|
winners[buyer] or= []
|
||||||
winners[buyer].push [ticket, score]
|
winners[buyer].push [ticket, score]
|
||||||
this.tickets = {}
|
this.tickets = {}
|
||||||
winners
|
winners
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
return this.literalToken();
|
return this.literalToken();
|
||||||
};
|
};
|
||||||
Lexer.prototype.identifierToken = function() {
|
Lexer.prototype.identifierToken = function() {
|
||||||
var _d, close_index, forcedIdentifier, id, tag;
|
var close_index, forcedIdentifier, id, tag;
|
||||||
if (!(id = this.match(IDENTIFIER, 1))) {
|
if (!(id = this.match(IDENTIFIER, 1))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -86,9 +86,6 @@
|
||||||
if (id === 'all' && this.tag() === 'FOR') {
|
if (id === 'all' && this.tag() === 'FOR') {
|
||||||
tag = 'ALL';
|
tag = 'ALL';
|
||||||
}
|
}
|
||||||
if (('AND' === (_d = this.tag() === '=' && tag) || 'OR' === _d)) {
|
|
||||||
return this.tag(1, CONVERSIONS[id] + '=');
|
|
||||||
}
|
|
||||||
if (include(JS_FORBIDDEN, id)) {
|
if (include(JS_FORBIDDEN, id)) {
|
||||||
if (forcedIdentifier) {
|
if (forcedIdentifier) {
|
||||||
tag = 'STRING';
|
tag = 'STRING';
|
||||||
|
|
|
@ -30,7 +30,7 @@ lexer = new Lexer
|
||||||
# Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
|
# Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
|
||||||
# compiler.
|
# compiler.
|
||||||
exports.compile = compile = (code, options) ->
|
exports.compile = compile = (code, options) ->
|
||||||
options = or {}
|
options or= {}
|
||||||
try
|
try
|
||||||
(parser.parse lexer.tokenize code).compile options
|
(parser.parse lexer.tokenize code).compile options
|
||||||
catch err
|
catch err
|
||||||
|
|
|
@ -156,7 +156,7 @@ printTokens = (tokens) ->
|
||||||
parseOptions = ->
|
parseOptions = ->
|
||||||
optionParser = new optparse.OptionParser SWITCHES, BANNER
|
optionParser = new optparse.OptionParser SWITCHES, BANNER
|
||||||
o = options = optionParser.parse(process.argv[2...process.argv.length])
|
o = options = optionParser.parse(process.argv[2...process.argv.length])
|
||||||
options.compile = or !!o.output
|
options.compile or= !!o.output
|
||||||
options.run = not (o.compile or o.print or o.lint)
|
options.run = not (o.compile or o.print or o.lint)
|
||||||
options.print = !! (o.print or (o.eval or o.stdio and o.compile))
|
options.print = !! (o.print or (o.eval or o.stdio and o.compile))
|
||||||
sources = options.arguments
|
sources = options.arguments
|
||||||
|
|
|
@ -88,8 +88,6 @@ exports.Lexer = class Lexer
|
||||||
tag = id.toUpperCase() if include(JS_KEYWORDS, id) or (not forcedIdentifier and include(COFFEE_KEYWORDS, id))
|
tag = id.toUpperCase() if include(JS_KEYWORDS, id) or (not forcedIdentifier and include(COFFEE_KEYWORDS, id))
|
||||||
tag = 'LEADING_WHEN' if tag is 'WHEN' and include LINE_BREAK, @tag()
|
tag = 'LEADING_WHEN' if tag is 'WHEN' and include LINE_BREAK, @tag()
|
||||||
tag = 'ALL' if id is 'all' and @tag() is 'FOR'
|
tag = 'ALL' if id is 'all' and @tag() is 'FOR'
|
||||||
if @tag() is '=' and tag in ['AND', 'OR']
|
|
||||||
return @tag 1, CONVERSIONS[id] + '='
|
|
||||||
if include(JS_FORBIDDEN, id)
|
if include(JS_FORBIDDEN, id)
|
||||||
if forcedIdentifier
|
if forcedIdentifier
|
||||||
tag = 'STRING'
|
tag = 'STRING'
|
||||||
|
@ -259,7 +257,7 @@ exports.Lexer = class Lexer
|
||||||
value = match and match[1]
|
value = match and match[1]
|
||||||
space = match and match[2]
|
space = match and match[2]
|
||||||
@tagParameters() if value and value.match CODE
|
@tagParameters() if value and value.match CODE
|
||||||
value = or @chunk.substr 0, 1
|
value or= @chunk.substr 0, 1
|
||||||
@i += value.length
|
@i += value.length
|
||||||
prevSpaced = @prev() and @prev().spaced
|
prevSpaced = @prev() and @prev().spaced
|
||||||
tag = value
|
tag = value
|
||||||
|
@ -347,7 +345,7 @@ exports.Lexer = class Lexer
|
||||||
# contents of the string. This method allows us to have strings within
|
# contents of the string. This method allows us to have strings within
|
||||||
# interpolations within strings, ad infinitum.
|
# interpolations within strings, ad infinitum.
|
||||||
balancedString: (str, delimited, options) ->
|
balancedString: (str, delimited, options) ->
|
||||||
options = or {}
|
options or= {}
|
||||||
slash = delimited[0][0] is '/'
|
slash = delimited[0][0] is '/'
|
||||||
levels = []
|
levels = []
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -384,7 +382,7 @@ exports.Lexer = class Lexer
|
||||||
# new Lexer, tokenize the interpolated contents, and merge them into the
|
# new Lexer, tokenize the interpolated contents, and merge them into the
|
||||||
# token stream.
|
# token stream.
|
||||||
interpolateString: (str, options) ->
|
interpolateString: (str, options) ->
|
||||||
options = or {}
|
options or= {}
|
||||||
if str.length < 3 or not starts str, '"'
|
if str.length < 3 or not starts str, '"'
|
||||||
@token 'STRING', str
|
@token 'STRING', str
|
||||||
else
|
else
|
||||||
|
|
|
@ -112,7 +112,7 @@ exports.BaseNode = class BaseNode
|
||||||
# `toString` representation of the node, for inspecting the parse tree.
|
# `toString` representation of the node, for inspecting the parse tree.
|
||||||
# This is what `coffee --nodes` prints out.
|
# This is what `coffee --nodes` prints out.
|
||||||
toString: (idt, override) ->
|
toString: (idt, override) ->
|
||||||
idt = or ''
|
idt or= ''
|
||||||
children = (child.toString idt + TAB for child in @collectChildren()).join('')
|
children = (child.toString idt + TAB for child in @collectChildren()).join('')
|
||||||
'\n' + idt + (override or @class) + children
|
'\n' + idt + (override or @class) + children
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ exports.Expressions = class Expressions extends BaseNode
|
||||||
|
|
||||||
# An **Expressions** is the only node that can serve as the root.
|
# An **Expressions** is the only node that can serve as the root.
|
||||||
compile: (o) ->
|
compile: (o) ->
|
||||||
o = or {}
|
o or= {}
|
||||||
if o.scope then super(o) else @compileRoot(o)
|
if o.scope then super(o) else @compileRoot(o)
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
|
@ -290,7 +290,7 @@ exports.ValueNode = class ValueNode extends BaseNode
|
||||||
|
|
||||||
# A **ValueNode** has a base and a list of property accesses.
|
# A **ValueNode** has a base and a list of property accesses.
|
||||||
constructor: (@base, @properties) ->
|
constructor: (@base, @properties) ->
|
||||||
@properties = or []
|
@properties or= []
|
||||||
|
|
||||||
# Add a property access to the list.
|
# Add a property access to the list.
|
||||||
push: (prop) ->
|
push: (prop) ->
|
||||||
|
@ -345,7 +345,7 @@ exports.ValueNode = class ValueNode extends BaseNode
|
||||||
only = del o, 'onlyFirst'
|
only = del o, 'onlyFirst'
|
||||||
op = del o, 'operation'
|
op = del o, 'operation'
|
||||||
props = if only then @properties[0...@properties.length - 1] else @properties
|
props = if only then @properties[0...@properties.length - 1] else @properties
|
||||||
o.chainRoot = or this
|
o.chainRoot or= this
|
||||||
baseline = @base.compile o
|
baseline = @base.compile o
|
||||||
baseline = "(#baseline)" if @hasProperties() and (@base instanceof ObjectNode or @isNumber())
|
baseline = "(#baseline)" if @hasProperties() and (@base instanceof ObjectNode or @isNumber())
|
||||||
complete = @last = baseline
|
complete = @last = baseline
|
||||||
|
@ -397,7 +397,7 @@ exports.CallNode = class CallNode extends BaseNode
|
||||||
@isNew = false
|
@isNew = false
|
||||||
@isSuper = variable is 'super'
|
@isSuper = variable is 'super'
|
||||||
@variable = if @isSuper then null else variable
|
@variable = if @isSuper then null else variable
|
||||||
@args = or []
|
@args or= []
|
||||||
@compileSplatArguments = (o) ->
|
@compileSplatArguments = (o) ->
|
||||||
SplatNode.compileSplattedArray.call(this, @args, o)
|
SplatNode.compileSplattedArray.call(this, @args, o)
|
||||||
|
|
||||||
|
@ -489,7 +489,7 @@ exports.AccessorNode = class AccessorNode extends BaseNode
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
name = @name.compile o
|
name = @name.compile o
|
||||||
o.chainRoot.wrapped = or @soakNode
|
o.chainRoot.wrapped or= @soakNode
|
||||||
namePart = if name.match(IS_STRING) then "[#name]" else ".#name"
|
namePart = if name.match(IS_STRING) then "[#name]" else ".#name"
|
||||||
@prototype + namePart
|
@prototype + namePart
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ exports.IndexNode = class IndexNode extends BaseNode
|
||||||
constructor: (@index) ->
|
constructor: (@index) ->
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
o.chainRoot.wrapped = or @soakNode
|
o.chainRoot.wrapped or= @soakNode
|
||||||
idx = @index.compile o
|
idx = @index.compile o
|
||||||
prefix = if @proto then '.prototype' else ''
|
prefix = if @proto then '.prototype' else ''
|
||||||
"#prefix[#idx]"
|
"#prefix[#idx]"
|
||||||
|
@ -554,7 +554,7 @@ exports.RangeNode = class RangeNode extends BaseNode
|
||||||
[from, to] = [parseInt(@fromNum, 10), parseInt(@toNum, 10)]
|
[from, to] = [parseInt(@fromNum, 10), parseInt(@toNum, 10)]
|
||||||
idx = del o, 'index'
|
idx = del o, 'index'
|
||||||
step = del o, 'step'
|
step = del o, 'step'
|
||||||
step = and "#idx += #{step.compile(o)}"
|
step and= "#idx += #{step.compile(o)}"
|
||||||
if from <= to
|
if from <= to
|
||||||
"#idx = #from; #idx <#@equals #to; #{step or "#idx++"}"
|
"#idx = #from; #idx <#@equals #to; #{step or "#idx++"}"
|
||||||
else
|
else
|
||||||
|
@ -633,7 +633,7 @@ exports.ArrayNode = class ArrayNode extends BaseNode
|
||||||
children: ['objects']
|
children: ['objects']
|
||||||
|
|
||||||
constructor: (@objects) ->
|
constructor: (@objects) ->
|
||||||
@objects = or []
|
@objects or= []
|
||||||
@compileSplatLiteral = (o) ->
|
@compileSplatLiteral = (o) ->
|
||||||
SplatNode.compileSplattedArray.call(this, @objects, o)
|
SplatNode.compileSplattedArray.call(this, @objects, o)
|
||||||
|
|
||||||
|
@ -668,7 +668,7 @@ exports.ClassNode = class ClassNode extends BaseNode
|
||||||
# Initialize a **ClassNode** with its name, an optional superclass, and a
|
# Initialize a **ClassNode** with its name, an optional superclass, and a
|
||||||
# list of prototype property assignments.
|
# list of prototype property assignments.
|
||||||
constructor: (@variable, @parent, @properties) ->
|
constructor: (@variable, @parent, @properties) ->
|
||||||
@properties = or []
|
@properties or= []
|
||||||
@returns = false
|
@returns = false
|
||||||
|
|
||||||
makeReturn: ->
|
makeReturn: ->
|
||||||
|
@ -707,8 +707,8 @@ exports.ClassNode = class ClassNode extends BaseNode
|
||||||
continue
|
continue
|
||||||
if func instanceof CodeNode and func.bound
|
if func instanceof CodeNode and func.bound
|
||||||
func.bound = false
|
func.bound = false
|
||||||
constScope = or new Scope(o.scope, constructor.body, constructor)
|
constScope or= new Scope(o.scope, constructor.body, constructor)
|
||||||
me = or constScope.freeVariable()
|
me or= constScope.freeVariable()
|
||||||
pname = pvar.compile(o)
|
pname = pvar.compile(o)
|
||||||
constructor.body.push new ReturnNode literal 'this' if constructor.body.empty()
|
constructor.body.push new ReturnNode literal 'this' if constructor.body.empty()
|
||||||
constructor.body.unshift literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#me, arguments); }"
|
constructor.body.unshift literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#me, arguments); }"
|
||||||
|
@ -838,8 +838,8 @@ exports.CodeNode = class CodeNode extends BaseNode
|
||||||
children: ['params', 'body']
|
children: ['params', 'body']
|
||||||
|
|
||||||
constructor: (@params, @body, tag) ->
|
constructor: (@params, @body, tag) ->
|
||||||
@params = or []
|
@params or= []
|
||||||
@body = or new Expressions
|
@body or= new Expressions
|
||||||
@bound = tag is 'boundfunc'
|
@bound = tag is 'boundfunc'
|
||||||
|
|
||||||
# Compilation creates a new scope unless explicitly asked to share with the
|
# Compilation creates a new scope unless explicitly asked to share with the
|
||||||
|
@ -893,7 +893,7 @@ exports.CodeNode = class CodeNode extends BaseNode
|
||||||
traverseChildren: (crossScope, func) -> super(crossScope, func) if crossScope
|
traverseChildren: (crossScope, func) -> super(crossScope, func) if crossScope
|
||||||
|
|
||||||
toString: (idt) ->
|
toString: (idt) ->
|
||||||
idt = or ''
|
idt or= ''
|
||||||
children = (child.toString(idt + TAB) for child in @collectChildren()).join('')
|
children = (child.toString(idt + TAB) for child in @collectChildren()).join('')
|
||||||
"\n#idt#children"
|
"\n#idt#children"
|
||||||
|
|
||||||
|
@ -1251,7 +1251,7 @@ exports.ForNode = class ForNode extends BaseNode
|
||||||
isStatement: -> yes
|
isStatement: -> yes
|
||||||
|
|
||||||
constructor: (@body, source, @name, @index) ->
|
constructor: (@body, source, @name, @index) ->
|
||||||
@index = or null
|
@index or= null
|
||||||
@source = source.source
|
@source = source.source
|
||||||
@guard = source.guard
|
@guard = source.guard
|
||||||
@step = source.step
|
@step = source.step
|
||||||
|
@ -1340,7 +1340,7 @@ exports.IfNode = class IfNode extends BaseNode
|
||||||
children: ['condition', 'switchSubject', 'body', 'elseBody', 'assigner']
|
children: ['condition', 'switchSubject', 'body', 'elseBody', 'assigner']
|
||||||
|
|
||||||
constructor: (@condition, @body, @tags) ->
|
constructor: (@condition, @body, @tags) ->
|
||||||
@tags = or {}
|
@tags or= {}
|
||||||
@condition = new OpNode('!', new ParentheticalNode(@condition)) if @tags.invert
|
@condition = new OpNode('!', new ParentheticalNode(@condition)) if @tags.invert
|
||||||
@elseBody = null
|
@elseBody = null
|
||||||
@isChain = false
|
@isChain = false
|
||||||
|
@ -1386,7 +1386,7 @@ exports.IfNode = class IfNode extends BaseNode
|
||||||
# The **IfNode** only compiles into a statement if either of its bodies needs
|
# The **IfNode** only compiles into a statement if either of its bodies needs
|
||||||
# to be a statement. Otherwise a ternary is safe.
|
# to be a statement. Otherwise a ternary is safe.
|
||||||
isStatement: ->
|
isStatement: ->
|
||||||
@statement = or !!(@tags.statement or @bodyNode().isStatement() or (@elseBody and @elseBodyNode().isStatement()))
|
@statement or= !!(@tags.statement or @bodyNode().isStatement() or (@elseBody and @elseBodyNode().isStatement()))
|
||||||
|
|
||||||
compileCondition: (o) ->
|
compileCondition: (o) ->
|
||||||
(cond.compile(o) for cond in flatten([@condition])).join(' || ')
|
(cond.compile(o) for cond in flatten([@condition])).join(' || ')
|
||||||
|
@ -1396,8 +1396,8 @@ exports.IfNode = class IfNode extends BaseNode
|
||||||
|
|
||||||
makeReturn: ->
|
makeReturn: ->
|
||||||
if @isStatement()
|
if @isStatement()
|
||||||
@body = and @ensureExpressions(@body.makeReturn())
|
@body and= @ensureExpressions(@body.makeReturn())
|
||||||
@elseBody = and @ensureExpressions(@elseBody.makeReturn())
|
@elseBody and= @ensureExpressions(@elseBody.makeReturn())
|
||||||
this
|
this
|
||||||
else
|
else
|
||||||
new ReturnNode this
|
new ReturnNode this
|
||||||
|
|
|
@ -239,7 +239,7 @@ exports.Rewriter = class Rewriter
|
||||||
@scanTokens (prev, token, post, i) =>
|
@scanTokens (prev, token, post, i) =>
|
||||||
for pair in pairs
|
for pair in pairs
|
||||||
[open, close] = pair
|
[open, close] = pair
|
||||||
levels[open] = or 0
|
levels[open] or= 0
|
||||||
if token[0] is open
|
if token[0] is open
|
||||||
openLine[open] = token[2] if levels[open] == 0
|
openLine[open] = token[2] if levels[open] == 0
|
||||||
levels[open] += 1
|
levels[open] += 1
|
||||||
|
|
|
@ -68,14 +68,14 @@ ok x*+y is -50
|
||||||
|
|
||||||
# Half-operators.
|
# Half-operators.
|
||||||
one = two = null
|
one = two = null
|
||||||
one = or 1
|
one or= 1
|
||||||
two = or 2
|
two or= 2
|
||||||
|
|
||||||
ok one is 1
|
ok one is 1
|
||||||
ok two is 2
|
ok two is 2
|
||||||
|
|
||||||
one = and 'one'
|
one and= 'one'
|
||||||
two = and 'two'
|
two and= 'two'
|
||||||
|
|
||||||
ok one is 'one'
|
ok one is 'one'
|
||||||
ok two is 'two'
|
ok two is 'two'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue