From 7915ca548825f89232de3629d098f87251bff7b4 Mon Sep 17 00:00:00 2001 From: satyr Date: Fri, 1 Feb 2013 18:55:47 +0900 Subject: [PATCH] made JS literal escape like Markdown (jashkenas/coffee-script#1504) --- lib/lexer.js | 13 +++++++------ src/lexer.co | 9 +++++---- test/literal.co | 14 ++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/lexer.js b/lib/lexer.js index 9504f579f..ef393330c 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -1,4 +1,4 @@ -var string, TABS, unlines, enlines, enslash, reslash, camelize, character, KEYWORDS_SHARED, KEYWORDS_UNUSED, KEYWORDS, ID, SYMBOL, SPACE, MULTIDENT, SIMPLESTR, JSTOKEN, BSTOKEN, NUMBER, NUMBER_OMIT, REGEX, HEREGEX_OMIT, LASTDENT, INLINEDENT, NONASCII, OPENERS, CLOSERS, INVERSES, CHAIN, ARG, BLOCK_USERS, slice$ = [].slice; +var string, TABS, unlines, enlines, enslash, reslash, camelize, character, KEYWORDS_SHARED, KEYWORDS_UNUSED, KEYWORDS, ID, SYMBOL, SPACE, MULTIDENT, SIMPLESTR, BSTOKEN, JSTOKEN, NUMBER, NUMBER_OMIT, REGEX, HEREGEX_OMIT, LASTDENT, INLINEDENT, NONASCII, OPENERS, CLOSERS, INVERSES, CHAIN, ARG, BLOCK_USERS, slice$ = [].slice; exports.lex = function(code, options){ return (clone$(exports)).tokenize(code || '', options || {}); }; @@ -353,11 +353,12 @@ exports.doComment = function(code, index){ return this.countLines(comment).length; }; exports.doJS = function(code, lastIndex){ - var js, ref$; + var ref$, lit, js; JSTOKEN.lastIndex = lastIndex; - js = JSTOKEN.exec(code)[0] || this.carp('unterminated JS literal'); - this.token('LITERAL', (ref$ = Object(detab(js.slice(1, -1), this.dent)), ref$.js = true, ref$), true); - return this.countLines(js).length; + ref$ = JSTOKEN.exec(code), lit = ref$[0], js = ref$[2]; + lit || this.carp('unterminated JS literal'); + this.token('LITERAL', (ref$ = Object(detab(js, this.dent)), ref$.js = true, ref$), true); + return this.countLines(lit).length; }; exports.doRegex = function(code, index){ var divisible, ref$, input, body, flag; @@ -1455,8 +1456,8 @@ SYMBOL = /[-+*\/%&|^:]=|\.{1,3}|([-+&|@:])\1|[-~=|]>|[!=]==?|<(?:<(?:=|<{0,2})|[ SPACE = /[^\n\S]*(?:#.*)?/g; MULTIDENT = /(?:\s*#.*)*(?:\n([^\n\S]*))+/g; SIMPLESTR = /'[^\\']*(?:\\[\s\S][^\\']*)*'|/g; -JSTOKEN = /`[^\\`]*(?:\\[\s\S][^\\`]*)*`|/g; BSTOKEN = /\\(?:(\S[^\s,;)}\]]*)|\s*)/g; +JSTOKEN = /(`+)([^`][\s\S]*?)\1|/g; NUMBER = /0x[\dA-Fa-f][\dA-Fa-f_]*|([2-9]|[12]\d|3[0-6])r([\dA-Za-z]\w*)|((\d[\d_]*)(\.\d[\d_]*)?(?:e[+-]?\d[\d_]*)?)[$\w]*|/g; NUMBER_OMIT = /_+/g; REGEX = /\/([^[\/\n\\]*(?:(?:\\.|\[[^\]\n\\]*(?:\\.[^\]\n\\]*)*\])[^[\/\n\\]*)*)\/([gimy]{1,4}|\$?)|/g; diff --git a/src/lexer.co b/src/lexer.co index 757dadd0a..18dbbd5d7 100644 --- a/src/lexer.co +++ b/src/lexer.co @@ -244,9 +244,10 @@ exports import # Matches embedded JavaScript. doJS: (code, JSTOKEN.lastIndex) -> - js = JSTOKEN.exec code .0 or @carp 'unterminated JS literal' - @token \LITERAL Object(detab js.slice(1 -1), @dent) <<< {+js}, true - @countLines(js)length + [lit,, js] = JSTOKEN.exec code + lit or @carp 'unterminated JS literal' + @token \LITERAL Object(detab js, @dent) <<< {+js}, true + @countLines(lit)length # Matches a regular expression literal aka _regex_, # disambiguating from division operators. @@ -1004,8 +1005,8 @@ SYMBOL = // SPACE = /[^\n\S]*(?:#.*)?/g MULTIDENT = /(?:\s*#.*)*(?:\n([^\n\S]*))+/g SIMPLESTR = /'[^\\']*(?:\\[\s\S][^\\']*)*'|/g -JSTOKEN = /`[^\\`]*(?:\\[\s\S][^\\`]*)*`|/g BSTOKEN = // \\ (?: (\S[^\s,;)}\]]*) | \s* ) //g +JSTOKEN = /(`+)([^`][\s\S]*?)\1|/g NUMBER = // 0x[\dA-Fa-f][\dA-Fa-f_]* # hex diff --git a/test/literal.co b/test/literal.co index fad27ddcd..733b033ea 100644 --- a/test/literal.co +++ b/test/literal.co @@ -362,16 +362,14 @@ eq 11, ((, a) -> a)(, 11) ### JS Literal +ok `delete ! delete {}` -eq '\\`', ` +# multi{line,tick} +eq \` ``'`'`` +eq '``' ``` // Inline JS - "\\\`" -` - -i = 3 -`LABEL:` -while --i then while --i then `break LABEL` -eq i, 1 + '``' +``` `not` = -> !it eq false `not` true