diff --git a/lib/lexer.js b/lib/lexer.js index 762144b0..c5d2b467 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -47,7 +47,7 @@ ASSIGNMENT = /^(:|=)$/; // Interpolation matching regexes. INTERPOLATED_EXPRESSION = /(^|[\s\S]*?(?:[\\]|\\\\)?)(\${[\s\S]*?(?:[^\\]|\\\\)})/; - INTERPOLATED_IDENTIFIER = /(^|[\s\S]*?(?:[\\]|\\\\)?)(\$([a-zA-Z_]\w*))/; + INTERPOLATED_IDENTIFIER = /(^|[\s\S]*?(?:[\\]|\\\\)?)(\$([a-zA-Z_@]\w*))/; // Token cleaning regexes. JS_CLEANER = /(^`|`$)/g; MULTILINER = /\n/g; @@ -408,7 +408,7 @@ // "Hello $name." // "Hello ${name.capitalize()}." Lexer.prototype.interpolate_string = function interpolate_string(str) { - var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, before, contents, each, expression, expression_match, group, i, identifier, identifier_match, lexer, nested, prev, quote, tok, tokens; + var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, before, contents, each, expression, expression_match, group, i, id, identifier, identifier_match, lexer, nested, prev, quote, tok, tokens; if (str.length < 3 || str.substring(0, 1) !== '"') { return this.token('STRING', str); } else { @@ -431,7 +431,7 @@ if (before.length) { tokens.push(['STRING', quote + before + quote]); } - nested = lexer.tokenize('(' + expression.substring(2, expression.length - 1) + ')', { + nested = lexer.tokenize(expression.substring(2, expression.length - 1), { rewrite: false }); nested.pop(); @@ -453,7 +453,11 @@ if (before.length) { tokens.push(['STRING', quote + before + quote]); } - tokens.push(['IDENTIFIER', identifier.substring(1)]); + id = identifier.substring(1); + if (id.substring(0, 1) === '@') { + id = 'this.' + id.substring(1); + } + tokens.push(['IDENTIFIER', id]); } str = str.substring(group.length); } else { diff --git a/src/lexer.coffee b/src/lexer.coffee index 9ef5002a..c86da8cb 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -73,7 +73,7 @@ ASSIGNMENT : /^(:|=)$/ # Interpolation matching regexes. INTERPOLATED_EXPRESSION: /(^|[\s\S]*?(?:[\\]|\\\\)?)(\${[\s\S]*?(?:[^\\]|\\\\)})/ -INTERPOLATED_IDENTIFIER: /(^|[\s\S]*?(?:[\\]|\\\\)?)(\$([a-zA-Z_]\w*))/ +INTERPOLATED_IDENTIFIER: /(^|[\s\S]*?(?:[\\]|\\\\)?)(\$([a-zA-Z_@]\w*))/ # Token cleaning regexes. JS_CLEANER : /(^`|`$)/g @@ -367,7 +367,7 @@ exports.Lexer: class Lexer tokens.push ['STRING', quote + before.substring(0, before.length - 1) + expression + quote] if before.length else tokens.push ['STRING', quote + before + quote] if before.length - nested: lexer.tokenize '(' + expression.substring(2, expression.length - 1) + ')', {rewrite: no} + nested: lexer.tokenize expression.substring(2, expression.length - 1), {rewrite: no} nested.pop() tokens.push ['TOKENS', nested] str: str.substring(group.length) @@ -379,7 +379,9 @@ exports.Lexer: class Lexer tokens.push ['STRING', quote + before.substring(0, before.length - 1) + identifier + quote] if before.length else tokens.push ['STRING', quote + before + quote] if before.length - tokens.push ['IDENTIFIER', identifier.substring(1)] + id: identifier.substring(1) + id: 'this.' + id.substring(1) if id.substring(0, 1) is '@' + tokens.push ['IDENTIFIER', id] str: str.substring(group.length) else tokens.push ['STRING', quote + str + quote] diff --git a/test/test_string_interpolation.coffee b/test/test_string_interpolation.coffee index 6d6687f5..87152447 100644 --- a/test/test_string_interpolation.coffee +++ b/test/test_string_interpolation.coffee @@ -40,3 +40,9 @@ ok "${hello + ' ' + world + '!'}" is 'Hello World!' list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ok "values: ${list.join(', ')}, length: ${list.length}." is 'values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, length: 10.' ok "values: ${list.join ' '}" is 'values: 0 1 2 3 4 5 6 7 8 9' + +obj: { + name: 'Joe' + hi: -> "Hello $@name." +} +ok obj.hi() is "Hello Joe."