Skip to content
Browse files

Coco 16dcb4a: parenthesized expressions can now be indented

  • Loading branch information...
1 parent 0e4d589 commit 4ef947046680410ae514bb113dde9663305e53eb @jashkenas jashkenas committed Nov 20, 2010
Showing with 85 additions and 71 deletions.
  1. +2 −0 lib/grammar.js
  2. +7 −5 lib/lexer.js
  3. +65 −63 lib/parser.js
  4. +1 −0 src/grammar.coffee
  5. +2 −3 src/lexer.coffee
  6. +8 −0 test/test_strings.coffee
View
2 lib/grammar.js
@@ -326,6 +326,8 @@
Parenthetical: [
o('( Body )', function() {
return new Parens($2);
+ }), o('( INDENT Body OUTDENT )', function() {
+ return new Parens($3);
})
],
WhileSource: [
View
12 lib/lexer.js
@@ -1,5 +1,5 @@
(function() {
- var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, last, op, starts, _ref;
+ var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, last, op, starts, _ref;
var __indexOf = Array.prototype.indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
if (this[i] === item) return i;
@@ -474,7 +474,7 @@
throw new Error("unterminated " + (stack.pop()[0]) + " on line " + (this.line + 1));
};
Lexer.prototype.interpolateString = function(str, options) {
- var expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value, _len, _ref, _this;
+ var expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value, _len, _ref, _ref2, _this;
options == null && (options = {});
heredoc = options.heredoc, regex = options.regex;
tokens = [];
@@ -491,13 +491,16 @@
if (pi < i) {
tokens.push(['NEOSTRING', str.slice(pi, i)]);
}
- inner = expr.slice(1, -1).replace(LEADING_SPACES, '').replace(TRAILING_SPACES, '');
+ inner = expr.slice(1, -1);
if (inner.length) {
nested = new Lexer().tokenize(inner, {
line: this.line,
rewrite: false
});
nested.pop();
+ if (((_ref = nested[0]) != null ? _ref[0] : void 0) === 'TERMINATOR') {
+ nested.shift();
+ }
if (nested.length > 1) {
nested.unshift(['(', '(']);
nested.push([')', ')']);
@@ -523,7 +526,7 @@
this.token('(', '(');
}
for (i = 0, _len = tokens.length; i < _len; i++) {
- _ref = tokens[i], tag = _ref[0], value = _ref[1];
+ _ref2 = tokens[i], tag = _ref2[0], value = _ref2[1];
if (i) {
this.token('+', '+');
}
@@ -606,7 +609,6 @@
HEREDOC_INDENT = /\n+([^\n\S]*)/g;
ASSIGNED = /^\s*@?([$A-Za-z_][$\w]*|['"].*['"])[^\n\S]*?[:=][^:=>]/;
LINE_CONTINUER = /^\s*(?:,|\??\.(?!\.)|::)/;
- LEADING_SPACES = /^\s+/;
TRAILING_SPACES = /\s+$/;
NO_NEWLINE = /^(?:[-+*&|\/%=<>!.\\][<>=&|]*|and|or|is(?:nt)?|n(?:ot|ew)|delete|typeof|instanceof)$/;
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
View
128 lib/parser.js
65 additions, 63 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
1 src/grammar.coffee
@@ -389,6 +389,7 @@ grammar =
# the trick.
Parenthetical: [
o '( Body )', -> new Parens $2
+ o '( INDENT Body OUTDENT )', -> new Parens $3
]
# The condition portion of a while loop.
View
5 src/lexer.coffee
@@ -426,10 +426,11 @@ exports.Lexer = class Lexer
(expr = @balancedString str.slice(i+1), [['{', '}']])
continue
tokens.push ['NEOSTRING', str.slice(pi, i)] if pi < i
- inner = expr.slice(1, -1).replace(LEADING_SPACES, '').replace(TRAILING_SPACES, '')
+ inner = expr.slice(1, -1)
if inner.length
nested = new Lexer().tokenize inner, line: @line, rewrite: off
nested.pop()
+ nested.shift() if nested[0]?[0] is 'TERMINATOR'
if nested.length > 1
nested.unshift ['(', '(']
nested.push [')', ')']
@@ -585,8 +586,6 @@ ASSIGNED = /^\s*@?([$A-Za-z_][$\w]*|['"].*['"])[^\n\S]*?[:=][^:=>]/
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?!\.) | :: ) ///
-LEADING_SPACES = /^\s+/
-
TRAILING_SPACES = /\s+$/
NO_NEWLINE = /// ^ (?: # non-capturing group
View
8 test/test_strings.coffee
@@ -99,3 +99,11 @@ ok result is 'a bb c'
foo = "hello"
ok "#{foo.replace("\"", "")}" is 'hello'
+
+
+eq 'multiline nested "interpolations" work', """multiline #{
+ "nested #{
+ ok true
+ "\"interpolations\""
+ }"
+} work"""

0 comments on commit 4ef9470

Please sign in to comment.
Something went wrong with that request. Please try again.