mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
implementing string interpolation using string interpolation
This commit is contained in:
parent
18e5f72a84
commit
15b00cb3ca
2 changed files with 34 additions and 28 deletions
38
lib/lexer.js
38
lib/lexer.js
|
@ -184,7 +184,7 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
doc = this.sanitize_heredoc(match[2] || match[4]);
|
doc = this.sanitize_heredoc(match[2] || match[4]);
|
||||||
this.token('STRING', '"' + doc + '"');
|
this.token('STRING', "\"" + doc + "\"");
|
||||||
this.line += count(match[1], "\n");
|
this.line += count(match[1], "\n");
|
||||||
this.i += match[1].length;
|
this.i += match[1].length;
|
||||||
return true;
|
return true;
|
||||||
|
@ -394,19 +394,19 @@
|
||||||
// Error for when you try to use a forbidden word in JavaScript as
|
// Error for when you try to use a forbidden word in JavaScript as
|
||||||
// an identifier.
|
// an identifier.
|
||||||
Lexer.prototype.identifier_error = function identifier_error(word) {
|
Lexer.prototype.identifier_error = function identifier_error(word) {
|
||||||
throw new Error('SyntaxError: Reserved word "' + word + '" on line ' + this.line);
|
throw new Error("SyntaxError: Reserved word \"" + word + "\" on line " + this.line);
|
||||||
};
|
};
|
||||||
// Error for when you try to assign to a reserved word in JavaScript,
|
// Error for when you try to assign to a reserved word in JavaScript,
|
||||||
// like "function" or "default".
|
// like "function" or "default".
|
||||||
Lexer.prototype.assignment_error = function assignment_error() {
|
Lexer.prototype.assignment_error = function assignment_error() {
|
||||||
throw new Error('SyntaxError: Reserved word "' + this.value() + '" on line ' + this.line + ' can\'t be assigned');
|
throw new Error("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + this.line + " can't be assigned");
|
||||||
};
|
};
|
||||||
// Expand variables and expressions inside double-quoted strings using
|
// Expand variables and expressions inside double-quoted strings using
|
||||||
// [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).
|
||||||
// "Hello $name."
|
// "Hello $name."
|
||||||
// "Hello ${name.capitalize()}."
|
// "Hello ${name.capitalize()}."
|
||||||
Lexer.prototype.interpolate_string = function interpolate_string(str) {
|
Lexer.prototype.interpolate_string = function interpolate_string(str) {
|
||||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, before, contents, each, group, i, interp, lexer, match, nested, prev, quote, tok, tokens;
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, before, each, group, i, inner, interp, lexer, match, nested, prev, quote, tok, tokens;
|
||||||
if (str.length < 3 || str.substring(0, 1) !== '"') {
|
if (str.length < 3 || str.substring(0, 1) !== '"') {
|
||||||
return this.token('STRING', str);
|
return this.token('STRING', str);
|
||||||
} else {
|
} else {
|
||||||
|
@ -422,22 +422,24 @@
|
||||||
before = _a[1];
|
before = _a[1];
|
||||||
interp = _a[2];
|
interp = _a[2];
|
||||||
if (before.substring(before.length - 1) === '\\') {
|
if (before.substring(before.length - 1) === '\\') {
|
||||||
|
prev = before.substring(0, before.length - 1);
|
||||||
if (before.length) {
|
if (before.length) {
|
||||||
tokens.push(['STRING', quote + before.substring(0, before.length - 1) + '$' + interp + quote]);
|
tokens.push(['STRING', quote + prev + "$" + interp + quote]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (before.length) {
|
if (before.length) {
|
||||||
tokens.push(['STRING', quote + before + quote]);
|
tokens.push(['STRING', quote + before + quote]);
|
||||||
}
|
}
|
||||||
if (interp.substring(0, 1) === '{') {
|
if (interp.substring(0, 1) === '{') {
|
||||||
nested = lexer.tokenize('(' + interp.substring(1, interp.length - 1) + ')', {
|
inner = interp.substring(1, interp.length - 1);
|
||||||
|
nested = lexer.tokenize("(" + inner + ")", {
|
||||||
rewrite: false
|
rewrite: false
|
||||||
});
|
});
|
||||||
nested.pop();
|
nested.pop();
|
||||||
tokens.push(['TOKENS', nested]);
|
tokens.push(['TOKENS', nested]);
|
||||||
} else {
|
} else {
|
||||||
if (interp.substring(0, 1) === '@') {
|
if (interp.substring(0, 1) === '@') {
|
||||||
interp = 'this.' + interp.substring(1);
|
interp = "this." + (interp.substring(1));
|
||||||
}
|
}
|
||||||
tokens.push(['IDENTIFIER', interp]);
|
tokens.push(['IDENTIFIER', interp]);
|
||||||
}
|
}
|
||||||
|
@ -455,19 +457,21 @@
|
||||||
prev = _f[0];
|
prev = _f[0];
|
||||||
tok = _f[1];
|
tok = _f[1];
|
||||||
if (tok[0] === 'STRING' && prev[0] === 'STRING') {
|
if (tok[0] === 'STRING' && prev[0] === 'STRING') {
|
||||||
contents = quote + prev[1].substring(1, prev[1].length - 1) + tok[1].substring(1, tok[1].length - 1) + quote;
|
_g = [prev[1].substring(1, prev[1].length - 1), tok[1].substring(1, tok[1].length - 1)];
|
||||||
tokens.splice(i - 1, 2, ['STRING', contents]);
|
prev = _g[0];
|
||||||
|
tok = _g[1];
|
||||||
|
tokens.splice(i - 1, 2, ['STRING', quote + prev + tok + quote]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_g = []; _h = tokens;
|
_h = []; _i = tokens;
|
||||||
for (i = 0, _i = _h.length; i < _i; i++) {
|
for (i = 0, _j = _i.length; i < _j; i++) {
|
||||||
each = _h[i];
|
each = _i[i];
|
||||||
_g.push((function() {
|
_h.push((function() {
|
||||||
if (each[0] === 'TOKENS') {
|
if (each[0] === 'TOKENS') {
|
||||||
_j = each[1];
|
_k = each[1];
|
||||||
for (_k = 0, _l = _j.length; _k < _l; _k++) {
|
for (_l = 0, _m = _k.length; _l < _m; _l++) {
|
||||||
nested = _j[_k];
|
nested = _k[_l];
|
||||||
this.token(nested[0], nested[1]);
|
this.token(nested[0], nested[1]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -478,7 +482,7 @@
|
||||||
}
|
}
|
||||||
}).call(this));
|
}).call(this));
|
||||||
}
|
}
|
||||||
return _g;
|
return _h;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
|
@ -177,7 +177,7 @@ exports.Lexer: class Lexer
|
||||||
heredoc_token: ->
|
heredoc_token: ->
|
||||||
return false unless match = @chunk.match(HEREDOC)
|
return false unless match = @chunk.match(HEREDOC)
|
||||||
doc: @sanitize_heredoc match[2] or match[4]
|
doc: @sanitize_heredoc match[2] or match[4]
|
||||||
@token 'STRING', '"' + doc + '"'
|
@token 'STRING', "\"$doc\""
|
||||||
@line += count match[1], "\n"
|
@line += count match[1], "\n"
|
||||||
@i += match[1].length
|
@i += match[1].length
|
||||||
true
|
true
|
||||||
|
@ -307,7 +307,7 @@ exports.Lexer: class Lexer
|
||||||
# indentation on the left-hand side.
|
# indentation on the left-hand side.
|
||||||
sanitize_heredoc: (doc) ->
|
sanitize_heredoc: (doc) ->
|
||||||
indent: (doc.match(HEREDOC_INDENT) or ['']).sort()[0]
|
indent: (doc.match(HEREDOC_INDENT) or ['']).sort()[0]
|
||||||
doc.replace(new RegExp("^" + indent, 'gm'), '')
|
doc.replace(new RegExp("^" +indent, 'gm'), '')
|
||||||
.replace(MULTILINER, "\\n")
|
.replace(MULTILINER, "\\n")
|
||||||
.replace(/"/g, '\\"')
|
.replace(/"/g, '\\"')
|
||||||
|
|
||||||
|
@ -335,12 +335,12 @@ exports.Lexer: class Lexer
|
||||||
# Error for when you try to use a forbidden word in JavaScript as
|
# Error for when you try to use a forbidden word in JavaScript as
|
||||||
# an identifier.
|
# an identifier.
|
||||||
identifier_error: (word) ->
|
identifier_error: (word) ->
|
||||||
throw new Error 'SyntaxError: Reserved word "' + word + '" on line ' + @line
|
throw new Error "SyntaxError: Reserved word \"$word\" on line $@line"
|
||||||
|
|
||||||
# Error for when you try to assign to a reserved word in JavaScript,
|
# Error for when you try to assign to a reserved word in JavaScript,
|
||||||
# like "function" or "default".
|
# like "function" or "default".
|
||||||
assignment_error: ->
|
assignment_error: ->
|
||||||
throw new Error 'SyntaxError: Reserved word "' + @value() + '" on line ' + @line + ' can\'t be assigned'
|
throw new Error "SyntaxError: Reserved word \"${@value()}\" on line $@line can't be assigned"
|
||||||
|
|
||||||
# Expand variables and expressions inside double-quoted strings using
|
# Expand variables and expressions inside double-quoted strings using
|
||||||
# [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).
|
||||||
|
@ -361,26 +361,28 @@ exports.Lexer: class Lexer
|
||||||
if match
|
if match
|
||||||
[group, before, interp]: match
|
[group, before, interp]: match
|
||||||
if before.substring(before.length - 1) is '\\'
|
if before.substring(before.length - 1) is '\\'
|
||||||
tokens.push ['STRING', quote + before.substring(0, before.length - 1) + '$' + interp + quote] if before.length
|
prev: before.substring(0, before.length - 1)
|
||||||
|
tokens.push ['STRING', "$quote$prev$$interp$quote"] if before.length
|
||||||
else
|
else
|
||||||
tokens.push ['STRING', quote + before + quote] if before.length
|
tokens.push ['STRING', "$quote$before$quote"] if before.length
|
||||||
if interp.substring(0, 1) is '{'
|
if interp.substring(0, 1) is '{'
|
||||||
nested: lexer.tokenize '(' + interp.substring(1, interp.length - 1) + ')', {rewrite: no}
|
inner: interp.substring(1, interp.length - 1)
|
||||||
|
nested: lexer.tokenize "($inner)", {rewrite: no}
|
||||||
nested.pop()
|
nested.pop()
|
||||||
tokens.push ['TOKENS', nested]
|
tokens.push ['TOKENS', nested]
|
||||||
else
|
else
|
||||||
interp: 'this.' + interp.substring(1) if interp.substring(0, 1) is '@'
|
interp: "this.${ interp.substring(1) }" if interp.substring(0, 1) is '@'
|
||||||
tokens.push ['IDENTIFIER', interp]
|
tokens.push ['IDENTIFIER', interp]
|
||||||
str: str.substring(group.length)
|
str: str.substring(group.length)
|
||||||
else
|
else
|
||||||
tokens.push ['STRING', quote + str + quote]
|
tokens.push ['STRING', "$quote$str$quote"]
|
||||||
str: ''
|
str: ''
|
||||||
if tokens.length > 1
|
if tokens.length > 1
|
||||||
for i in [tokens.length - 1..1]
|
for i in [tokens.length - 1..1]
|
||||||
[prev, tok]: [tokens[i - 1], tokens[i]]
|
[prev, tok]: [tokens[i - 1], tokens[i]]
|
||||||
if tok[0] is 'STRING' and prev[0] is 'STRING'
|
if tok[0] is 'STRING' and prev[0] is 'STRING'
|
||||||
contents: quote + prev[1].substring(1, prev[1].length - 1) + tok[1].substring(1, tok[1].length - 1) + quote
|
[prev, tok]: [prev[1].substring(1, prev[1].length - 1), tok[1].substring(1, tok[1].length - 1)]
|
||||||
tokens.splice i - 1, 2, ['STRING', contents]
|
tokens.splice i - 1, 2, ['STRING', "$quote$prev$tok$quote"]
|
||||||
for each, i in tokens
|
for each, i in tokens
|
||||||
if each[0] is 'TOKENS'
|
if each[0] is 'TOKENS'
|
||||||
@token nested[0], nested[1] for nested in each[1]
|
@token nested[0], nested[1] for nested in each[1]
|
||||||
|
|
Loading…
Add table
Reference in a new issue