mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
first step towards requiring #{ ... } interpolation -- removing naked interps from the compiler.
This commit is contained in:
parent
b1f7d5e33b
commit
9df3e6a538
28 changed files with 284 additions and 300 deletions
28
Cakefile
28
Cakefile
|
@ -16,25 +16,25 @@ run = (args) ->
|
||||||
|
|
||||||
# Log a message with a color.
|
# Log a message with a color.
|
||||||
log = (message, color, explanation) ->
|
log = (message, color, explanation) ->
|
||||||
puts "#color#message#reset #{explanation or ''}"
|
puts color + message + reset + ' ' + (explanation or '')
|
||||||
|
|
||||||
option '-p', '--prefix [DIR]', 'set the installation prefix for `cake install`'
|
option '-p', '--prefix [DIR]', 'set the installation prefix for `cake install`'
|
||||||
|
|
||||||
task 'install', 'install CoffeeScript into /usr/local (or --prefix)', (options) ->
|
task 'install', 'install CoffeeScript into /usr/local (or --prefix)', (options) ->
|
||||||
base = options.prefix or '/usr/local'
|
base = options.prefix or '/usr/local'
|
||||||
lib = "#base/lib/coffee-script"
|
lib = "#{base}/lib/coffee-script"
|
||||||
bin = "#base/bin"
|
bin = "#{base}/bin"
|
||||||
node = "~/.node_libraries/coffee-script"
|
node = "~/.node_libraries/coffee-script"
|
||||||
puts "Installing CoffeeScript to #lib"
|
puts "Installing CoffeeScript to #{lib}"
|
||||||
puts "Linking to #node"
|
puts "Linking to #{node}"
|
||||||
puts "Linking 'coffee' to #bin/coffee"
|
puts "Linking 'coffee' to #{bin}/coffee"
|
||||||
exec([
|
exec([
|
||||||
"mkdir -p #lib #bin"
|
"mkdir -p #{lib} #{bin}"
|
||||||
"cp -rf bin lib LICENSE README package.json src #lib"
|
"cp -rf bin lib LICENSE README package.json src #{lib}"
|
||||||
"ln -sf #lib/bin/coffee #bin/coffee"
|
"ln -sf #{lib}/bin/coffee #{bin}/coffee"
|
||||||
"ln -sf #lib/bin/cake #bin/cake"
|
"ln -sf #{lib}/bin/cake #{bin}/cake"
|
||||||
"mkdir -p ~/.node_libraries"
|
"mkdir -p ~/.node_libraries"
|
||||||
"ln -sf #lib/lib #node"
|
"ln -sf #{lib}/lib #{node}"
|
||||||
].join(' && '), (err, stdout, stderr) ->
|
].join(' && '), (err, stdout, stderr) ->
|
||||||
if err then print stderr else log 'done', green
|
if err then print stderr else log 'done', green
|
||||||
)
|
)
|
||||||
|
@ -103,9 +103,9 @@ task 'test', 'run the CoffeeScript language test suite', ->
|
||||||
}
|
}
|
||||||
process.on 'exit', ->
|
process.on 'exit', ->
|
||||||
time = ((new Date - startTime) / 1000).toFixed(2)
|
time = ((new Date - startTime) / 1000).toFixed(2)
|
||||||
message = "passed #passedTests tests in #time seconds#reset"
|
message = "passed #{passedTests} tests in #{time} seconds#{reset}"
|
||||||
if failedTests
|
if failedTests
|
||||||
log "failed #failedTests and #message", red
|
log "failed #{failedTests} and #{message}", red
|
||||||
else
|
else
|
||||||
log message, green
|
log message, green
|
||||||
fs.readdir 'test', (err, files) ->
|
fs.readdir 'test', (err, files) ->
|
||||||
|
@ -117,4 +117,4 @@ task 'test', 'run the CoffeeScript language test suite', ->
|
||||||
CoffeeScript.run code.toString(), {fileName}
|
CoffeeScript.run code.toString(), {fileName}
|
||||||
catch err
|
catch err
|
||||||
failedTests += 1
|
failedTests += 1
|
||||||
log "failed #fileName", red, '\n' + err.stack.toString()
|
log "failed #{fileName}", red, '\n' + err.stack.toString()
|
||||||
|
|
|
@ -6,4 +6,4 @@ task 'build:parser', 'rebuild the Jison parser', ->
|
||||||
require 'jison'
|
require 'jison'
|
||||||
code = require('./lib/grammar').parser.generate()
|
code = require('./lib/grammar').parser.generate()
|
||||||
dir = options.output or 'lib'
|
dir = options.output or 'lib'
|
||||||
fs.writeFile "#dir/parser.js", code
|
fs.writeFile "#{dir}/parser.js", code
|
|
@ -1,2 +1,2 @@
|
||||||
author = "Wittgenstein"
|
author = "Wittgenstein"
|
||||||
quote = "A picture is a fact. -- #author"
|
quote = "A picture is a fact. -- #{author}"
|
|
@ -1,6 +1,6 @@
|
||||||
sentence = "#{ 22 / 7 } is a decent approximation of π"
|
sentence = "#{ 22 / 7 } is a decent approximation of π"
|
||||||
|
|
||||||
sep = "[.\\/\\- ]"
|
sep = "[.\\/\\- ]"
|
||||||
dates = /\d+#sep\d+#sep\d+/g
|
dates = /\d+#{sep}\d+#{sep}\d+/g
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,15 +70,15 @@
|
||||||
}
|
}
|
||||||
return _b;
|
return _b;
|
||||||
})().join('') : '';
|
})().join('') : '';
|
||||||
desc = task.description ? ("# " + task.description) : '';
|
desc = task.description ? ("# " + (task.description)) : '';
|
||||||
puts("cake " + name + spaces + " " + desc);
|
puts(("cake " + (name) + (spaces) + " " + (desc)));
|
||||||
}
|
}
|
||||||
if (switches.length) {
|
if (switches.length) {
|
||||||
return puts(oparse.help());
|
return puts(oparse.help());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
missingTask = function(task) {
|
missingTask = function(task) {
|
||||||
puts("No such task: \"" + task + "\"");
|
puts(("No such task: \"" + (task) + "\""));
|
||||||
return process.exit(1);
|
return process.exit(1);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
return (parser.parse(lexer.tokenize(code))).compile(options);
|
return (parser.parse(lexer.tokenize(code))).compile(options);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (options.fileName) {
|
if (options.fileName) {
|
||||||
err.message = ("In " + options.fileName + ", " + err.message);
|
err.message = ("In " + (options.fileName) + ", " + (err.message));
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
compile = function(source, topLevel) {
|
compile = function(source, topLevel) {
|
||||||
return path.exists(source, function(exists) {
|
return path.exists(source, function(exists) {
|
||||||
if (!(exists)) {
|
if (!(exists)) {
|
||||||
throw new Error("File not found: " + source);
|
throw new Error(("File not found: " + (source)));
|
||||||
}
|
}
|
||||||
return fs.stat(source, function(err, stats) {
|
return fs.stat(source, function(err, stats) {
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
|
@ -155,12 +155,12 @@
|
||||||
}
|
}
|
||||||
return fs.writeFile(jsPath, js, function(err) {
|
return fs.writeFile(jsPath, js, function(err) {
|
||||||
if (options.compile && options.watch) {
|
if (options.compile && options.watch) {
|
||||||
return puts("Compiled " + source);
|
return puts(("Compiled " + (source)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return path.exists(dir, function(exists) {
|
return path.exists(dir, function(exists) {
|
||||||
return exists ? compile() : exec(("mkdir -p " + dir), compile);
|
return exists ? compile() : exec(("mkdir -p " + (dir)), compile);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
lint = function(js) {
|
lint = function(js) {
|
||||||
|
@ -184,7 +184,7 @@
|
||||||
_f = [token[0], token[1].toString().replace(/\n/, '\\n')];
|
_f = [token[0], token[1].toString().replace(/\n/, '\\n')];
|
||||||
tag = _f[0];
|
tag = _f[0];
|
||||||
value = _f[1];
|
value = _f[1];
|
||||||
return "[" + tag + " " + value + "]";
|
return "[" + (tag) + " " + (value) + "]";
|
||||||
})());
|
})());
|
||||||
}
|
}
|
||||||
return _b;
|
return _b;
|
||||||
|
@ -213,7 +213,7 @@
|
||||||
return process.exit(0);
|
return process.exit(0);
|
||||||
};
|
};
|
||||||
version = function() {
|
version = function() {
|
||||||
puts("CoffeeScript version " + CoffeeScript.VERSION);
|
puts(("CoffeeScript version " + (CoffeeScript.VERSION)));
|
||||||
return process.exit(0);
|
return process.exit(0);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
if (!(action)) {
|
if (!(action)) {
|
||||||
return [patternString, '$$ = $1;', options];
|
return [patternString, '$$ = $1;', options];
|
||||||
}
|
}
|
||||||
action = (match = (action + '').match(unwrap)) ? match[1] : ("(" + action + "())");
|
action = (match = (action + '').match(unwrap)) ? match[1] : ("(" + (action) + "())");
|
||||||
return [patternString, ("$$ = " + action + ";"), options];
|
return [patternString, ("$$ = " + (action) + ";"), options];
|
||||||
};
|
};
|
||||||
grammar = {
|
grammar = {
|
||||||
Root: [
|
Root: [
|
||||||
|
|
24
lib/lexer.js
24
lib/lexer.js
|
@ -89,7 +89,7 @@
|
||||||
if (include(JS_FORBIDDEN, id)) {
|
if (include(JS_FORBIDDEN, id)) {
|
||||||
if (forcedIdentifier) {
|
if (forcedIdentifier) {
|
||||||
tag = 'STRING';
|
tag = 'STRING';
|
||||||
id = ("\"" + id + "\"");
|
id = ("\"" + (id) + "\"");
|
||||||
if (forcedIdentifier === 'accessor') {
|
if (forcedIdentifier === 'accessor') {
|
||||||
close_index = true;
|
close_index = true;
|
||||||
if (this.tag() !== '@') {
|
if (this.tag() !== '@') {
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
doc = this.sanitizeHeredoc(match[2] || match[4], {
|
doc = this.sanitizeHeredoc(match[2] || match[4], {
|
||||||
quote: quote
|
quote: quote
|
||||||
});
|
});
|
||||||
this.interpolateString(("" + quote + doc + quote), {
|
this.interpolateString(quote + doc + quote, {
|
||||||
heredoc: true
|
heredoc: true
|
||||||
});
|
});
|
||||||
this.line += count(match[1], "\n");
|
this.line += count(match[1], "\n");
|
||||||
|
@ -204,11 +204,11 @@
|
||||||
return '\\' + escaped;
|
return '\\' + escaped;
|
||||||
});
|
});
|
||||||
this.tokens = this.tokens.concat([['(', '('], ['NEW', 'new'], ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']]);
|
this.tokens = this.tokens.concat([['(', '('], ['NEW', 'new'], ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']]);
|
||||||
this.interpolateString(("\"" + str + "\""), {
|
this.interpolateString(("\"" + (str) + "\""), {
|
||||||
escapeQuotes: true
|
escapeQuotes: true
|
||||||
});
|
});
|
||||||
if (flags) {
|
if (flags) {
|
||||||
this.tokens.splice(this.tokens.length, 0, [',', ','], ['STRING', ("\"" + flags + "\"")]);
|
this.tokens.splice(this.tokens.length, 0, [',', ','], ['STRING', ("\"" + (flags) + "\"")]);
|
||||||
}
|
}
|
||||||
this.tokens.splice(this.tokens.length, 0, [')', ')'], [')', ')']);
|
this.tokens.splice(this.tokens.length, 0, [')', ')'], [')', ')']);
|
||||||
} else {
|
} else {
|
||||||
|
@ -377,7 +377,7 @@
|
||||||
if (options.herecomment) {
|
if (options.herecomment) {
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
return doc.replace(MULTILINER, "\\n").replace(new RegExp(options.quote, 'g'), ("\\" + options.quote));
|
return doc.replace(MULTILINER, "\\n").replace(new RegExp(options.quote, 'g'), ("\\" + (options.quote)));
|
||||||
};
|
};
|
||||||
Lexer.prototype.tagParameters = function() {
|
Lexer.prototype.tagParameters = function() {
|
||||||
var _d, i, tok;
|
var _d, i, tok;
|
||||||
|
@ -405,7 +405,7 @@
|
||||||
return this.outdentToken(this.indent);
|
return this.outdentToken(this.indent);
|
||||||
};
|
};
|
||||||
Lexer.prototype.identifierError = function(word) {
|
Lexer.prototype.identifierError = function(word) {
|
||||||
throw new Error(("SyntaxError: Reserved word \"" + word + "\" on line " + (this.line + 1)));
|
throw new Error(("SyntaxError: Reserved word \"" + (word) + "\" on line " + (this.line + 1)));
|
||||||
};
|
};
|
||||||
Lexer.prototype.assignmentError = function() {
|
Lexer.prototype.assignmentError = function() {
|
||||||
throw new Error(("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned"));
|
throw new Error(("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned"));
|
||||||
|
@ -476,21 +476,21 @@
|
||||||
interp = ("this." + (interp.substring(1)));
|
interp = ("this." + (interp.substring(1)));
|
||||||
}
|
}
|
||||||
if (pi < i) {
|
if (pi < i) {
|
||||||
tokens.push(['STRING', ("" + quote + (str.substring(pi, i)) + quote)]);
|
tokens.push(['STRING', quote + str.substring(pi, i) + quote]);
|
||||||
}
|
}
|
||||||
tokens.push(['IDENTIFIER', interp]);
|
tokens.push(['IDENTIFIER', interp]);
|
||||||
i += group.length - 1;
|
i += group.length - 1;
|
||||||
pi = i + 1;
|
pi = i + 1;
|
||||||
} else if ((expr = this.balancedString(str.substring(i), [['#{', '}']]))) {
|
} else if ((expr = this.balancedString(str.substring(i), [['#{', '}']]))) {
|
||||||
if (pi < i) {
|
if (pi < i) {
|
||||||
tokens.push(['STRING', ("" + quote + (str.substring(pi, i)) + quote)]);
|
tokens.push(['STRING', quote + str.substring(pi, i) + quote]);
|
||||||
}
|
}
|
||||||
inner = expr.substring(2, expr.length - 1);
|
inner = expr.substring(2, expr.length - 1);
|
||||||
if (inner.length) {
|
if (inner.length) {
|
||||||
if (options.heredoc) {
|
if (options.heredoc) {
|
||||||
inner = inner.replace(new RegExp('\\\\' + quote, 'g'), quote);
|
inner = inner.replace(new RegExp('\\\\' + quote, 'g'), quote);
|
||||||
}
|
}
|
||||||
nested = lexer.tokenize(("(" + inner + ")"), {
|
nested = lexer.tokenize(("(" + (inner) + ")"), {
|
||||||
line: this.line
|
line: this.line
|
||||||
});
|
});
|
||||||
_f = nested;
|
_f = nested;
|
||||||
|
@ -501,7 +501,7 @@
|
||||||
nested.pop();
|
nested.pop();
|
||||||
tokens.push(['TOKENS', nested]);
|
tokens.push(['TOKENS', nested]);
|
||||||
} else {
|
} else {
|
||||||
tokens.push(['STRING', ("" + quote + quote)]);
|
tokens.push(['STRING', quote + quote]);
|
||||||
}
|
}
|
||||||
i += expr.length - 1;
|
i += expr.length - 1;
|
||||||
pi = i + 1;
|
pi = i + 1;
|
||||||
|
@ -509,7 +509,7 @@
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
if (pi < i && pi < str.length - 1) {
|
if (pi < i && pi < str.length - 1) {
|
||||||
tokens.push(['STRING', ("" + quote + (str.substring(pi, i)) + quote)]);
|
tokens.push(['STRING', quote + str.substring(pi, i) + quote]);
|
||||||
}
|
}
|
||||||
if (!(tokens[0][0] === 'STRING')) {
|
if (!(tokens[0][0] === 'STRING')) {
|
||||||
tokens.unshift(['STRING', '""']);
|
tokens.unshift(['STRING', '""']);
|
||||||
|
@ -528,7 +528,7 @@
|
||||||
this.tokens = this.tokens.concat(value);
|
this.tokens = this.tokens.concat(value);
|
||||||
} else if (tag === 'STRING' && options.escapeQuotes) {
|
} else if (tag === 'STRING' && options.escapeQuotes) {
|
||||||
escaped = value.substring(1, value.length - 1).replace(/"/g, '\\"');
|
escaped = value.substring(1, value.length - 1).replace(/"/g, '\\"');
|
||||||
this.token(tag, ("\"" + escaped + "\""));
|
this.token(tag, ("\"" + (escaped) + "\""));
|
||||||
} else {
|
} else {
|
||||||
this.token(tag, value);
|
this.token(tag, value);
|
||||||
}
|
}
|
||||||
|
|
186
lib/nodes.js
186
lib/nodes.js
|
@ -228,16 +228,16 @@
|
||||||
code = this.compileWithDeclarations(o);
|
code = this.compileWithDeclarations(o);
|
||||||
code = code.replace(TRAILING_WHITESPACE, '');
|
code = code.replace(TRAILING_WHITESPACE, '');
|
||||||
code = code.replace(DOUBLE_PARENS, '($1)');
|
code = code.replace(DOUBLE_PARENS, '($1)');
|
||||||
return o.noWrap ? code : ("(function() {\n" + code + "\n})();\n");
|
return o.noWrap ? code : ("(function() {\n" + (code) + "\n})();\n");
|
||||||
};
|
};
|
||||||
Expressions.prototype.compileWithDeclarations = function(o) {
|
Expressions.prototype.compileWithDeclarations = function(o) {
|
||||||
var code;
|
var code;
|
||||||
code = this.compileNode(o);
|
code = this.compileNode(o);
|
||||||
if (o.scope.hasAssignments(this)) {
|
if (o.scope.hasAssignments(this)) {
|
||||||
code = ("" + (this.tab) + "var " + (o.scope.compiledAssignments()) + ";\n" + code);
|
code = ("" + (this.tab) + "var " + (o.scope.compiledAssignments()) + ";\n" + (code));
|
||||||
}
|
}
|
||||||
if (!o.globals && o.scope.hasDeclarations(this)) {
|
if (!o.globals && o.scope.hasDeclarations(this)) {
|
||||||
code = ("" + (this.tab) + "var " + (o.scope.compiledDeclarations()) + ";\n" + code);
|
code = ("" + (this.tab) + "var " + (o.scope.compiledDeclarations()) + ";\n" + (code));
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
|
@ -247,7 +247,7 @@
|
||||||
compiledNode = node.compile(merge(o, {
|
compiledNode = node.compile(merge(o, {
|
||||||
top: true
|
top: true
|
||||||
}));
|
}));
|
||||||
return node.isStatement() ? compiledNode : ("" + (this.idt()) + compiledNode + ";");
|
return node.isStatement() ? compiledNode : ("" + (this.idt()) + (compiledNode) + ";");
|
||||||
};
|
};
|
||||||
return Expressions;
|
return Expressions;
|
||||||
})();
|
})();
|
||||||
|
@ -275,10 +275,10 @@
|
||||||
var end, idt;
|
var end, idt;
|
||||||
idt = this.isStatement() ? this.idt() : '';
|
idt = this.isStatement() ? this.idt() : '';
|
||||||
end = this.isStatement() ? ';' : '';
|
end = this.isStatement() ? ';' : '';
|
||||||
return "" + idt + this.value + end;
|
return idt + this.value + end;
|
||||||
};
|
};
|
||||||
LiteralNode.prototype.toString = function(idt) {
|
LiteralNode.prototype.toString = function(idt) {
|
||||||
return " \"" + this.value + "\"";
|
return '"' + this.value + '"';
|
||||||
};
|
};
|
||||||
return LiteralNode;
|
return LiteralNode;
|
||||||
})();
|
})();
|
||||||
|
@ -398,7 +398,7 @@
|
||||||
o.chainRoot = o.chainRoot || this;
|
o.chainRoot = o.chainRoot || this;
|
||||||
baseline = this.base.compile(o);
|
baseline = this.base.compile(o);
|
||||||
if (this.hasProperties() && (this.base instanceof ObjectNode || this.isNumber())) {
|
if (this.hasProperties() && (this.base instanceof ObjectNode || this.isNumber())) {
|
||||||
baseline = ("(" + baseline + ")");
|
baseline = ("(" + (baseline) + ")");
|
||||||
}
|
}
|
||||||
complete = (this.last = baseline);
|
complete = (this.last = baseline);
|
||||||
_c = props;
|
_c = props;
|
||||||
|
@ -413,10 +413,10 @@
|
||||||
return n instanceof CallNode;
|
return n instanceof CallNode;
|
||||||
}) && i === 0) {
|
}) && i === 0) {
|
||||||
temp = o.scope.freeVariable();
|
temp = o.scope.freeVariable();
|
||||||
complete = ("(" + (baseline = temp) + " = (" + complete + "))");
|
complete = ("(" + (baseline = temp) + " = (" + (complete) + "))");
|
||||||
}
|
}
|
||||||
if (i === 0 && this.isStart(o)) {
|
if (i === 0 && this.isStart(o)) {
|
||||||
complete = ("typeof " + complete + " === \"undefined\" || " + baseline);
|
complete = ("typeof " + (complete) + " === \"undefined\" || " + (baseline));
|
||||||
}
|
}
|
||||||
return complete += this.SOAK + (baseline += prop.compile(o));
|
return complete += this.SOAK + (baseline += prop.compile(o));
|
||||||
} else {
|
} else {
|
||||||
|
@ -427,7 +427,7 @@
|
||||||
}
|
}
|
||||||
}).call(this);
|
}).call(this);
|
||||||
}
|
}
|
||||||
return op && this.wrapped ? ("(" + complete + ")") : complete;
|
return op && this.wrapped ? ("(" + (complete) + ")") : complete;
|
||||||
};
|
};
|
||||||
return ValueNode;
|
return ValueNode;
|
||||||
})();
|
})();
|
||||||
|
@ -446,8 +446,8 @@
|
||||||
};
|
};
|
||||||
CommentNode.prototype.compileNode = function(o) {
|
CommentNode.prototype.compileNode = function(o) {
|
||||||
var sep;
|
var sep;
|
||||||
sep = ("\n" + this.tab);
|
sep = '\n' + this.tab;
|
||||||
return "" + this.tab + "/*" + sep + (this.lines.join(sep)) + "\n" + this.tab + "*/";
|
return "" + (this.tab) + "/*#" + (sep + this.lines.join(sep)) + "\n" + (this.tab) + "*/";
|
||||||
};
|
};
|
||||||
return CommentNode;
|
return CommentNode;
|
||||||
})();
|
})();
|
||||||
|
@ -478,7 +478,7 @@
|
||||||
methname = o.scope.method.name;
|
methname = o.scope.method.name;
|
||||||
return (meth = (function() {
|
return (meth = (function() {
|
||||||
if (o.scope.method.proto) {
|
if (o.scope.method.proto) {
|
||||||
return "" + (o.scope.method.proto) + ".__superClass__." + methname;
|
return "" + (o.scope.method.proto) + ".__superClass__." + (methname);
|
||||||
} else if (methname) {
|
} else if (methname) {
|
||||||
return "" + (methname) + ".__superClass__.constructor";
|
return "" + (methname) + ".__superClass__.constructor";
|
||||||
} else {
|
} else {
|
||||||
|
@ -505,12 +505,12 @@
|
||||||
}
|
}
|
||||||
return _e;
|
return _e;
|
||||||
}).call(this).join(', ');
|
}).call(this).join(', ');
|
||||||
compilation = this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + args + ")");
|
compilation = this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + (args) + ")");
|
||||||
}
|
}
|
||||||
return o.operation && this.wrapped ? ("(" + compilation + ")") : compilation;
|
return o.operation && this.wrapped ? ("(" + (compilation) + ")") : compilation;
|
||||||
};
|
};
|
||||||
CallNode.prototype.compileSuper = function(args, o) {
|
CallNode.prototype.compileSuper = function(args, o) {
|
||||||
return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + args + ")";
|
return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + (args) + ")";
|
||||||
};
|
};
|
||||||
CallNode.prototype.compileSplat = function(o) {
|
CallNode.prototype.compileSplat = function(o) {
|
||||||
var meth, obj, temp;
|
var meth, obj, temp;
|
||||||
|
@ -519,13 +519,13 @@
|
||||||
if (obj.match(/\(/)) {
|
if (obj.match(/\(/)) {
|
||||||
temp = o.scope.freeVariable();
|
temp = o.scope.freeVariable();
|
||||||
obj = temp;
|
obj = temp;
|
||||||
meth = ("(" + temp + " = " + (this.variable.source) + ")" + (this.variable.last));
|
meth = ("(" + (temp) + " = " + (this.variable.source) + ")" + (this.variable.last));
|
||||||
}
|
}
|
||||||
if (this.isNew) {
|
if (this.isNew) {
|
||||||
utility('extends');
|
utility('extends');
|
||||||
return "(function() {\n" + (this.idt(1)) + "var ctor = function(){};\n" + (this.idt(1)) + "__extends(ctor, " + meth + ");\n" + (this.idt(1)) + "return " + (meth) + ".apply(new ctor, " + (this.compileSplatArguments(o)) + ");\n" + this.tab + "}).call(this)";
|
return "(function() {\n" + (this.idt(1)) + "var ctor = function(){};\n" + (this.idt(1)) + "__extends(ctor, " + (meth) + ");\n" + (this.idt(1)) + "return " + (meth) + ".apply(new ctor, " + (this.compileSplatArguments(o)) + ");\n" + (this.tab) + "}).call(this)";
|
||||||
} else {
|
} else {
|
||||||
return "" + (this.prefix()) + (meth) + ".apply(" + obj + ", " + (this.compileSplatArguments(o)) + ")";
|
return "" + (this.prefix()) + (meth) + ".apply(" + (obj) + ", " + (this.compileSplatArguments(o)) + ")";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return CallNode;
|
return CallNode;
|
||||||
|
@ -560,7 +560,7 @@
|
||||||
var name, namePart;
|
var name, namePart;
|
||||||
name = this.name.compile(o);
|
name = this.name.compile(o);
|
||||||
o.chainRoot.wrapped = o.chainRoot.wrapped || this.soakNode;
|
o.chainRoot.wrapped = o.chainRoot.wrapped || this.soakNode;
|
||||||
namePart = name.match(IS_STRING) ? ("[" + name + "]") : ("." + name);
|
namePart = name.match(IS_STRING) ? ("[" + (name) + "]") : ("." + (name));
|
||||||
return this.prototype + namePart;
|
return this.prototype + namePart;
|
||||||
};
|
};
|
||||||
return AccessorNode;
|
return AccessorNode;
|
||||||
|
@ -578,7 +578,7 @@
|
||||||
o.chainRoot.wrapped = o.chainRoot.wrapped || this.soakNode;
|
o.chainRoot.wrapped = o.chainRoot.wrapped || this.soakNode;
|
||||||
idx = this.index.compile(o);
|
idx = this.index.compile(o);
|
||||||
prefix = this.proto ? '.prototype' : '';
|
prefix = this.proto ? '.prototype' : '';
|
||||||
return "" + prefix + "[" + idx + "]";
|
return "" + (prefix) + "[" + (idx) + "]";
|
||||||
};
|
};
|
||||||
return IndexNode;
|
return IndexNode;
|
||||||
})();
|
})();
|
||||||
|
@ -630,12 +630,12 @@
|
||||||
}
|
}
|
||||||
idx = del(o, 'index');
|
idx = del(o, 'index');
|
||||||
step = del(o, 'step');
|
step = del(o, 'step');
|
||||||
vars = ("" + idx + " = " + this.fromVar);
|
vars = ("" + (idx) + " = " + (this.fromVar));
|
||||||
intro = ("(" + this.fromVar + " <= " + this.toVar + " ? " + idx);
|
intro = ("(" + (this.fromVar) + " <= " + (this.toVar) + " ? " + (idx));
|
||||||
compare = ("" + intro + " <" + this.equals + " " + this.toVar + " : " + idx + " >" + this.equals + " " + this.toVar + ")");
|
compare = ("" + (intro) + " <" + (this.equals) + " " + (this.toVar) + " : " + (idx) + " >" + (this.equals) + " " + (this.toVar) + ")");
|
||||||
stepPart = step ? step.compile(o) : '1';
|
stepPart = step ? step.compile(o) : '1';
|
||||||
incr = step ? ("" + idx + " += " + stepPart) : ("" + intro + " += " + stepPart + " : " + idx + " -= " + stepPart + ")");
|
incr = step ? ("" + (idx) + " += " + (stepPart)) : ("" + (intro) + " += " + (stepPart) + " : " + (idx) + " -= " + (stepPart) + ")");
|
||||||
return "" + vars + "; " + compare + "; " + incr;
|
return "" + (vars) + "; " + (compare) + "; " + (incr);
|
||||||
};
|
};
|
||||||
RangeNode.prototype.compileSimple = function(o) {
|
RangeNode.prototype.compileSimple = function(o) {
|
||||||
var _b, from, idx, step, to;
|
var _b, from, idx, step, to;
|
||||||
|
@ -644,8 +644,8 @@
|
||||||
to = _b[1];
|
to = _b[1];
|
||||||
idx = del(o, 'index');
|
idx = del(o, 'index');
|
||||||
step = del(o, 'step');
|
step = del(o, 'step');
|
||||||
step = step && ("" + idx + " += " + (step.compile(o)));
|
step = step && ("" + (idx) + " += " + (step.compile(o)));
|
||||||
return from <= to ? ("" + idx + " = " + from + "; " + idx + " <" + this.equals + " " + to + "; " + (step || ("" + idx + "++"))) : ("" + idx + " = " + from + "; " + idx + " >" + this.equals + " " + to + "; " + (step || ("" + idx + "--")));
|
return from <= to ? ("" + (idx) + " = " + (from) + "; " + (idx) + " <" + (this.equals) + " " + (to) + "; " + (step || ("" + (idx) + "++"))) : ("" + (idx) + " = " + (from) + "; " + (idx) + " >" + (this.equals) + " " + (to) + "; " + (step || ("" + (idx) + "--")));
|
||||||
};
|
};
|
||||||
RangeNode.prototype.compileArray = function(o) {
|
RangeNode.prototype.compileArray = function(o) {
|
||||||
var _b, _c, body, clause, i, idt, post, pre, range, result, vars;
|
var _b, _c, body, clause, i, idt, post, pre, range, result, vars;
|
||||||
|
@ -671,11 +671,11 @@
|
||||||
o.index = i;
|
o.index = i;
|
||||||
body = this.compileSimple(o);
|
body = this.compileSimple(o);
|
||||||
} else {
|
} else {
|
||||||
clause = ("" + this.fromVar + " <= " + this.toVar + " ?");
|
clause = ("" + (this.fromVar) + " <= " + (this.toVar) + " ?");
|
||||||
body = ("var " + i + " = " + this.fromVar + "; " + clause + " " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + clause + " " + i + " += 1 : " + i + " -= 1");
|
body = ("var " + (i) + " = " + (this.fromVar) + "; " + (clause) + " " + (i) + " <" + (this.equals) + " " + (this.toVar) + " : " + (i) + " >" + (this.equals) + " " + (this.toVar) + "; " + (clause) + " " + (i) + " += 1 : " + (i) + " -= 1");
|
||||||
}
|
}
|
||||||
post = ("{ " + (result) + ".push(" + i + "); }\n" + (idt) + "return " + result + ";\n" + o.indent);
|
post = ("{ " + (result) + ".push(" + (i) + "); }\n" + (idt) + "return " + (result) + ";\n" + (o.indent));
|
||||||
return "(function() {" + (pre) + "\n" + (idt) + "for (" + body + ")" + post + "}).call(this)";
|
return "(function() {" + (pre) + "\n" + (idt) + "for (" + (body) + ")" + (post) + "}).call(this)";
|
||||||
};
|
};
|
||||||
return RangeNode;
|
return RangeNode;
|
||||||
})();
|
})();
|
||||||
|
@ -692,7 +692,7 @@
|
||||||
from = this.range.from.compile(o);
|
from = this.range.from.compile(o);
|
||||||
to = this.range.to.compile(o);
|
to = this.range.to.compile(o);
|
||||||
plusPart = this.range.exclusive ? '' : ' + 1';
|
plusPart = this.range.exclusive ? '' : ' + 1';
|
||||||
return ".slice(" + from + ", " + to + plusPart + ")";
|
return ".slice(" + (from) + ", " + (to) + (plusPart) + ")";
|
||||||
};
|
};
|
||||||
return SliceNode;
|
return SliceNode;
|
||||||
})();
|
})();
|
||||||
|
@ -739,7 +739,7 @@
|
||||||
}).call(this);
|
}).call(this);
|
||||||
props = props.join('');
|
props = props.join('');
|
||||||
inner = props ? '\n' + props + '\n' + this.idt() : '';
|
inner = props ? '\n' + props + '\n' + this.idt() : '';
|
||||||
return "{" + inner + "}";
|
return '{' + inner + '}';
|
||||||
};
|
};
|
||||||
return ObjectNode;
|
return ObjectNode;
|
||||||
})();
|
})();
|
||||||
|
@ -766,15 +766,15 @@
|
||||||
if (obj instanceof SplatNode) {
|
if (obj instanceof SplatNode) {
|
||||||
return this.compileSplatLiteral(o);
|
return this.compileSplatLiteral(o);
|
||||||
} else if (obj instanceof CommentNode) {
|
} else if (obj instanceof CommentNode) {
|
||||||
objects.push("\n" + code + "\n" + o.indent);
|
objects.push(("\n" + (code) + "\n" + (o.indent)));
|
||||||
} else if (i === this.objects.length - 1) {
|
} else if (i === this.objects.length - 1) {
|
||||||
objects.push(code);
|
objects.push(code);
|
||||||
} else {
|
} else {
|
||||||
objects.push("" + code + ", ");
|
objects.push(("" + (code) + ", "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
objects = objects.join('');
|
objects = objects.join('');
|
||||||
return indexOf(objects, '\n') >= 0 ? ("[\n" + (this.idt(1)) + objects + "\n" + this.tab + "]") : ("[" + objects + "]");
|
return indexOf(objects, '\n') >= 0 ? ("[\n" + (this.idt(1)) + (objects) + "\n" + (this.tab) + "]") : ("[" + (objects) + "]");
|
||||||
};
|
};
|
||||||
return ArrayNode;
|
return ArrayNode;
|
||||||
})();
|
})();
|
||||||
|
@ -839,7 +839,7 @@
|
||||||
if (constructor.body.empty()) {
|
if (constructor.body.empty()) {
|
||||||
constructor.body.push(new ReturnNode(literal('this')));
|
constructor.body.push(new ReturnNode(literal('this')));
|
||||||
}
|
}
|
||||||
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); }")));
|
||||||
}
|
}
|
||||||
if (pvar) {
|
if (pvar) {
|
||||||
access = prop.context === 'this' ? pvar.base.properties[0] : new AccessorNode(pvar, 'prototype');
|
access = prop.context === 'this' ? pvar.base.properties[0] : new AccessorNode(pvar, 'prototype');
|
||||||
|
@ -849,7 +849,7 @@
|
||||||
props.push(prop);
|
props.push(prop);
|
||||||
}
|
}
|
||||||
if (me) {
|
if (me) {
|
||||||
constructor.body.unshift(literal("" + me + " = this"));
|
constructor.body.unshift(literal(("" + (me) + " = this")));
|
||||||
}
|
}
|
||||||
construct = this.idt() + (new AssignNode(this.variable, constructor)).compile(merge(o, {
|
construct = this.idt() + (new AssignNode(this.variable, constructor)).compile(merge(o, {
|
||||||
sharedScope: constScope
|
sharedScope: constScope
|
||||||
|
@ -857,7 +857,7 @@
|
||||||
props = !props.empty() ? '\n' + props.compile(o) : '';
|
props = !props.empty() ? '\n' + props.compile(o) : '';
|
||||||
extension = extension ? '\n' + this.idt() + extension.compile(o) + ';' : '';
|
extension = extension ? '\n' + this.idt() + extension.compile(o) + ';' : '';
|
||||||
returns = this.returns ? '\n' + new ReturnNode(this.variable).compile(o) : '';
|
returns = this.returns ? '\n' + new ReturnNode(this.variable).compile(o) : '';
|
||||||
return "" + construct + extension + props + returns;
|
return construct + extension + props + returns;
|
||||||
};
|
};
|
||||||
return ClassNode;
|
return ClassNode;
|
||||||
})();
|
})();
|
||||||
|
@ -913,22 +913,22 @@
|
||||||
}
|
}
|
||||||
val = this.value.compile(o);
|
val = this.value.compile(o);
|
||||||
if (this.context === 'object') {
|
if (this.context === 'object') {
|
||||||
return ("" + name + ": " + val);
|
return ("" + (name) + ": " + (val));
|
||||||
}
|
}
|
||||||
if (!(this.isValue() && (this.variable.hasProperties() || this.variable.namespaced))) {
|
if (!(this.isValue() && (this.variable.hasProperties() || this.variable.namespaced))) {
|
||||||
o.scope.find(name);
|
o.scope.find(name);
|
||||||
}
|
}
|
||||||
val = ("" + name + " = " + val);
|
val = ("" + (name) + " = " + (val));
|
||||||
if (stmt) {
|
if (stmt) {
|
||||||
return ("" + this.tab + val + ";");
|
return ("" + (this.tab) + (val) + ";");
|
||||||
}
|
}
|
||||||
return top ? val : ("(" + val + ")");
|
return top ? val : ("(" + (val) + ")");
|
||||||
};
|
};
|
||||||
AssignNode.prototype.compilePatternMatch = function(o) {
|
AssignNode.prototype.compilePatternMatch = function(o) {
|
||||||
var _b, _c, _d, accessClass, assigns, code, i, idx, isString, obj, oindex, olength, splat, val, valVar, value;
|
var _b, _c, _d, accessClass, assigns, code, i, idx, isString, obj, oindex, olength, splat, val, valVar, value;
|
||||||
valVar = o.scope.freeVariable();
|
valVar = o.scope.freeVariable();
|
||||||
value = this.value.isStatement() ? ClosureNode.wrap(this.value) : this.value;
|
value = this.value.isStatement() ? ClosureNode.wrap(this.value) : this.value;
|
||||||
assigns = [("" + this.tab + valVar + " = " + (value.compile(o)) + ";")];
|
assigns = [("" + (this.tab) + (valVar) + " = " + (value.compile(o)) + ";")];
|
||||||
o.top = true;
|
o.top = true;
|
||||||
o.asStatement = true;
|
o.asStatement = true;
|
||||||
splat = false;
|
splat = false;
|
||||||
|
@ -975,7 +975,7 @@
|
||||||
from = range.from.compile(o);
|
from = range.from.compile(o);
|
||||||
to = range.to.compile(o) + ' - ' + from + plus;
|
to = range.to.compile(o) + ' - ' + from + plus;
|
||||||
val = this.value.compile(o);
|
val = this.value.compile(o);
|
||||||
return "" + (name) + ".splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + val + "))";
|
return "" + (name) + ".splice.apply(" + (name) + ", [" + (from) + ", " + (to) + "].concat(" + (val) + "))";
|
||||||
};
|
};
|
||||||
return AssignNode;
|
return AssignNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1049,11 +1049,11 @@
|
||||||
(o.scope.parameter(param));
|
(o.scope.parameter(param));
|
||||||
}
|
}
|
||||||
code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : '';
|
code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : '';
|
||||||
func = ("function(" + (params.join(', ')) + ") {" + code + (code && this.tab) + "}");
|
func = ("function(" + (params.join(', ')) + ") {" + (code) + (code && this.tab) + "}");
|
||||||
if (this.bound) {
|
if (this.bound) {
|
||||||
return ("" + (utility('bind')) + "(" + func + ", this)");
|
return ("" + (utility('bind')) + "(" + (func) + ", this)");
|
||||||
}
|
}
|
||||||
return top ? ("(" + func + ")") : func;
|
return top ? ("(" + (func) + ")") : func;
|
||||||
};
|
};
|
||||||
CodeNode.prototype.topSensitive = function() {
|
CodeNode.prototype.topSensitive = function() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1074,7 +1074,7 @@
|
||||||
}
|
}
|
||||||
return _b;
|
return _b;
|
||||||
}).call(this).join('');
|
}).call(this).join('');
|
||||||
return "\n" + idt + children;
|
return '\n' + idt + children;
|
||||||
};
|
};
|
||||||
return CodeNode;
|
return CodeNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1093,7 +1093,7 @@
|
||||||
return this.value.compile(o);
|
return this.value.compile(o);
|
||||||
};
|
};
|
||||||
ParamNode.prototype.toString = function(idt) {
|
ParamNode.prototype.toString = function(idt) {
|
||||||
return this.attach ? (literal("@" + this.name)).toString(idt) : this.value.toString(idt);
|
return this.attach ? (literal('@' + this.name)).toString(idt) : this.value.toString(idt);
|
||||||
};
|
};
|
||||||
return ParamNode;
|
return ParamNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1121,8 +1121,8 @@
|
||||||
len = o.scope.freeVariable();
|
len = o.scope.freeVariable();
|
||||||
o.scope.assign(len, "arguments.length");
|
o.scope.assign(len, "arguments.length");
|
||||||
variadic = o.scope.freeVariable();
|
variadic = o.scope.freeVariable();
|
||||||
o.scope.assign(variadic, ("" + len + " >= " + this.arglength));
|
o.scope.assign(variadic, len + ' >= ' + this.arglength);
|
||||||
end = this.trailings.length ? (", " + len + " - " + (this.trailings.length)) : null;
|
end = this.trailings.length ? (", " + (len) + " - " + (this.trailings.length)) : null;
|
||||||
_b = this.trailings;
|
_b = this.trailings;
|
||||||
for (idx = 0, _c = _b.length; idx < _c; idx++) {
|
for (idx = 0, _c = _b.length; idx < _c; idx++) {
|
||||||
trailing = _b[idx];
|
trailing = _b[idx];
|
||||||
|
@ -1132,15 +1132,15 @@
|
||||||
assign.value = trailing;
|
assign.value = trailing;
|
||||||
}
|
}
|
||||||
pos = this.trailings.length - idx;
|
pos = this.trailings.length - idx;
|
||||||
o.scope.assign(trailing.compile(o), ("arguments[" + variadic + " ? " + len + " - " + pos + " : " + (this.index + idx) + "]"));
|
o.scope.assign(trailing.compile(o), ("arguments[" + (variadic) + " ? " + (len) + " - " + (pos) + " : " + (this.index + idx) + "]"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "" + name + " = " + (utility('slice')) + ".call(arguments, " + this.index + end + ")";
|
return "" + (name) + " = " + (utility('slice')) + ".call(arguments, " + (this.index) + (end) + ")";
|
||||||
};
|
};
|
||||||
SplatNode.prototype.compileValue = function(o, name, index, trailings) {
|
SplatNode.prototype.compileValue = function(o, name, index, trailings) {
|
||||||
var trail;
|
var trail;
|
||||||
trail = trailings ? (", " + (name) + ".length - " + trailings) : '';
|
trail = trailings ? (", " + (name) + ".length - " + (trailings)) : '';
|
||||||
return "" + (utility('slice')) + ".call(" + name + ", " + index + trail + ")";
|
return "" + (utility('slice')) + ".call(" + (name) + ", " + (index) + (trail) + ")";
|
||||||
};
|
};
|
||||||
SplatNode.compileSplattedArray = function(list, o) {
|
SplatNode.compileSplattedArray = function(list, o) {
|
||||||
var _b, _c, arg, args, code, i, last, prev;
|
var _b, _c, arg, args, code, i, last, prev;
|
||||||
|
@ -1152,16 +1152,16 @@
|
||||||
prev = args[(last = args.length - 1)];
|
prev = args[(last = args.length - 1)];
|
||||||
if (!(arg instanceof SplatNode)) {
|
if (!(arg instanceof SplatNode)) {
|
||||||
if (prev && starts(prev, '[') && ends(prev, ']')) {
|
if (prev && starts(prev, '[') && ends(prev, ']')) {
|
||||||
args[last] = ("" + (prev.substr(0, prev.length - 1)) + ", " + code + "]");
|
args[last] = ("" + (prev.substr(0, prev.length - 1)) + ", " + (code) + "]");
|
||||||
continue;
|
continue;
|
||||||
} else if (prev && starts(prev, '.concat([') && ends(prev, '])')) {
|
} else if (prev && starts(prev, '.concat([') && ends(prev, '])')) {
|
||||||
args[last] = ("" + (prev.substr(0, prev.length - 2)) + ", " + code + "])");
|
args[last] = ("" + (prev.substr(0, prev.length - 2)) + ", " + (code) + "])");
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
code = ("[" + code + "]");
|
code = ("[" + (code) + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args.push(i === 0 ? code : (".concat(" + code + ")"));
|
args.push(i === 0 ? code : (".concat(" + (code) + ")"));
|
||||||
}
|
}
|
||||||
return args.join('');
|
return args.join('');
|
||||||
};
|
};
|
||||||
|
@ -1205,19 +1205,19 @@
|
||||||
set = '';
|
set = '';
|
||||||
if (!(top)) {
|
if (!(top)) {
|
||||||
rvar = o.scope.freeVariable();
|
rvar = o.scope.freeVariable();
|
||||||
set = ("" + this.tab + rvar + " = [];\n");
|
set = ("" + (this.tab) + (rvar) + " = [];\n");
|
||||||
if (this.body) {
|
if (this.body) {
|
||||||
this.body = PushNode.wrap(rvar, this.body);
|
this.body = PushNode.wrap(rvar, this.body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pre = ("" + set + (this.tab) + "while (" + cond + ")");
|
pre = ("" + (set) + (this.tab) + "while (" + (cond) + ")");
|
||||||
if (this.guard) {
|
if (this.guard) {
|
||||||
this.body = Expressions.wrap([new IfNode(this.guard, this.body)]);
|
this.body = Expressions.wrap([new IfNode(this.guard, this.body)]);
|
||||||
}
|
}
|
||||||
this.returns ? (post = '\n' + new ReturnNode(literal(rvar)).compile(merge(o, {
|
this.returns ? (post = '\n' + new ReturnNode(literal(rvar)).compile(merge(o, {
|
||||||
indent: this.idt()
|
indent: this.idt()
|
||||||
}))) : (post = '');
|
}))) : (post = '');
|
||||||
return "" + pre + " {\n" + (this.body.compile(o)) + "\n" + this.tab + "}" + post;
|
return "" + (pre) + " {\n" + (this.body.compile(o)) + "\n" + (this.tab) + "}" + (post);
|
||||||
};
|
};
|
||||||
return WhileNode;
|
return WhileNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1278,7 +1278,7 @@
|
||||||
first = _c[0];
|
first = _c[0];
|
||||||
second = _c[1];
|
second = _c[1];
|
||||||
shared = _c[2];
|
shared = _c[2];
|
||||||
return "(" + first + ") && (" + shared + " " + this.operator + " " + second + ")";
|
return "(" + (first) + ") && (" + (shared) + " " + (this.operator) + " " + (second) + ")";
|
||||||
};
|
};
|
||||||
OpNode.prototype.compileAssignment = function(o) {
|
OpNode.prototype.compileAssignment = function(o) {
|
||||||
var _b, first, firstVar, second;
|
var _b, first, firstVar, second;
|
||||||
|
@ -1293,9 +1293,9 @@
|
||||||
o.scope.find(first);
|
o.scope.find(first);
|
||||||
}
|
}
|
||||||
if (this.operator === '?=') {
|
if (this.operator === '?=') {
|
||||||
return ("" + first + " = " + (ExistenceNode.compileTest(o, literal(firstVar))) + " ? " + firstVar + " : " + second);
|
return ("" + (first) + " = " + (ExistenceNode.compileTest(o, literal(firstVar))) + " ? " + (firstVar) + " : " + (second));
|
||||||
}
|
}
|
||||||
return "" + first + " = " + firstVar + " " + (this.operator.substr(0, 2)) + " " + second;
|
return "" + (first) + " = " + (firstVar) + " " + (this.operator.substr(0, 2)) + " " + (second);
|
||||||
};
|
};
|
||||||
OpNode.prototype.compileExistence = function(o) {
|
OpNode.prototype.compileExistence = function(o) {
|
||||||
var _b, first, second, test;
|
var _b, first, second, test;
|
||||||
|
@ -1303,7 +1303,7 @@
|
||||||
first = _b[0];
|
first = _b[0];
|
||||||
second = _b[1];
|
second = _b[1];
|
||||||
test = ExistenceNode.compileTest(o, this.first);
|
test = ExistenceNode.compileTest(o, this.first);
|
||||||
return "" + test + " ? " + first + " : " + second;
|
return "" + (test) + " ? " + (first) + " : " + (second);
|
||||||
};
|
};
|
||||||
OpNode.prototype.compileUnary = function(o) {
|
OpNode.prototype.compileUnary = function(o) {
|
||||||
var parts, space;
|
var parts, space;
|
||||||
|
@ -1360,7 +1360,7 @@
|
||||||
i = _c[0];
|
i = _c[0];
|
||||||
l = _c[1];
|
l = _c[1];
|
||||||
prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : '';
|
prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : '';
|
||||||
return "(function(){ " + (prefix) + "for (var " + i + "=0, " + l + "=" + (this.arr1) + ".length; " + i + "<" + l + "; " + i + "++) { if (" + (this.arr2) + "[" + i + "] === " + this.obj2 + ") return true; } return false; }).call(this)";
|
return "(function(){ " + (prefix) + "for (var " + (i) + "=0, " + (l) + "=" + (this.arr1) + ".length; " + (i) + "<" + (l) + "; " + (i) + "++) { if (" + (this.arr2) + "[" + (i) + "] === " + (this.obj2) + ") return true; } return false; }).call(this)";
|
||||||
};
|
};
|
||||||
return InNode;
|
return InNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1393,9 +1393,9 @@
|
||||||
o.top = true;
|
o.top = true;
|
||||||
attemptPart = this.attempt.compile(o);
|
attemptPart = this.attempt.compile(o);
|
||||||
errorPart = this.error ? (" (" + (this.error.compile(o)) + ") ") : ' ';
|
errorPart = this.error ? (" (" + (this.error.compile(o)) + ") ") : ' ';
|
||||||
catchPart = this.recovery ? (" catch" + errorPart + "{\n" + (this.recovery.compile(o)) + "\n" + this.tab + "}") : '';
|
catchPart = this.recovery ? (" catch" + (errorPart) + "{\n" + (this.recovery.compile(o)) + "\n" + (this.tab) + "}") : '';
|
||||||
finallyPart = (this.ensure || '') && ' finally {\n' + this.ensure.compile(merge(o)) + ("\n" + this.tab + "}");
|
finallyPart = (this.ensure || '') && ' finally {\n' + this.ensure.compile(merge(o)) + ("\n" + (this.tab) + "}");
|
||||||
return "" + (this.tab) + "try {\n" + attemptPart + "\n" + this.tab + "}" + catchPart + finallyPart;
|
return "" + (this.tab) + "try {\n" + (attemptPart) + "\n" + (this.tab) + "}" + (catchPart) + (finallyPart);
|
||||||
};
|
};
|
||||||
return TryNode;
|
return TryNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1460,13 +1460,13 @@
|
||||||
top = del(o, 'top');
|
top = del(o, 'top');
|
||||||
code = this.expression.compile(o);
|
code = this.expression.compile(o);
|
||||||
if (this.isStatement()) {
|
if (this.isStatement()) {
|
||||||
return (top ? ("" + this.tab + code + ";") : code);
|
return (top ? this.tab + code + ';' : code);
|
||||||
}
|
}
|
||||||
l = code.length;
|
l = code.length;
|
||||||
if (code.substr(l - 1, 1) === ';') {
|
if (code.substr(l - 1, 1) === ';') {
|
||||||
code = code.substr(o, l - 1);
|
code = code.substr(o, l - 1);
|
||||||
}
|
}
|
||||||
return this.expression instanceof AssignNode ? code : ("(" + code + ")");
|
return this.expression instanceof AssignNode ? code : ("(" + (code) + ")");
|
||||||
};
|
};
|
||||||
return ParentheticalNode;
|
return ParentheticalNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1556,25 +1556,25 @@
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
svar = scope.freeVariable();
|
svar = scope.freeVariable();
|
||||||
sourcePart = ("" + svar + " = " + (this.source.compile(o)) + ";");
|
sourcePart = ("" + (svar) + " = " + (this.source.compile(o)) + ";");
|
||||||
if (this.pattern) {
|
if (this.pattern) {
|
||||||
namePart = new AssignNode(this.name, literal("" + svar + "[" + ivar + "]")).compile(merge(o, {
|
namePart = new AssignNode(this.name, literal(("" + (svar) + "[" + (ivar) + "]"))).compile(merge(o, {
|
||||||
indent: this.idt(1),
|
indent: this.idt(1),
|
||||||
top: true
|
top: true
|
||||||
})) + '\n';
|
})) + '\n';
|
||||||
} else {
|
} else {
|
||||||
if (name) {
|
if (name) {
|
||||||
namePart = ("" + name + " = " + svar + "[" + ivar + "]");
|
namePart = ("" + (name) + " = " + (svar) + "[" + (ivar) + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(this.object)) {
|
if (!(this.object)) {
|
||||||
lvar = scope.freeVariable();
|
lvar = scope.freeVariable();
|
||||||
stepPart = this.step ? ("" + ivar + " += " + (this.step.compile(o))) : ("" + ivar + "++");
|
stepPart = this.step ? ("" + (ivar) + " += " + (this.step.compile(o))) : ("" + (ivar) + "++");
|
||||||
forPart = ("" + ivar + " = 0, " + lvar + " = " + (svar) + ".length; " + ivar + " < " + lvar + "; " + stepPart);
|
forPart = ("" + (ivar) + " = 0, " + (lvar) + " = " + (svar) + ".length; " + (ivar) + " < " + (lvar) + "; " + (stepPart));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourcePart = (rvar ? ("" + rvar + " = []; ") : '') + sourcePart;
|
sourcePart = (rvar ? ("" + (rvar) + " = []; ") : '') + sourcePart;
|
||||||
sourcePart = sourcePart ? ("" + this.tab + sourcePart + "\n" + this.tab) : this.tab;
|
sourcePart = sourcePart ? ("" + (this.tab) + (sourcePart) + "\n" + (this.tab)) : this.tab;
|
||||||
returnResult = this.compileReturnValue(rvar, o);
|
returnResult = this.compileReturnValue(rvar, o);
|
||||||
if (!(topLevel)) {
|
if (!(topLevel)) {
|
||||||
body = PushNode.wrap(rvar, body);
|
body = PushNode.wrap(rvar, body);
|
||||||
|
@ -1582,27 +1582,27 @@
|
||||||
this.guard ? (body = Expressions.wrap([new IfNode(this.guard, body)])) : null;
|
this.guard ? (body = Expressions.wrap([new IfNode(this.guard, body)])) : null;
|
||||||
if (codeInBody) {
|
if (codeInBody) {
|
||||||
if (namePart) {
|
if (namePart) {
|
||||||
body.unshift(literal("var " + namePart));
|
body.unshift(literal(("var " + (namePart))));
|
||||||
}
|
}
|
||||||
if (index) {
|
if (index) {
|
||||||
body.unshift(literal("var " + index + " = " + ivar));
|
body.unshift(literal(("var " + (index) + " = " + (ivar))));
|
||||||
}
|
}
|
||||||
body = ClosureNode.wrap(body, true);
|
body = ClosureNode.wrap(body, true);
|
||||||
} else {
|
} else {
|
||||||
varPart = (namePart || '') && (this.pattern ? namePart : ("" + (this.idt(1)) + namePart + ";\n"));
|
varPart = (namePart || '') && (this.pattern ? namePart : ("" + (this.idt(1)) + (namePart) + ";\n"));
|
||||||
}
|
}
|
||||||
if (this.object) {
|
if (this.object) {
|
||||||
forPart = ("" + ivar + " in " + svar);
|
forPart = ("" + (ivar) + " in " + (svar));
|
||||||
if (!(this.raw)) {
|
if (!(this.raw)) {
|
||||||
guardPart = ("\n" + (this.idt(1)) + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")) continue;");
|
guardPart = ("\n" + (this.idt(1)) + "if (!" + (utility('hasProp')) + ".call(" + (svar) + ", " + (ivar) + ")) continue;");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body = body.compile(merge(o, {
|
body = body.compile(merge(o, {
|
||||||
indent: this.idt(1),
|
indent: this.idt(1),
|
||||||
top: true
|
top: true
|
||||||
}));
|
}));
|
||||||
vars = range ? name : ("" + name + ", " + ivar);
|
vars = range ? name : ("" + (name) + ", " + (ivar));
|
||||||
return "" + (sourcePart) + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + this.tab + "}" + returnResult;
|
return "" + (sourcePart) + "for (" + (forPart) + ") {" + (guardPart) + "\n" + (varPart) + (body) + "\n" + (this.tab) + "}" + (returnResult);
|
||||||
};
|
};
|
||||||
return ForNode;
|
return ForNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1713,22 +1713,22 @@
|
||||||
ifDent = child ? '' : this.idt();
|
ifDent = child ? '' : this.idt();
|
||||||
comDent = child ? this.idt() : '';
|
comDent = child ? this.idt() : '';
|
||||||
body = this.body.compile(o);
|
body = this.body.compile(o);
|
||||||
ifPart = ("" + (ifDent) + "if (" + (this.compileCondition(condO)) + ") {\n" + body + "\n" + this.tab + "}");
|
ifPart = ("" + (ifDent) + "if (" + (this.compileCondition(condO)) + ") {\n" + (body) + "\n" + (this.tab) + "}");
|
||||||
if (!(this.elseBody)) {
|
if (!(this.elseBody)) {
|
||||||
return ifPart;
|
return ifPart;
|
||||||
}
|
}
|
||||||
elsePart = this.isChain ? ' else ' + this.elseBodyNode().compile(merge(o, {
|
elsePart = this.isChain ? ' else ' + this.elseBodyNode().compile(merge(o, {
|
||||||
indent: this.idt(),
|
indent: this.idt(),
|
||||||
chainChild: true
|
chainChild: true
|
||||||
})) : (" else {\n" + (this.elseBody.compile(o)) + "\n" + this.tab + "}");
|
})) : (" else {\n" + (this.elseBody.compile(o)) + "\n" + (this.tab) + "}");
|
||||||
return "" + ifPart + elsePart;
|
return "" + (ifPart) + (elsePart);
|
||||||
};
|
};
|
||||||
IfNode.prototype.compileTernary = function(o) {
|
IfNode.prototype.compileTernary = function(o) {
|
||||||
var elsePart, ifPart;
|
var elsePart, ifPart;
|
||||||
o.operation = true;
|
o.operation = true;
|
||||||
ifPart = this.condition.compile(o) + ' ? ' + this.bodyNode().compile(o);
|
ifPart = this.condition.compile(o) + ' ? ' + this.bodyNode().compile(o);
|
||||||
elsePart = this.elseBody ? this.elseBodyNode().compile(o) : 'null';
|
elsePart = this.elseBody ? this.elseBodyNode().compile(o) : 'null';
|
||||||
return "" + ifPart + " : " + elsePart;
|
return "" + (ifPart) + " : " + (elsePart);
|
||||||
};
|
};
|
||||||
return IfNode;
|
return IfNode;
|
||||||
})();
|
})();
|
||||||
|
@ -1786,7 +1786,7 @@
|
||||||
};
|
};
|
||||||
utility = function(name) {
|
utility = function(name) {
|
||||||
var ref;
|
var ref;
|
||||||
ref = ("__" + name);
|
ref = ("__" + (name));
|
||||||
Scope.root.assign(ref, UTILITIES[name]);
|
Scope.root.assign(ref, UTILITIES[name]);
|
||||||
return ref;
|
return ref;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isOption && !matchedRule) {
|
if (isOption && !matchedRule) {
|
||||||
throw new Error("unrecognized option: " + arg);
|
throw new Error(("unrecognized option: " + (arg)));
|
||||||
}
|
}
|
||||||
if (!isOption) {
|
if (!isOption) {
|
||||||
options.arguments = args.slice(i, args.length);
|
options.arguments = args.slice(i, args.length);
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
var _a, _b, _c, _d, i, letPart, lines, rule, spaces;
|
var _a, _b, _c, _d, i, letPart, lines, rule, spaces;
|
||||||
lines = ['Available options:'];
|
lines = ['Available options:'];
|
||||||
if (this.banner) {
|
if (this.banner) {
|
||||||
lines.unshift("" + this.banner + "\n");
|
lines.unshift(("" + (this.banner) + "\n"));
|
||||||
}
|
}
|
||||||
_b = this.rules;
|
_b = this.rules;
|
||||||
for (_a = 0, _c = _b.length; _a < _c; _a++) {
|
for (_a = 0, _c = _b.length; _a < _c; _a++) {
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
return _d;
|
return _d;
|
||||||
})().join('') : '';
|
})().join('') : '';
|
||||||
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
|
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
|
||||||
lines.push(" " + letPart + rule.longFlag + spaces + rule.description);
|
lines.push(' ' + letPart + rule.longFlag + spaces + rule.description);
|
||||||
}
|
}
|
||||||
return "\n" + (lines.join('\n')) + "\n";
|
return "\n" + (lines.join('\n')) + "\n";
|
||||||
};
|
};
|
||||||
|
|
|
@ -313,7 +313,7 @@
|
||||||
if (unclosed.length) {
|
if (unclosed.length) {
|
||||||
open = unclosed[0];
|
open = unclosed[0];
|
||||||
line = openLine[open] + 1;
|
line = openLine[open] + 1;
|
||||||
throw new Error("unclosed " + open + " on line " + line);
|
throw new Error(("unclosed " + (open) + " on line " + (line)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Rewriter.prototype.rewriteClosingParens = function() {
|
Rewriter.prototype.rewriteClosingParens = function() {
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
for (key in _b) {
|
for (key in _b) {
|
||||||
if (!__hasProp.call(_b, key)) continue;
|
if (!__hasProp.call(_b, key)) continue;
|
||||||
val = _b[key];
|
val = _b[key];
|
||||||
val.assigned ? _a.push("" + key + " = " + val.value) : null;
|
val.assigned ? _a.push(("" + (key) + " = " + (val.value))) : null;
|
||||||
}
|
}
|
||||||
return _a;
|
return _a;
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,11 +59,11 @@ printTasks = ->
|
||||||
for all name, task of tasks
|
for all name, task of tasks
|
||||||
spaces = 20 - name.length
|
spaces = 20 - name.length
|
||||||
spaces = if spaces > 0 then (' ' for i in [0..spaces]).join('') else ''
|
spaces = if spaces > 0 then (' ' for i in [0..spaces]).join('') else ''
|
||||||
desc = if task.description then "# #task.description" else ''
|
desc = if task.description then "# #{task.description}" else ''
|
||||||
puts "cake #name#spaces #desc"
|
puts "cake #{name}#{spaces} #{desc}"
|
||||||
puts oparse.help() if switches.length
|
puts oparse.help() if switches.length
|
||||||
|
|
||||||
# Print an error and exit when attempting to all an undefined task.
|
# Print an error and exit when attempting to all an undefined task.
|
||||||
missingTask = (task) ->
|
missingTask = (task) ->
|
||||||
puts "No such task: \"#task\""
|
puts "No such task: \"#{task}\""
|
||||||
process.exit 1
|
process.exit 1
|
||||||
|
|
|
@ -34,7 +34,7 @@ exports.compile = compile = (code, options) ->
|
||||||
try
|
try
|
||||||
(parser.parse lexer.tokenize code).compile options
|
(parser.parse lexer.tokenize code).compile options
|
||||||
catch err
|
catch err
|
||||||
err.message = "In #options.fileName, #err.message" if options.fileName
|
err.message = "In #{options.fileName}, #{err.message}" if options.fileName
|
||||||
throw err
|
throw err
|
||||||
|
|
||||||
# Tokenize a string of CoffeeScript code, and return the array of tokens.
|
# Tokenize a string of CoffeeScript code, and return the array of tokens.
|
||||||
|
|
|
@ -71,7 +71,7 @@ compileScripts = ->
|
||||||
base = source
|
base = source
|
||||||
compile = (source, topLevel) ->
|
compile = (source, topLevel) ->
|
||||||
path.exists source, (exists) ->
|
path.exists source, (exists) ->
|
||||||
throw new Error "File not found: #source" unless exists
|
throw new Error "File not found: #{source}" unless exists
|
||||||
fs.stat source, (err, stats) ->
|
fs.stat source, (err, stats) ->
|
||||||
if stats.isDirectory()
|
if stats.isDirectory()
|
||||||
fs.readdir source, (err, files) ->
|
fs.readdir source, (err, files) ->
|
||||||
|
@ -131,9 +131,9 @@ writeJs = (source, js, base) ->
|
||||||
compile = ->
|
compile = ->
|
||||||
js = ' ' if js.length <= 0
|
js = ' ' if js.length <= 0
|
||||||
fs.writeFile jsPath, js, (err) ->
|
fs.writeFile jsPath, js, (err) ->
|
||||||
puts "Compiled #source" if options.compile and options.watch
|
puts "Compiled #{source}" if options.compile and options.watch
|
||||||
path.exists dir, (exists) ->
|
path.exists dir, (exists) ->
|
||||||
if exists then compile() else exec "mkdir -p #dir", compile
|
if exists then compile() else exec "mkdir -p #{dir}", compile
|
||||||
|
|
||||||
# Pipe compiled JS through JSLint (requires a working `jsl` command), printing
|
# Pipe compiled JS through JSLint (requires a working `jsl` command), printing
|
||||||
# any errors or warnings that arise.
|
# any errors or warnings that arise.
|
||||||
|
@ -149,7 +149,7 @@ lint = (js) ->
|
||||||
printTokens = (tokens) ->
|
printTokens = (tokens) ->
|
||||||
strings = for token in tokens
|
strings = for token in tokens
|
||||||
[tag, value] = [token[0], token[1].toString().replace(/\n/, '\\n')]
|
[tag, value] = [token[0], token[1].toString().replace(/\n/, '\\n')]
|
||||||
"[#tag #value]"
|
"[#{tag} #{value}]"
|
||||||
puts strings.join(' ')
|
puts strings.join(' ')
|
||||||
|
|
||||||
# Use the [OptionParser module](optparse.html) to extract all options from
|
# Use the [OptionParser module](optparse.html) to extract all options from
|
||||||
|
@ -175,5 +175,5 @@ usage = ->
|
||||||
|
|
||||||
# Print the `--version` message and exit.
|
# Print the `--version` message and exit.
|
||||||
version = ->
|
version = ->
|
||||||
puts "CoffeeScript version #CoffeeScript.VERSION"
|
puts "CoffeeScript version #{CoffeeScript.VERSION}"
|
||||||
process.exit 0
|
process.exit 0
|
||||||
|
|
|
@ -32,8 +32,8 @@ unwrap = /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/
|
||||||
# previous nonterminal.
|
# previous nonterminal.
|
||||||
o = (patternString, action, options) ->
|
o = (patternString, action, options) ->
|
||||||
return [patternString, '$$ = $1;', options] unless action
|
return [patternString, '$$ = $1;', options] unless action
|
||||||
action = if match = (action + '').match(unwrap) then match[1] else "(#action())"
|
action = if match = (action + '').match(unwrap) then match[1] else "(#{action}())"
|
||||||
[patternString, "$$ = #action;", options]
|
[patternString, "$$ = #{action};", options]
|
||||||
|
|
||||||
# Grammatical Rules
|
# Grammatical Rules
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|
|
@ -91,7 +91,7 @@ exports.Lexer = class Lexer
|
||||||
if include(JS_FORBIDDEN, id)
|
if include(JS_FORBIDDEN, id)
|
||||||
if forcedIdentifier
|
if forcedIdentifier
|
||||||
tag = 'STRING'
|
tag = 'STRING'
|
||||||
id = "\"#id\""
|
id = "\"#{id}\""
|
||||||
if forcedIdentifier is 'accessor'
|
if forcedIdentifier is 'accessor'
|
||||||
close_index = true
|
close_index = true
|
||||||
@tokens.pop() if @tag() isnt '@'
|
@tokens.pop() if @tag() isnt '@'
|
||||||
|
@ -131,7 +131,7 @@ exports.Lexer = class Lexer
|
||||||
return false unless match = @chunk.match(HEREDOC)
|
return false unless match = @chunk.match(HEREDOC)
|
||||||
quote = match[1].substr 0, 1
|
quote = match[1].substr 0, 1
|
||||||
doc = @sanitizeHeredoc match[2] or match[4], {quote}
|
doc = @sanitizeHeredoc match[2] or match[4], {quote}
|
||||||
@interpolateString "#quote#doc#quote", heredoc: yes
|
@interpolateString quote + doc + quote, heredoc: yes
|
||||||
@line += count match[1], "\n"
|
@line += count match[1], "\n"
|
||||||
@i += match[1].length
|
@i += match[1].length
|
||||||
true
|
true
|
||||||
|
@ -169,8 +169,8 @@ exports.Lexer = class Lexer
|
||||||
str = regex.substring(1).split('/')[0]
|
str = regex.substring(1).split('/')[0]
|
||||||
str = str.replace REGEX_ESCAPE, (escaped) -> '\\' + escaped
|
str = str.replace REGEX_ESCAPE, (escaped) -> '\\' + escaped
|
||||||
@tokens = @tokens.concat [['(', '('], ['NEW', 'new'], ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']]
|
@tokens = @tokens.concat [['(', '('], ['NEW', 'new'], ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']]
|
||||||
@interpolateString "\"#str\"", escapeQuotes: yes
|
@interpolateString "\"#{str}\"", escapeQuotes: yes
|
||||||
@tokens.splice @tokens.length, 0, [',', ','], ['STRING', "\"#flags\""] if flags
|
@tokens.splice @tokens.length, 0, [',', ','], ['STRING', "\"#{flags}\""] if flags
|
||||||
@tokens.splice @tokens.length, 0, [')', ')'], [')', ')']
|
@tokens.splice @tokens.length, 0, [')', ')'], [')', ')']
|
||||||
else
|
else
|
||||||
@token 'REGEX', regex
|
@token 'REGEX', regex
|
||||||
|
@ -318,7 +318,7 @@ exports.Lexer = class Lexer
|
||||||
doc = doc.replace(new RegExp("^" +indent, 'gm'), '')
|
doc = doc.replace(new RegExp("^" +indent, 'gm'), '')
|
||||||
return doc if options.herecomment
|
return doc if options.herecomment
|
||||||
doc.replace(MULTILINER, "\\n")
|
doc.replace(MULTILINER, "\\n")
|
||||||
.replace(new RegExp(options.quote, 'g'), "\\#options.quote")
|
.replace(new RegExp(options.quote, 'g'), "\\#{options.quote}")
|
||||||
|
|
||||||
# A source of ambiguity in our grammar used to be parameter lists in function
|
# A source of ambiguity in our grammar used to be parameter lists in function
|
||||||
# definitions versus argument lists in function calls. Walk backwards, tagging
|
# definitions versus argument lists in function calls. Walk backwards, tagging
|
||||||
|
@ -343,7 +343,7 @@ exports.Lexer = class Lexer
|
||||||
# The error for when you try to use a forbidden word in JavaScript as
|
# The error for when you try to use a forbidden word in JavaScript as
|
||||||
# an identifier.
|
# an identifier.
|
||||||
identifierError: (word) ->
|
identifierError: (word) ->
|
||||||
throw new Error "SyntaxError: Reserved word \"#word\" on line #{@line + 1}"
|
throw new Error "SyntaxError: Reserved word \"#{word}\" on line #{@line + 1}"
|
||||||
|
|
||||||
# The error for when you try to assign to a reserved word in JavaScript,
|
# The error for when you try to assign to a reserved word in JavaScript,
|
||||||
# like "function" or "default".
|
# like "function" or "default".
|
||||||
|
@ -385,7 +385,6 @@ exports.Lexer = class Lexer
|
||||||
# [ECMA Harmony's interpolation syntax](http://wiki.ecmascript.org/doku.php?id=strawman:string_interpolation)
|
# [ECMA Harmony's interpolation syntax](http://wiki.ecmascript.org/doku.php?id=strawman:string_interpolation)
|
||||||
# for substitution of bare variables as well as arbitrary expressions.
|
# for substitution of bare variables as well as arbitrary expressions.
|
||||||
#
|
#
|
||||||
# "Hello #name."
|
|
||||||
# "Hello #{name.capitalize()}."
|
# "Hello #{name.capitalize()}."
|
||||||
#
|
#
|
||||||
# If it encounters an interpolation, this method will recursively create a
|
# If it encounters an interpolation, this method will recursively create a
|
||||||
|
@ -406,25 +405,25 @@ exports.Lexer = class Lexer
|
||||||
else if match = str.substring(i).match INTERPOLATION
|
else if match = str.substring(i).match INTERPOLATION
|
||||||
[group, interp] = match
|
[group, interp] = match
|
||||||
interp = "this.#{ interp.substring(1) }" if starts interp, '@'
|
interp = "this.#{ interp.substring(1) }" if starts interp, '@'
|
||||||
tokens.push ['STRING', "#quote#{ str.substring(pi, i) }#quote"] if pi < i
|
tokens.push ['STRING', quote + str.substring(pi, i) + quote] if pi < i
|
||||||
tokens.push ['IDENTIFIER', interp]
|
tokens.push ['IDENTIFIER', interp]
|
||||||
i += group.length - 1
|
i += group.length - 1
|
||||||
pi = i + 1
|
pi = i + 1
|
||||||
else if (expr = @balancedString str.substring(i), [['#{', '}']])
|
else if (expr = @balancedString str.substring(i), [['#{', '}']])
|
||||||
tokens.push ['STRING', "#quote#{ str.substring(pi, i) }#quote"] if pi < i
|
tokens.push ['STRING', quote + str.substring(pi, i) + quote] if pi < i
|
||||||
inner = expr.substring(2, expr.length - 1)
|
inner = expr.substring(2, expr.length - 1)
|
||||||
if inner.length
|
if inner.length
|
||||||
inner = inner.replace new RegExp('\\\\' + quote, 'g'), quote if options.heredoc
|
inner = inner.replace new RegExp('\\\\' + quote, 'g'), quote if options.heredoc
|
||||||
nested = lexer.tokenize "(#inner)", line: @line
|
nested = lexer.tokenize "(#{inner})", line: @line
|
||||||
(tok[0] = ')') for tok, idx in nested when tok[0] is 'CALL_END'
|
(tok[0] = ')') for tok, idx in nested when tok[0] is 'CALL_END'
|
||||||
nested.pop()
|
nested.pop()
|
||||||
tokens.push ['TOKENS', nested]
|
tokens.push ['TOKENS', nested]
|
||||||
else
|
else
|
||||||
tokens.push ['STRING', "#quote#quote"]
|
tokens.push ['STRING', quote + quote]
|
||||||
i += expr.length - 1
|
i += expr.length - 1
|
||||||
pi = i + 1
|
pi = i + 1
|
||||||
i += 1
|
i += 1
|
||||||
tokens.push ['STRING', "#quote#{ str.substring(pi, i) }#quote"] if pi < i and pi < str.length - 1
|
tokens.push ['STRING', quote + str.substring(pi, i) + quote] if pi < i and pi < str.length - 1
|
||||||
tokens.unshift ['STRING', '""'] unless tokens[0][0] is 'STRING'
|
tokens.unshift ['STRING', '""'] unless tokens[0][0] is 'STRING'
|
||||||
interpolated = tokens.length > 1
|
interpolated = tokens.length > 1
|
||||||
@token '(', '(' if interpolated
|
@token '(', '(' if interpolated
|
||||||
|
@ -434,7 +433,7 @@ exports.Lexer = class Lexer
|
||||||
@tokens = @tokens.concat value
|
@tokens = @tokens.concat value
|
||||||
else if tag is 'STRING' and options.escapeQuotes
|
else if tag is 'STRING' and options.escapeQuotes
|
||||||
escaped = value.substring(1, value.length - 1).replace(/"/g, '\\"')
|
escaped = value.substring(1, value.length - 1).replace(/"/g, '\\"')
|
||||||
@token tag, "\"#escaped\""
|
@token tag, "\"#{escaped}\""
|
||||||
else
|
else
|
||||||
@token tag, value
|
@token tag, value
|
||||||
@token '+', '+' if i < tokens.length - 1
|
@token '+', '+' if i < tokens.length - 1
|
||||||
|
|
192
src/nodes.coffee
192
src/nodes.coffee
|
@ -206,14 +206,14 @@ exports.Expressions = class Expressions extends BaseNode
|
||||||
code = @compileWithDeclarations(o)
|
code = @compileWithDeclarations(o)
|
||||||
code = code.replace(TRAILING_WHITESPACE, '')
|
code = code.replace(TRAILING_WHITESPACE, '')
|
||||||
code = code.replace(DOUBLE_PARENS, '($1)')
|
code = code.replace(DOUBLE_PARENS, '($1)')
|
||||||
if o.noWrap then code else "(function() {\n#code\n})();\n"
|
if o.noWrap then code else "(function() {\n#{code}\n})();\n"
|
||||||
|
|
||||||
# Compile the expressions body for the contents of a function, with
|
# Compile the expressions body for the contents of a function, with
|
||||||
# declarations of all inner variables pushed up to the top.
|
# declarations of all inner variables pushed up to the top.
|
||||||
compileWithDeclarations: (o) ->
|
compileWithDeclarations: (o) ->
|
||||||
code = @compileNode(o)
|
code = @compileNode(o)
|
||||||
code = "#{@tab}var #{o.scope.compiledAssignments()};\n#code" if o.scope.hasAssignments(this)
|
code = "#{@tab}var #{o.scope.compiledAssignments()};\n#{code}" if o.scope.hasAssignments(this)
|
||||||
code = "#{@tab}var #{o.scope.compiledDeclarations()};\n#code" if not o.globals and o.scope.hasDeclarations(this)
|
code = "#{@tab}var #{o.scope.compiledDeclarations()};\n#{code}" if not o.globals and o.scope.hasDeclarations(this)
|
||||||
code
|
code
|
||||||
|
|
||||||
# Compiles a single expression within the expressions body. If we need to
|
# Compiles a single expression within the expressions body. If we need to
|
||||||
|
@ -222,7 +222,7 @@ exports.Expressions = class Expressions extends BaseNode
|
||||||
compileExpression: (node, o) ->
|
compileExpression: (node, o) ->
|
||||||
@tab = o.indent
|
@tab = o.indent
|
||||||
compiledNode = node.compile merge o, top: true
|
compiledNode = node.compile merge o, top: true
|
||||||
if node.isStatement() then compiledNode else "#{@idt()}#compiledNode;"
|
if node.isStatement() then compiledNode else "#{@idt()}#{compiledNode};"
|
||||||
|
|
||||||
# Wrap up the given nodes as an **Expressions**, unless it already happens
|
# Wrap up the given nodes as an **Expressions**, unless it already happens
|
||||||
# to be one.
|
# to be one.
|
||||||
|
@ -253,10 +253,10 @@ exports.LiteralNode = class LiteralNode extends BaseNode
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
idt = if @isStatement() then @idt() else ''
|
idt = if @isStatement() then @idt() else ''
|
||||||
end = if @isStatement() then ';' else ''
|
end = if @isStatement() then ';' else ''
|
||||||
"#idt#@value#end"
|
idt + @value + end
|
||||||
|
|
||||||
toString: (idt) ->
|
toString: (idt) ->
|
||||||
" \"#@value\""
|
'"' + @value + '"'
|
||||||
|
|
||||||
#### ReturnNode
|
#### ReturnNode
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ exports.ValueNode = class ValueNode extends BaseNode
|
||||||
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
|
||||||
|
|
||||||
for prop, i in props
|
for prop, i in props
|
||||||
|
@ -373,8 +373,8 @@ exports.ValueNode = class ValueNode extends BaseNode
|
||||||
if prop.soakNode
|
if prop.soakNode
|
||||||
if @base instanceof CallNode or @base.contains((n) -> n instanceof CallNode) and i is 0
|
if @base instanceof CallNode or @base.contains((n) -> n instanceof CallNode) and i is 0
|
||||||
temp = o.scope.freeVariable()
|
temp = o.scope.freeVariable()
|
||||||
complete = "(#{ baseline = temp } = (#complete))"
|
complete = "(#{ baseline = temp } = (#{complete}))"
|
||||||
complete = "typeof #complete === \"undefined\" || #baseline" if i is 0 and @isStart(o)
|
complete = "typeof #{complete} === \"undefined\" || #{baseline}" if i is 0 and @isStart(o)
|
||||||
complete += @SOAK + (baseline += prop.compile(o))
|
complete += @SOAK + (baseline += prop.compile(o))
|
||||||
else
|
else
|
||||||
part = prop.compile(o)
|
part = prop.compile(o)
|
||||||
|
@ -382,7 +382,7 @@ exports.ValueNode = class ValueNode extends BaseNode
|
||||||
complete += part
|
complete += part
|
||||||
@last = part
|
@last = part
|
||||||
|
|
||||||
if op and @wrapped then "(#complete)" else complete
|
if op and @wrapped then "(#{complete})" else complete
|
||||||
|
|
||||||
#### CommentNode
|
#### CommentNode
|
||||||
|
|
||||||
|
@ -399,8 +399,8 @@ exports.CommentNode = class CommentNode extends BaseNode
|
||||||
this
|
this
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
sep = "\n#@tab"
|
sep = '\n' + @tab
|
||||||
"#@tab/*#sep#{ @lines.join(sep) }\n#@tab*/"
|
"#{@tab}/*##{sep + @lines.join(sep) }\n#{@tab}*/"
|
||||||
|
|
||||||
#### CallNode
|
#### CallNode
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ exports.CallNode = class CallNode extends BaseNode
|
||||||
superReference: (o) ->
|
superReference: (o) ->
|
||||||
methname = o.scope.method.name
|
methname = o.scope.method.name
|
||||||
meth = if o.scope.method.proto
|
meth = if o.scope.method.proto
|
||||||
"#{o.scope.method.proto}.__superClass__.#methname"
|
"#{o.scope.method.proto}.__superClass__.#{methname}"
|
||||||
else if methname
|
else if methname
|
||||||
"#{methname}.__superClass__.constructor"
|
"#{methname}.__superClass__.constructor"
|
||||||
else throw new Error "cannot call super on an anonymous function."
|
else throw new Error "cannot call super on an anonymous function."
|
||||||
|
@ -444,13 +444,13 @@ exports.CallNode = class CallNode extends BaseNode
|
||||||
unless compilation
|
unless compilation
|
||||||
args = (arg.compile(o) for arg in @args).join(', ')
|
args = (arg.compile(o) for arg in @args).join(', ')
|
||||||
compilation = if @isSuper then @compileSuper(args, o)
|
compilation = if @isSuper then @compileSuper(args, o)
|
||||||
else "#{@prefix()}#{@variable.compile(o)}(#args)"
|
else "#{@prefix()}#{@variable.compile(o)}(#{args})"
|
||||||
if o.operation and @wrapped then "(#compilation)" else compilation
|
if o.operation and @wrapped then "(#{compilation})" else compilation
|
||||||
|
|
||||||
# `super()` is converted into a call against the superclass's implementation
|
# `super()` is converted into a call against the superclass's implementation
|
||||||
# of the current function.
|
# of the current function.
|
||||||
compileSuper: (args, o) ->
|
compileSuper: (args, o) ->
|
||||||
"#{@superReference(o)}.call(this#{ if args.length then ', ' else '' }#args)"
|
"#{@superReference(o)}.call(this#{ if args.length then ', ' else '' }#{args})"
|
||||||
|
|
||||||
# If you call a function with a splat, it's converted into a JavaScript
|
# If you call a function with a splat, it's converted into a JavaScript
|
||||||
# `.apply()` call to allow an array of arguments to be passed.
|
# `.apply()` call to allow an array of arguments to be passed.
|
||||||
|
@ -462,18 +462,18 @@ exports.CallNode = class CallNode extends BaseNode
|
||||||
if obj.match(/\(/)
|
if obj.match(/\(/)
|
||||||
temp = o.scope.freeVariable()
|
temp = o.scope.freeVariable()
|
||||||
obj = temp
|
obj = temp
|
||||||
meth = "(#temp = #{ @variable.source })#{ @variable.last }"
|
meth = "(#{temp} = #{ @variable.source })#{ @variable.last }"
|
||||||
if @isNew
|
if @isNew
|
||||||
utility 'extends'
|
utility 'extends'
|
||||||
"""
|
"""
|
||||||
(function() {
|
(function() {
|
||||||
#{@idt(1)}var ctor = function(){};
|
#{@idt(1)}var ctor = function(){};
|
||||||
#{@idt(1)}__extends(ctor, #meth);
|
#{@idt(1)}__extends(ctor, #{meth});
|
||||||
#{@idt(1)}return #{meth}.apply(new ctor, #{ @compileSplatArguments(o) });
|
#{@idt(1)}return #{meth}.apply(new ctor, #{ @compileSplatArguments(o) });
|
||||||
#@tab}).call(this)
|
#{@tab}}).call(this)
|
||||||
"""
|
"""
|
||||||
else
|
else
|
||||||
"#{@prefix()}#{meth}.apply(#obj, #{ @compileSplatArguments(o) })"
|
"#{@prefix()}#{meth}.apply(#{obj}, #{ @compileSplatArguments(o) })"
|
||||||
|
|
||||||
#### ExtendsNode
|
#### ExtendsNode
|
||||||
|
|
||||||
|
@ -508,7 +508,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
|
||||||
|
|
||||||
#### IndexNode
|
#### IndexNode
|
||||||
|
@ -525,7 +525,7 @@ exports.IndexNode = class IndexNode extends BaseNode
|
||||||
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}]"
|
||||||
|
|
||||||
#### RangeNode
|
#### RangeNode
|
||||||
|
|
||||||
|
@ -560,23 +560,23 @@ exports.RangeNode = class RangeNode extends BaseNode
|
||||||
return @compileSimple(o) if @fromNum and @toNum
|
return @compileSimple(o) if @fromNum and @toNum
|
||||||
idx = del o, 'index'
|
idx = del o, 'index'
|
||||||
step = del o, 'step'
|
step = del o, 'step'
|
||||||
vars = "#idx = #@fromVar"
|
vars = "#{idx} = #{@fromVar}"
|
||||||
intro = "(#@fromVar <= #@toVar ? #idx"
|
intro = "(#{@fromVar} <= #{@toVar} ? #{idx}"
|
||||||
compare = "#intro <#@equals #@toVar : #idx >#@equals #@toVar)"
|
compare = "#{intro} <#{@equals} #{@toVar} : #{idx} >#{@equals} #{@toVar})"
|
||||||
stepPart = if step then step.compile(o) else '1'
|
stepPart = if step then step.compile(o) else '1'
|
||||||
incr = if step then "#idx += #stepPart" else "#intro += #stepPart : #idx -= #stepPart)"
|
incr = if step then "#{idx} += #{stepPart}" else "#{intro} += #{stepPart} : #{idx} -= #{stepPart})"
|
||||||
"#vars; #compare; #incr"
|
"#{vars}; #{compare}; #{incr}"
|
||||||
|
|
||||||
# Compile a simple range comprehension, with integers.
|
# Compile a simple range comprehension, with integers.
|
||||||
compileSimple: (o) ->
|
compileSimple: (o) ->
|
||||||
[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
|
||||||
"#idx = #from; #idx >#@equals #to; #{step or "#idx--"}"
|
"#{idx} = #{from}; #{idx} >#{@equals} #{to}; #{step or "#{idx}--"}"
|
||||||
|
|
||||||
# When used as a value, expand the range into the equivalent array.
|
# When used as a value, expand the range into the equivalent array.
|
||||||
compileArray: (o) ->
|
compileArray: (o) ->
|
||||||
|
@ -593,10 +593,10 @@ exports.RangeNode = class RangeNode extends BaseNode
|
||||||
o.index = i
|
o.index = i
|
||||||
body = @compileSimple o
|
body = @compileSimple o
|
||||||
else
|
else
|
||||||
clause = "#@fromVar <= #@toVar ?"
|
clause = "#{@fromVar} <= #{@toVar} ?"
|
||||||
body = "var #i = #@fromVar; #clause #i <#@equals #@toVar : #i >#@equals #@toVar; #clause #i += 1 : #i -= 1"
|
body = "var #{i} = #{@fromVar}; #{clause} #{i} <#{@equals} #{@toVar} : #{i} >#{@equals} #{@toVar}; #{clause} #{i} += 1 : #{i} -= 1"
|
||||||
post = "{ #{result}.push(#i); }\n#{idt}return #result;\n#o.indent"
|
post = "{ #{result}.push(#{i}); }\n#{idt}return #{result};\n#{o.indent}"
|
||||||
"(function() {#{pre}\n#{idt}for (#body)#post}).call(this)"
|
"(function() {#{pre}\n#{idt}for (#{body})#{post}}).call(this)"
|
||||||
|
|
||||||
#### SliceNode
|
#### SliceNode
|
||||||
|
|
||||||
|
@ -614,7 +614,7 @@ exports.SliceNode = class SliceNode extends BaseNode
|
||||||
from = @range.from.compile(o)
|
from = @range.from.compile(o)
|
||||||
to = @range.to.compile(o)
|
to = @range.to.compile(o)
|
||||||
plusPart = if @range.exclusive then '' else ' + 1'
|
plusPart = if @range.exclusive then '' else ' + 1'
|
||||||
".slice(#from, #to#plusPart)"
|
".slice(#{from}, #{to}#{plusPart})"
|
||||||
|
|
||||||
#### ObjectNode
|
#### ObjectNode
|
||||||
|
|
||||||
|
@ -640,7 +640,7 @@ exports.ObjectNode = class ObjectNode extends BaseNode
|
||||||
indent + prop.compile(o) + join
|
indent + prop.compile(o) + join
|
||||||
props = props.join('')
|
props = props.join('')
|
||||||
inner = if props then '\n' + props + '\n' + @idt() else ''
|
inner = if props then '\n' + props + '\n' + @idt() else ''
|
||||||
"{#inner}"
|
'{' + inner + '}'
|
||||||
|
|
||||||
#### ArrayNode
|
#### ArrayNode
|
||||||
|
|
||||||
|
@ -663,16 +663,16 @@ exports.ArrayNode = class ArrayNode extends BaseNode
|
||||||
if obj instanceof SplatNode
|
if obj instanceof SplatNode
|
||||||
return @compileSplatLiteral o
|
return @compileSplatLiteral o
|
||||||
else if obj instanceof CommentNode
|
else if obj instanceof CommentNode
|
||||||
objects.push "\n#code\n#o.indent"
|
objects.push "\n#{code}\n#{o.indent}"
|
||||||
else if i is @objects.length - 1
|
else if i is @objects.length - 1
|
||||||
objects.push code
|
objects.push code
|
||||||
else
|
else
|
||||||
objects.push "#code, "
|
objects.push "#{code}, "
|
||||||
objects = objects.join('')
|
objects = objects.join('')
|
||||||
if indexOf(objects, '\n') >= 0
|
if indexOf(objects, '\n') >= 0
|
||||||
"[\n#{@idt(1)}#objects\n#@tab]"
|
"[\n#{@idt(1)}#{objects}\n#{@tab}]"
|
||||||
else
|
else
|
||||||
"[#objects]"
|
"[#{objects}]"
|
||||||
|
|
||||||
#### ClassNode
|
#### ClassNode
|
||||||
|
|
||||||
|
@ -729,19 +729,19 @@ exports.ClassNode = class ClassNode extends BaseNode
|
||||||
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); }"
|
||||||
if pvar
|
if pvar
|
||||||
access = if prop.context is 'this' then pvar.base.properties[0] else new AccessorNode(pvar, 'prototype')
|
access = if prop.context is 'this' then pvar.base.properties[0] else new AccessorNode(pvar, 'prototype')
|
||||||
val = new ValueNode(@variable, [access])
|
val = new ValueNode(@variable, [access])
|
||||||
prop = new AssignNode(val, func)
|
prop = new AssignNode(val, func)
|
||||||
props.push prop
|
props.push prop
|
||||||
|
|
||||||
constructor.body.unshift literal "#me = this" if me
|
constructor.body.unshift literal "#{me} = this" if me
|
||||||
construct = @idt() + (new AssignNode(@variable, constructor)).compile(merge o, {sharedScope: constScope}) + ';'
|
construct = @idt() + (new AssignNode(@variable, constructor)).compile(merge o, {sharedScope: constScope}) + ';'
|
||||||
props = if !props.empty() then '\n' + props.compile(o) else ''
|
props = if !props.empty() then '\n' + props.compile(o) else ''
|
||||||
extension = if extension then '\n' + @idt() + extension.compile(o) + ';' else ''
|
extension = if extension then '\n' + @idt() + extension.compile(o) + ';' else ''
|
||||||
returns = if @returns then '\n' + new ReturnNode(@variable).compile(o) else ''
|
returns = if @returns then '\n' + new ReturnNode(@variable).compile(o) else ''
|
||||||
"#construct#extension#props#returns"
|
construct + extension + props + returns
|
||||||
|
|
||||||
#### AssignNode
|
#### AssignNode
|
||||||
|
|
||||||
|
@ -790,11 +790,11 @@ exports.AssignNode = class AssignNode extends BaseNode
|
||||||
@value.name = last if last.match(IDENTIFIER)
|
@value.name = last if last.match(IDENTIFIER)
|
||||||
@value.proto = proto if proto
|
@value.proto = proto if proto
|
||||||
val = @value.compile o
|
val = @value.compile o
|
||||||
return "#name: #val" if @context is 'object'
|
return "#{name}: #{val}" if @context is 'object'
|
||||||
o.scope.find name unless @isValue() and (@variable.hasProperties() or @variable.namespaced)
|
o.scope.find name unless @isValue() and (@variable.hasProperties() or @variable.namespaced)
|
||||||
val = "#name = #val"
|
val = "#{name} = #{val}"
|
||||||
return "#@tab#val;" if stmt
|
return "#{@tab}#{val};" if stmt
|
||||||
if top then val else "(#val)"
|
if top then val else "(#{val})"
|
||||||
|
|
||||||
# Brief implementation of recursive pattern matching, when assigning array or
|
# Brief implementation of recursive pattern matching, when assigning array or
|
||||||
# object literals to a value. Peeks at their properties to assign inner names.
|
# object literals to a value. Peeks at their properties to assign inner names.
|
||||||
|
@ -803,7 +803,7 @@ exports.AssignNode = class AssignNode extends BaseNode
|
||||||
compilePatternMatch: (o) ->
|
compilePatternMatch: (o) ->
|
||||||
valVar = o.scope.freeVariable()
|
valVar = o.scope.freeVariable()
|
||||||
value = if @value.isStatement() then ClosureNode.wrap(@value) else @value
|
value = if @value.isStatement() then ClosureNode.wrap(@value) else @value
|
||||||
assigns = ["#@tab#valVar = #{ value.compile(o) };"]
|
assigns = ["#{@tab}#{valVar} = #{ value.compile(o) };"]
|
||||||
o.top = true
|
o.top = true
|
||||||
o.asStatement = true
|
o.asStatement = true
|
||||||
splat = false
|
splat = false
|
||||||
|
@ -843,7 +843,7 @@ exports.AssignNode = class AssignNode extends BaseNode
|
||||||
from = range.from.compile(o)
|
from = range.from.compile(o)
|
||||||
to = range.to.compile(o) + ' - ' + from + plus
|
to = range.to.compile(o) + ' - ' + from + plus
|
||||||
val = @value.compile(o)
|
val = @value.compile(o)
|
||||||
"#{name}.splice.apply(#name, [#from, #to].concat(#val))"
|
"#{name}.splice.apply(#{name}, [#{from}, #{to}].concat(#{val}))"
|
||||||
|
|
||||||
#### CodeNode
|
#### CodeNode
|
||||||
|
|
||||||
|
@ -899,9 +899,9 @@ exports.CodeNode = class CodeNode extends BaseNode
|
||||||
@body.makeReturn() unless empty
|
@body.makeReturn() unless empty
|
||||||
(o.scope.parameter(param)) for param in params
|
(o.scope.parameter(param)) for param in params
|
||||||
code = if @body.expressions.length then "\n#{ @body.compileWithDeclarations(o) }\n" else ''
|
code = if @body.expressions.length then "\n#{ @body.compileWithDeclarations(o) }\n" else ''
|
||||||
func = "function(#{ params.join(', ') }) {#code#{ code and @tab }}"
|
func = "function(#{ params.join(', ') }) {#{code}#{ code and @tab }}"
|
||||||
return "#{utility('bind')}(#func, this)" if @bound
|
return "#{utility('bind')}(#{func}, this)" if @bound
|
||||||
if top then "(#func)" else func
|
if top then "(#{func})" else func
|
||||||
|
|
||||||
topSensitive: ->
|
topSensitive: ->
|
||||||
true
|
true
|
||||||
|
@ -913,7 +913,7 @@ exports.CodeNode = class CodeNode extends BaseNode
|
||||||
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
|
||||||
|
|
||||||
#### ParamNode
|
#### ParamNode
|
||||||
|
|
||||||
|
@ -932,7 +932,7 @@ exports.ParamNode = class ParamNode extends BaseNode
|
||||||
@value.compile o
|
@value.compile o
|
||||||
|
|
||||||
toString: (idt) ->
|
toString: (idt) ->
|
||||||
if @attach then (literal "@#@name").toString idt else @value.toString idt
|
if @attach then (literal '@' + @name).toString idt else @value.toString idt
|
||||||
|
|
||||||
#### SplatNode
|
#### SplatNode
|
||||||
|
|
||||||
|
@ -960,22 +960,22 @@ exports.SplatNode = class SplatNode extends BaseNode
|
||||||
len = o.scope.freeVariable()
|
len = o.scope.freeVariable()
|
||||||
o.scope.assign len, "arguments.length"
|
o.scope.assign len, "arguments.length"
|
||||||
variadic = o.scope.freeVariable()
|
variadic = o.scope.freeVariable()
|
||||||
o.scope.assign variadic, "#len >= #@arglength"
|
o.scope.assign variadic, len + ' >= ' + @arglength
|
||||||
end = if @trailings.length then ", #len - #{@trailings.length}"
|
end = if @trailings.length then ", #{len} - #{@trailings.length}"
|
||||||
for trailing, idx in @trailings
|
for trailing, idx in @trailings
|
||||||
if trailing.attach
|
if trailing.attach
|
||||||
assign = trailing.assign
|
assign = trailing.assign
|
||||||
trailing = literal o.scope.freeVariable()
|
trailing = literal o.scope.freeVariable()
|
||||||
assign.value = trailing
|
assign.value = trailing
|
||||||
pos = @trailings.length - idx
|
pos = @trailings.length - idx
|
||||||
o.scope.assign(trailing.compile(o), "arguments[#variadic ? #len - #pos : #{@index + idx}]")
|
o.scope.assign(trailing.compile(o), "arguments[#{variadic} ? #{len} - #{pos} : #{@index + idx}]")
|
||||||
"#name = #{utility('slice')}.call(arguments, #@index#end)"
|
"#{name} = #{utility('slice')}.call(arguments, #{@index}#{end})"
|
||||||
|
|
||||||
# A compiling a splat as a destructuring assignment means slicing arguments
|
# A compiling a splat as a destructuring assignment means slicing arguments
|
||||||
# from the right-hand-side's corresponding array.
|
# from the right-hand-side's corresponding array.
|
||||||
compileValue: (o, name, index, trailings) ->
|
compileValue: (o, name, index, trailings) ->
|
||||||
trail = if trailings then ", #{name}.length - #trailings" else ''
|
trail = if trailings then ", #{name}.length - #{trailings}" else ''
|
||||||
"#{utility 'slice'}.call(#name, #index#trail)"
|
"#{utility 'slice'}.call(#{name}, #{index}#{trail})"
|
||||||
|
|
||||||
# Utility function that converts arbitrary number of elements, mixed with
|
# Utility function that converts arbitrary number of elements, mixed with
|
||||||
# splats, to a proper array
|
# splats, to a proper array
|
||||||
|
@ -986,14 +986,14 @@ exports.SplatNode = class SplatNode extends BaseNode
|
||||||
prev = args[last = args.length - 1]
|
prev = args[last = args.length - 1]
|
||||||
if not (arg instanceof SplatNode)
|
if not (arg instanceof SplatNode)
|
||||||
if prev and starts(prev, '[') and ends(prev, ']')
|
if prev and starts(prev, '[') and ends(prev, ']')
|
||||||
args[last] = "#{prev.substr(0, prev.length - 1)}, #code]"
|
args[last] = "#{prev.substr(0, prev.length - 1)}, #{code}]"
|
||||||
continue
|
continue
|
||||||
else if prev and starts(prev, '.concat([') and ends(prev, '])')
|
else if prev and starts(prev, '.concat([') and ends(prev, '])')
|
||||||
args[last] = "#{prev.substr(0, prev.length - 2)}, #code])"
|
args[last] = "#{prev.substr(0, prev.length - 2)}, #{code}])"
|
||||||
continue
|
continue
|
||||||
else
|
else
|
||||||
code = "[#code]"
|
code = "[#{code}]"
|
||||||
args.push(if i is 0 then code else ".concat(#code)")
|
args.push(if i is 0 then code else ".concat(#{code})")
|
||||||
args.join('')
|
args.join('')
|
||||||
|
|
||||||
#### WhileNode
|
#### WhileNode
|
||||||
|
@ -1036,15 +1036,15 @@ exports.WhileNode = class WhileNode extends BaseNode
|
||||||
set = ''
|
set = ''
|
||||||
unless top
|
unless top
|
||||||
rvar = o.scope.freeVariable()
|
rvar = o.scope.freeVariable()
|
||||||
set = "#@tab#rvar = [];\n"
|
set = "#{@tab}#{rvar} = [];\n"
|
||||||
@body = PushNode.wrap(rvar, @body) if @body
|
@body = PushNode.wrap(rvar, @body) if @body
|
||||||
pre = "#set#{@tab}while (#cond)"
|
pre = "#{set}#{@tab}while (#{cond})"
|
||||||
@body = Expressions.wrap([new IfNode(@guard, @body)]) if @guard
|
@body = Expressions.wrap([new IfNode(@guard, @body)]) if @guard
|
||||||
if @returns
|
if @returns
|
||||||
post = '\n' + new ReturnNode(literal(rvar)).compile(merge(o, indent: @idt()))
|
post = '\n' + new ReturnNode(literal(rvar)).compile(merge(o, indent: @idt()))
|
||||||
else
|
else
|
||||||
post = ''
|
post = ''
|
||||||
"#pre {\n#{ @body.compile(o) }\n#@tab}#post"
|
"#{pre} {\n#{ @body.compile(o) }\n#{@tab}}#{post}"
|
||||||
|
|
||||||
#### OpNode
|
#### OpNode
|
||||||
|
|
||||||
|
@ -1103,7 +1103,7 @@ exports.OpNode = class OpNode extends BaseNode
|
||||||
shared = @first.unwrap().second
|
shared = @first.unwrap().second
|
||||||
[@first.second, shared] = shared.compileReference(o) if shared.containsType CallNode
|
[@first.second, shared] = shared.compileReference(o) if shared.containsType CallNode
|
||||||
[first, second, shared] = [@first.compile(o), @second.compile(o), shared.compile(o)]
|
[first, second, shared] = [@first.compile(o), @second.compile(o), shared.compile(o)]
|
||||||
"(#first) && (#shared #@operator #second)"
|
"(#{first}) && (#{shared} #{@operator} #{second})"
|
||||||
|
|
||||||
# When compiling a conditional assignment, take care to ensure that the
|
# When compiling a conditional assignment, take care to ensure that the
|
||||||
# operands are only evaluated once, even though we have to reference them
|
# operands are only evaluated once, even though we have to reference them
|
||||||
|
@ -1112,15 +1112,15 @@ exports.OpNode = class OpNode extends BaseNode
|
||||||
[first, firstVar] = @first.compileReference o, precompile: yes, assignment: yes
|
[first, firstVar] = @first.compileReference o, precompile: yes, assignment: yes
|
||||||
second = @second.compile o
|
second = @second.compile o
|
||||||
o.scope.find(first) if first.match(IDENTIFIER)
|
o.scope.find(first) if first.match(IDENTIFIER)
|
||||||
return "#first = #{ ExistenceNode.compileTest(o, literal(firstVar)) } ? #firstVar : #second" if @operator is '?='
|
return "#{first} = #{ ExistenceNode.compileTest(o, literal(firstVar)) } ? #{firstVar} : #{second}" if @operator is '?='
|
||||||
"#first = #firstVar #{ @operator.substr(0, 2) } #second"
|
"#{first} = #{firstVar} #{ @operator.substr(0, 2) } #{second}"
|
||||||
|
|
||||||
# If this is an existence operator, we delegate to `ExistenceNode.compileTest`
|
# If this is an existence operator, we delegate to `ExistenceNode.compileTest`
|
||||||
# to give us the safe references for the variables.
|
# to give us the safe references for the variables.
|
||||||
compileExistence: (o) ->
|
compileExistence: (o) ->
|
||||||
[first, second] = [@first.compile(o), @second.compile(o)]
|
[first, second] = [@first.compile(o), @second.compile(o)]
|
||||||
test = ExistenceNode.compileTest(o, @first)
|
test = ExistenceNode.compileTest(o, @first)
|
||||||
"#test ? #first : #second"
|
"#{test} ? #{first} : #{second}"
|
||||||
|
|
||||||
# Compile a unary **OpNode**.
|
# Compile a unary **OpNode**.
|
||||||
compileUnary: (o) ->
|
compileUnary: (o) ->
|
||||||
|
@ -1153,7 +1153,7 @@ exports.InNode = class InNode extends BaseNode
|
||||||
[@arr1, @arr2] = @array.compileReference o, precompile: yes
|
[@arr1, @arr2] = @array.compileReference o, precompile: yes
|
||||||
[i, l] = [o.scope.freeVariable(), o.scope.freeVariable()]
|
[i, l] = [o.scope.freeVariable(), o.scope.freeVariable()]
|
||||||
prefix = if @obj1 isnt @obj2 then @obj1 + '; ' else ''
|
prefix = if @obj1 isnt @obj2 then @obj1 + '; ' else ''
|
||||||
"(function(){ #{prefix}for (var #i=0, #l=#{@arr1}.length; #i<#l; #i++) { if (#{@arr2}[#i] === #@obj2) return true; } return false; }).call(this)"
|
"(function(){ #{prefix}for (var #{i}=0, #{l}=#{@arr1}.length; #{i}<#{l}; #{i}++) { if (#{@arr2}[#{i}] === #{@obj2}) return true; } return false; }).call(this)"
|
||||||
|
|
||||||
#### TryNode
|
#### TryNode
|
||||||
|
|
||||||
|
@ -1178,9 +1178,9 @@ exports.TryNode = class TryNode extends BaseNode
|
||||||
o.top = true
|
o.top = true
|
||||||
attemptPart = @attempt.compile(o)
|
attemptPart = @attempt.compile(o)
|
||||||
errorPart = if @error then " (#{ @error.compile(o) }) " else ' '
|
errorPart = if @error then " (#{ @error.compile(o) }) " else ' '
|
||||||
catchPart = if @recovery then " catch#errorPart{\n#{ @recovery.compile(o) }\n#@tab}" else ''
|
catchPart = if @recovery then " catch#{errorPart}{\n#{ @recovery.compile(o) }\n#{@tab}}" else ''
|
||||||
finallyPart = (@ensure or '') and ' finally {\n' + @ensure.compile(merge(o)) + "\n#@tab}"
|
finallyPart = (@ensure or '') and ' finally {\n' + @ensure.compile(merge(o)) + "\n#{@tab}}"
|
||||||
"#{@tab}try {\n#attemptPart\n#@tab}#catchPart#finallyPart"
|
"#{@tab}try {\n#{attemptPart}\n#{@tab}}#{catchPart}#{finallyPart}"
|
||||||
|
|
||||||
#### ThrowNode
|
#### ThrowNode
|
||||||
|
|
||||||
|
@ -1249,10 +1249,10 @@ exports.ParentheticalNode = class ParentheticalNode extends BaseNode
|
||||||
top = del o, 'top'
|
top = del o, 'top'
|
||||||
code = @expression.compile(o)
|
code = @expression.compile(o)
|
||||||
if @isStatement()
|
if @isStatement()
|
||||||
return (if top then "#@tab#code;" else code)
|
return (if top then @tab + code + ';' else code)
|
||||||
l = code.length
|
l = code.length
|
||||||
code = code.substr(o, l-1) if code.substr(l-1, 1) is ';'
|
code = code.substr(o, l-1) if code.substr(l-1, 1) is ';'
|
||||||
if @expression instanceof AssignNode then code else "(#code)"
|
if @expression instanceof AssignNode then code else "(#{code})"
|
||||||
|
|
||||||
#### ForNode
|
#### ForNode
|
||||||
|
|
||||||
|
@ -1317,34 +1317,34 @@ exports.ForNode = class ForNode extends BaseNode
|
||||||
forPart = source.compile merge o, index: ivar, step: @step
|
forPart = source.compile merge o, index: ivar, step: @step
|
||||||
else
|
else
|
||||||
svar = scope.freeVariable()
|
svar = scope.freeVariable()
|
||||||
sourcePart = "#svar = #{ @source.compile(o) };"
|
sourcePart = "#{svar} = #{ @source.compile(o) };"
|
||||||
if @pattern
|
if @pattern
|
||||||
namePart = new AssignNode(@name, literal("#svar[#ivar]")).compile(merge o, {indent: @idt(1), top: true}) + '\n'
|
namePart = new AssignNode(@name, literal("#{svar}[#{ivar}]")).compile(merge o, {indent: @idt(1), top: true}) + '\n'
|
||||||
else
|
else
|
||||||
namePart = "#name = #svar[#ivar]" if name
|
namePart = "#{name} = #{svar}[#{ivar}]" if name
|
||||||
unless @object
|
unless @object
|
||||||
lvar = scope.freeVariable()
|
lvar = scope.freeVariable()
|
||||||
stepPart = if @step then "#ivar += #{ @step.compile(o) }" else "#ivar++"
|
stepPart = if @step then "#{ivar} += #{ @step.compile(o) }" else "#{ivar}++"
|
||||||
forPart = "#ivar = 0, #lvar = #{svar}.length; #ivar < #lvar; #stepPart"
|
forPart = "#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} < #{lvar}; #{stepPart}"
|
||||||
sourcePart = (if rvar then "#rvar = []; " else '') + sourcePart
|
sourcePart = (if rvar then "#{rvar} = []; " else '') + sourcePart
|
||||||
sourcePart = if sourcePart then "#@tab#sourcePart\n#@tab" else @tab
|
sourcePart = if sourcePart then "#{@tab}#{sourcePart}\n#{@tab}" else @tab
|
||||||
returnResult = @compileReturnValue(rvar, o)
|
returnResult = @compileReturnValue(rvar, o)
|
||||||
|
|
||||||
body = PushNode.wrap(rvar, body) unless topLevel
|
body = PushNode.wrap(rvar, body) unless topLevel
|
||||||
if @guard
|
if @guard
|
||||||
body = Expressions.wrap([new IfNode(@guard, body)])
|
body = Expressions.wrap([new IfNode(@guard, body)])
|
||||||
if codeInBody
|
if codeInBody
|
||||||
body.unshift literal "var #namePart" if namePart
|
body.unshift literal "var #{namePart}" if namePart
|
||||||
body.unshift literal "var #index = #ivar" if index
|
body.unshift literal "var #{index} = #{ivar}" if index
|
||||||
body = ClosureNode.wrap(body, true)
|
body = ClosureNode.wrap(body, true)
|
||||||
else
|
else
|
||||||
varPart = (namePart or '') and (if @pattern then namePart else "#{@idt(1)}#namePart;\n")
|
varPart = (namePart or '') and (if @pattern then namePart else "#{@idt(1)}#{namePart};\n")
|
||||||
if @object
|
if @object
|
||||||
forPart = "#ivar in #svar"
|
forPart = "#{ivar} in #{svar}"
|
||||||
guardPart = "\n#{@idt(1)}if (!#{utility('hasProp')}.call(#svar, #ivar)) continue;" unless @raw
|
guardPart = "\n#{@idt(1)}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw
|
||||||
body = body.compile(merge(o, {indent: @idt(1), top: true}))
|
body = body.compile(merge(o, {indent: @idt(1), top: true}))
|
||||||
vars = if range then name else "#name, #ivar"
|
vars = if range then name else "#{name}, #{ivar}"
|
||||||
"#{sourcePart}for (#forPart) {#guardPart\n#varPart#body\n#@tab}#returnResult"
|
"#{sourcePart}for (#{forPart}) {#{guardPart}\n#{varPart}#{body}\n#{@tab}}#{returnResult}"
|
||||||
|
|
||||||
#### IfNode
|
#### IfNode
|
||||||
|
|
||||||
|
@ -1435,20 +1435,20 @@ exports.IfNode = class IfNode extends BaseNode
|
||||||
ifDent = if child then '' else @idt()
|
ifDent = if child then '' else @idt()
|
||||||
comDent = if child then @idt() else ''
|
comDent = if child then @idt() else ''
|
||||||
body = @body.compile(o)
|
body = @body.compile(o)
|
||||||
ifPart = "#{ifDent}if (#{ @compileCondition(condO) }) {\n#body\n#@tab}"
|
ifPart = "#{ifDent}if (#{ @compileCondition(condO) }) {\n#{body}\n#{@tab}}"
|
||||||
return ifPart unless @elseBody
|
return ifPart unless @elseBody
|
||||||
elsePart = if @isChain
|
elsePart = if @isChain
|
||||||
' else ' + @elseBodyNode().compile(merge(o, {indent: @idt(), chainChild: true}))
|
' else ' + @elseBodyNode().compile(merge(o, {indent: @idt(), chainChild: true}))
|
||||||
else
|
else
|
||||||
" else {\n#{ @elseBody.compile(o) }\n#@tab}"
|
" else {\n#{ @elseBody.compile(o) }\n#{@tab}}"
|
||||||
"#ifPart#elsePart"
|
"#{ifPart}#{elsePart}"
|
||||||
|
|
||||||
# Compile the IfNode as a ternary operator.
|
# Compile the IfNode as a ternary operator.
|
||||||
compileTernary: (o) ->
|
compileTernary: (o) ->
|
||||||
o.operation = true
|
o.operation = true
|
||||||
ifPart = @condition.compile(o) + ' ? ' + @bodyNode().compile(o)
|
ifPart = @condition.compile(o) + ' ? ' + @bodyNode().compile(o)
|
||||||
elsePart = if @elseBody then @elseBodyNode().compile(o) else 'null'
|
elsePart = if @elseBody then @elseBodyNode().compile(o) else 'null'
|
||||||
"#ifPart : #elsePart"
|
"#{ifPart} : #{elsePart}"
|
||||||
|
|
||||||
# Faux-Nodes
|
# Faux-Nodes
|
||||||
# ----------
|
# ----------
|
||||||
|
@ -1559,6 +1559,6 @@ literal = (name) ->
|
||||||
|
|
||||||
# Helper for ensuring that utility functions are assigned at the top level.
|
# Helper for ensuring that utility functions are assigned at the top level.
|
||||||
utility = (name) ->
|
utility = (name) ->
|
||||||
ref = "__#name"
|
ref = "__#{name}"
|
||||||
Scope.root.assign ref, UTILITIES[name]
|
Scope.root.assign ref, UTILITIES[name]
|
||||||
ref
|
ref
|
||||||
|
|
|
@ -33,7 +33,7 @@ exports.OptionParser = class OptionParser
|
||||||
options[rule.name] = if rule.hasArgument then args[i += 1] else true
|
options[rule.name] = if rule.hasArgument then args[i += 1] else true
|
||||||
matchedRule = yes
|
matchedRule = yes
|
||||||
break
|
break
|
||||||
throw new Error "unrecognized option: #arg" if isOption and not matchedRule
|
throw new Error "unrecognized option: #{arg}" if isOption and not matchedRule
|
||||||
if not isOption
|
if not isOption
|
||||||
options.arguments = args[i...args.length]
|
options.arguments = args[i...args.length]
|
||||||
break
|
break
|
||||||
|
@ -43,12 +43,12 @@ exports.OptionParser = class OptionParser
|
||||||
# of the valid options, for `--help` and such.
|
# of the valid options, for `--help` and such.
|
||||||
help: ->
|
help: ->
|
||||||
lines = ['Available options:']
|
lines = ['Available options:']
|
||||||
lines.unshift "#@banner\n" if @banner
|
lines.unshift "#{@banner}\n" if @banner
|
||||||
for rule in @rules
|
for rule in @rules
|
||||||
spaces = 15 - rule.longFlag.length
|
spaces = 15 - rule.longFlag.length
|
||||||
spaces = if spaces > 0 then (' ' for i in [0..spaces]).join('') else ''
|
spaces = if spaces > 0 then (' ' for i in [0..spaces]).join('') else ''
|
||||||
letPart = if rule.shortFlag then rule.shortFlag + ', ' else ' '
|
letPart = if rule.shortFlag then rule.shortFlag + ', ' else ' '
|
||||||
lines.push " #letPart#rule.longFlag#spaces#rule.description"
|
lines.push ' ' + letPart + rule.longFlag + spaces + rule.description
|
||||||
"\n#{ lines.join('\n') }\n"
|
"\n#{ lines.join('\n') }\n"
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# and evaluates it. Good for simple tests, or poking around the **Node.js** API.
|
# and evaluates it. Good for simple tests, or poking around the **Node.js** API.
|
||||||
# Using it looks like this:
|
# Using it looks like this:
|
||||||
#
|
#
|
||||||
# coffee> puts "#num bottles of beer" for num in [99..1]
|
# coffee> puts "#{num} bottles of beer" for num in [99..1]
|
||||||
|
|
||||||
# Require the **coffee-script** module to get access to the compiler.
|
# Require the **coffee-script** module to get access to the compiler.
|
||||||
CoffeeScript = require './coffee-script'
|
CoffeeScript = require './coffee-script'
|
||||||
|
|
|
@ -254,7 +254,7 @@ exports.Rewriter = class Rewriter
|
||||||
if unclosed.length
|
if unclosed.length
|
||||||
open = unclosed[0]
|
open = unclosed[0]
|
||||||
line = openLine[open] + 1
|
line = openLine[open] + 1
|
||||||
throw new Error "unclosed #open on line #line"
|
throw new Error "unclosed #{open} on line #{line}"
|
||||||
|
|
||||||
# We'd like to support syntax like this:
|
# We'd like to support syntax like this:
|
||||||
#
|
#
|
||||||
|
|
|
@ -80,7 +80,7 @@ exports.Scope = class Scope
|
||||||
# Return the list of assignments that are supposed to be made at the top
|
# Return the list of assignments that are supposed to be made at the top
|
||||||
# of this scope.
|
# of this scope.
|
||||||
assignedVariables: ->
|
assignedVariables: ->
|
||||||
"#key = #val.value" for key, val of @variables when val.assigned
|
"#{key} = #{val.value}" for key, val of @variables when val.assigned
|
||||||
|
|
||||||
# Compile the JavaScript for all of the variable declarations in this scope.
|
# Compile the JavaScript for all of the variable declarations in this scope.
|
||||||
compiledDeclarations: ->
|
compiledDeclarations: ->
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Test classes with a four-level inheritance chain.
|
# Test classes with a four-level inheritance chain.
|
||||||
class Base
|
class Base
|
||||||
func: (string) ->
|
func: (string) ->
|
||||||
"zero/#string"
|
"zero/#{string}"
|
||||||
|
|
||||||
@static: (string) ->
|
@static: (string) ->
|
||||||
"static/#string"
|
"static/#{string}"
|
||||||
|
|
||||||
class FirstChild extends Base
|
class FirstChild extends Base
|
||||||
func: (string) ->
|
func: (string) ->
|
||||||
|
@ -56,7 +56,7 @@ Base = ->
|
||||||
Base::func = (string) ->
|
Base::func = (string) ->
|
||||||
'zero/' + string
|
'zero/' + string
|
||||||
Base::['func-func'] = (string) ->
|
Base::['func-func'] = (string) ->
|
||||||
"dynamic-#string"
|
"dynamic-#{string}"
|
||||||
|
|
||||||
FirstChild = ->
|
FirstChild = ->
|
||||||
FirstChild extends Base
|
FirstChild extends Base
|
||||||
|
@ -137,7 +137,7 @@ class Dog
|
||||||
@name = name
|
@name = name
|
||||||
|
|
||||||
bark: =>
|
bark: =>
|
||||||
"#@name woofs!"
|
"#{@name} woofs!"
|
||||||
|
|
||||||
spark = new Dog('Spark')
|
spark = new Dog('Spark')
|
||||||
fido = new Dog('Fido')
|
fido = new Dog('Fido')
|
||||||
|
@ -164,7 +164,7 @@ class Connection
|
||||||
[@one, @two, @three] = [one, two, three]
|
[@one, @two, @three] = [one, two, three]
|
||||||
|
|
||||||
out: ->
|
out: ->
|
||||||
"#@one-#@two-#@three"
|
"#{@one}-#{@two}-#{@three}"
|
||||||
|
|
||||||
list = [3, 2, 1]
|
list = [3, 2, 1]
|
||||||
conn = new Connection list...
|
conn = new Connection list...
|
||||||
|
|
|
@ -55,17 +55,17 @@ ok a is 'more"than"one"quote'
|
||||||
val = 10
|
val = 10
|
||||||
|
|
||||||
a = """
|
a = """
|
||||||
basic heredoc #val
|
basic heredoc #{val}
|
||||||
on two lines
|
on two lines
|
||||||
"""
|
"""
|
||||||
|
|
||||||
b = '''
|
b = '''
|
||||||
basic heredoc #val
|
basic heredoc #{val}
|
||||||
on two lines
|
on two lines
|
||||||
'''
|
'''
|
||||||
|
|
||||||
ok a is "basic heredoc 10\non two lines"
|
ok a is "basic heredoc 10\non two lines"
|
||||||
ok b is "basic heredoc \#val\non two lines"
|
ok b is "basic heredoc \#{val}\non two lines"
|
||||||
|
|
||||||
|
|
||||||
a = '''here's an apostrophe'''
|
a = '''here's an apostrophe'''
|
||||||
|
|
|
@ -119,7 +119,7 @@ persons = {
|
||||||
Christopher: { name: "Stan" }
|
Christopher: { name: "Stan" }
|
||||||
}
|
}
|
||||||
|
|
||||||
join1 = "#key: #name" for key, { name } of persons
|
join1 = "#{key}: #{name}" for key, { name } of persons
|
||||||
|
|
||||||
deepEqual join1, ["George: Bob", "Bob: Alice", "Christopher: Stan"]
|
deepEqual join1, ["George: Bob", "Bob: Alice", "Christopher: Stan"]
|
||||||
|
|
||||||
|
@ -129,11 +129,11 @@ persons = [
|
||||||
{ name: "Stan", parent: { name: "Christopher" } }
|
{ name: "Stan", parent: { name: "Christopher" } }
|
||||||
]
|
]
|
||||||
|
|
||||||
join2 = "#parent: #name" for { name, parent: { name: parent } } in persons
|
join2 = "#{parent}: #{name}" for { name, parent: { name: parent } } in persons
|
||||||
|
|
||||||
deepEqual join1, join2
|
deepEqual join1, join2
|
||||||
|
|
||||||
persons = [['Bob', ['George']], ['Alice', ['Bob']], ['Stan', ['Christopher']]]
|
persons = [['Bob', ['George']], ['Alice', ['Bob']], ['Stan', ['Christopher']]]
|
||||||
join3 = "#parent: #name" for [name, [parent]] in persons
|
join3 = "#{parent}: #{name}" for [name, [parent]] in persons
|
||||||
|
|
||||||
deepEqual join2, join3
|
deepEqual join2, join3
|
||||||
|
|
|
@ -4,17 +4,17 @@ name = 'Moe'
|
||||||
ok not not '"Moe"'.match(/^"#{name}"$/i)
|
ok not not '"Moe"'.match(/^"#{name}"$/i)
|
||||||
ok '"Moe!"'.match(/^"#{name}"$/i) is null
|
ok '"Moe!"'.match(/^"#{name}"$/i) is null
|
||||||
|
|
||||||
ok not not 'Moe'.match(/^#name$/)
|
ok not not 'Moe'.match(/^#{name}$/)
|
||||||
ok 'Moe!'.match(/^#name/)
|
ok 'Moe!'.match(/^#{name}/)
|
||||||
|
|
||||||
ok 'Moe!'.match(/#{"#{"#{"#name"}"}"}/imgy)
|
ok 'Moe!'.match(/#{"#{"#{"#{name}"}"}"}/imgy)
|
||||||
|
|
||||||
ok '$a$b$c'.match(/\$A\$B\$C/i)
|
ok '$a$b$c'.match(/\$A\$B\$C/i)
|
||||||
|
|
||||||
a = 1
|
a = 1
|
||||||
b = 2
|
b = 2
|
||||||
c = 3
|
c = 3
|
||||||
ok '123'.match(/#a#b#c/i)
|
ok '123'.match(/#{a}#{b}#{c}/i)
|
||||||
|
|
||||||
[a, b, c] = [1, 2, /\d+/]
|
[a, b, c] = [1, 2, /\d+/]
|
||||||
ok (/#a#b#c$/i).toString() is '/12/\\d+/$/i'
|
ok (/#{a}#{b}#{c}$/i).toString() is '/12/\\d+/$/i'
|
||||||
|
|
|
@ -1,45 +1,31 @@
|
||||||
hello = 'Hello'
|
hello = 'Hello'
|
||||||
world = 'World'
|
world = 'World'
|
||||||
ok '#hello #world!' is '#hello #world!'
|
|
||||||
ok '#{hello} #{world}!' is '#{hello} #{world}!'
|
ok '#{hello} #{world}!' is '#{hello} #{world}!'
|
||||||
ok "#hello #world!" is 'Hello World!'
|
|
||||||
ok "#{hello} #{world}!" is 'Hello World!'
|
ok "#{hello} #{world}!" is 'Hello World!'
|
||||||
ok "[#hello#world]" is '[HelloWorld]'
|
|
||||||
ok "[#{hello}#{world}]" is '[HelloWorld]'
|
ok "[#{hello}#{world}]" is '[HelloWorld]'
|
||||||
ok "#hello##world" is 'Hello#World'
|
|
||||||
ok "#{hello}##{world}" is 'Hello#World'
|
ok "#{hello}##{world}" is 'Hello#World'
|
||||||
ok "Hello #{ 1 + 2 } World" is 'Hello 3 World'
|
ok "Hello #{ 1 + 2 } World" is 'Hello 3 World'
|
||||||
ok "#hello #{ 1 + 2 } #world" is "Hello 3 World"
|
ok "#{hello} #{ 1 + 2 } #{world}" is "Hello 3 World"
|
||||||
|
|
||||||
|
|
||||||
[s, t, r, i, n, g] = ['s', 't', 'r', 'i', 'n', 'g']
|
[s, t, r, i, n, g] = ['s', 't', 'r', 'i', 'n', 'g']
|
||||||
ok "#s#t#r#i#n#g" is 'string'
|
|
||||||
ok "#{s}#{t}#{r}#{i}#{n}#{g}" is 'string'
|
ok "#{s}#{t}#{r}#{i}#{n}#{g}" is 'string'
|
||||||
ok "\#s\#t\#r\#i\#n\#g" is '#s#t#r#i#n#g'
|
|
||||||
ok "\\#s\\#t\\#r\\#i\\#n\\#g" is '\\s\\t\\r\\i\\n\\g'
|
|
||||||
ok "\#{s}\#{t}\#{r}\#{i}\#{n}\#{g}" is '#{s}#{t}#{r}#{i}#{n}#{g}'
|
ok "\#{s}\#{t}\#{r}\#{i}\#{n}\#{g}" is '#{s}#{t}#{r}#{i}#{n}#{g}'
|
||||||
ok "\#string" is '#string'
|
|
||||||
ok "\#{string}" is '#{string}'
|
ok "\#{string}" is '#{string}'
|
||||||
|
|
||||||
|
|
||||||
ok "\#Escaping first" is '#Escaping first'
|
|
||||||
ok "\#{Escaping} first" is '#{Escaping} first'
|
ok "\#{Escaping} first" is '#{Escaping} first'
|
||||||
ok "Escaping \#in middle" is 'Escaping #in middle'
|
|
||||||
ok "Escaping \#{in} middle" is 'Escaping #{in} middle'
|
ok "Escaping \#{in} middle" is 'Escaping #{in} middle'
|
||||||
ok "Escaping \#last" is 'Escaping #last'
|
|
||||||
ok "Escaping \#{last}" is 'Escaping #{last}'
|
ok "Escaping \#{last}" is 'Escaping #{last}'
|
||||||
|
|
||||||
|
|
||||||
ok "##" is '##'
|
ok "##" is '##'
|
||||||
ok "#{}" is ''
|
ok "#{}" is ''
|
||||||
ok "#{}A#{} #{} #{}B#{}" is 'A B'
|
ok "#{}A#{} #{} #{}B#{}" is 'A B'
|
||||||
ok "\\\\\##" is '\\\\\##'
|
|
||||||
ok "\\\#{}" is '\\#{}'
|
ok "\\\#{}" is '\\#{}'
|
||||||
|
|
||||||
|
|
||||||
ok "I won #20 last night." is 'I won #20 last night.'
|
|
||||||
ok "I won ##{20} last night." is 'I won #20 last night.'
|
ok "I won ##{20} last night." is 'I won #20 last night.'
|
||||||
ok "I won ##20 last night." is 'I won ##20 last night.'
|
|
||||||
ok "I won ##{'#20'} last night." is 'I won ##20 last night.'
|
ok "I won ##{'#20'} last night." is 'I won ##20 last night.'
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,8 +40,8 @@ ok "values: #{list.join ' '}" is 'values: 0 1 2 3 4 5 6 7 8 9'
|
||||||
|
|
||||||
obj = {
|
obj = {
|
||||||
name: 'Joe'
|
name: 'Joe'
|
||||||
hi: -> "Hello #@name."
|
hi: -> "Hello #{@name}."
|
||||||
cya: -> "Hello #@name.".replace('Hello','Goodbye')
|
cya: -> "Hello #{@name}.".replace('Hello','Goodbye')
|
||||||
}
|
}
|
||||||
ok obj.hi() is "Hello Joe."
|
ok obj.hi() is "Hello Joe."
|
||||||
ok obj.cya() is "Goodbye Joe."
|
ok obj.cya() is "Goodbye Joe."
|
||||||
|
@ -65,10 +51,9 @@ ok "With #{"quotes"}" is 'With quotes'
|
||||||
ok 'With #{"quotes"}' is 'With #{"quotes"}'
|
ok 'With #{"quotes"}' is 'With #{"quotes"}'
|
||||||
|
|
||||||
ok "Where is #{obj["name"] + '?'}" is 'Where is Joe?'
|
ok "Where is #{obj["name"] + '?'}" is 'Where is Joe?'
|
||||||
ok "Where is #obj.name?" is 'Where is Joe?'
|
|
||||||
|
|
||||||
ok "Where is #{"the nested #{obj["name"]}"}?" is 'Where is the nested Joe?'
|
ok "Where is #{"the nested #{obj["name"]}"}?" is 'Where is the nested Joe?'
|
||||||
ok "Hello #{world ? "#hello"}" is 'Hello World'
|
ok "Hello #{world ? "#{hello}"}" is 'Hello World'
|
||||||
|
|
||||||
ok "Hello #{"#{"#{obj["name"]}" + '!'}"}" is 'Hello Joe!'
|
ok "Hello #{"#{"#{obj["name"]}" + '!'}"}" is 'Hello Joe!'
|
||||||
|
|
||||||
|
@ -82,7 +67,7 @@ ok a is "Hello Joe"
|
||||||
a = 1
|
a = 1
|
||||||
b = 2
|
b = 2
|
||||||
c = 3
|
c = 3
|
||||||
ok "#a#b#c" is '123'
|
ok "#{a}#{b}#{c}" is '123'
|
||||||
|
|
||||||
|
|
||||||
result = null
|
result = null
|
||||||
|
|
Loading…
Reference in a new issue