diff --git a/Cokefile b/Cokefile index ae887aa7f..1eb1d89f1 100644 --- a/Cokefile +++ b/Cokefile @@ -95,6 +95,7 @@ task \build:browser task \bench, 'quick benchmark of compilation time', -> Lexer = require \./lib/lexer Rewriter = require \./lib/rewriter + Coco = require \./lib/coco co = coreSources().map(-> slurp it).join \\n fmt = -> "#{bold}#{ " #{it}".slice -4 }#{reset} ms" total = nc = 0 diff --git a/lib/rewriter.js b/lib/rewriter.js index 71644ba29..b3c0394ad 100644 --- a/lib/rewriter.js +++ b/lib/rewriter.js @@ -4,8 +4,7 @@ var BALANCED_PAIRS, INVERSES, EXPR_START, EXPR_END, left, rite, ARG, _i, _len, _ exports.rewrite = rewrite; exports.able = able; function rewrite(it){ - removeLeadingTerminators(it); - removeMidExpressionTerminators(it); + removeTerminators(it); closeCalls(it); addImplicitIndentation(it); tagPostfixConditionals(it); @@ -16,40 +15,15 @@ function rewrite(it){ expandNumbers(it); return it; } -function detectEnd(tokens, i, ok, go){ - var levels, token, tag; - levels = 0; - while (token = tokens[i]) { - if (!levels) { - if (ok(token, i)) { - return go(token, i); - } - } else if (0 > levels) { - return go(token, i - 1); - } - tag = token[0]; - if (__indexOf.call(EXPR_START, tag) >= 0) { - ++levels; - } else if (__indexOf.call(EXPR_END, tag) >= 0) { - --levels; - } - ++i; - } -} -function removeLeadingTerminators(tokens){ - var i, tag, _len; - for (i = 0, _len = tokens.length; i < _len; ++i) { - tag = tokens[i][0]; - if (tag !== 'TERMINATOR') { +function removeTerminators(tokens){ + var i, that; + i = -1; + while (that = tokens[++i]) { + if (that[0] !== 'TERMINATOR') { break; } } - if (i) { - tokens.splice(0, i); - } -} -function removeMidExpressionTerminators(tokens){ - var i, that; + i && tokens.splice(0, i); i = 1; while (that = tokens[++i]) { if (tokens[i - 1][0] !== 'TERMINATOR') { @@ -397,6 +371,26 @@ function expandNumbers(tokens){ } } } +function detectEnd(tokens, i, ok, go){ + var levels, token, tag; + levels = 0; + while (token = tokens[i]) { + if (!levels) { + if (ok(token, i)) { + return go(token, i); + } + } else if (0 > levels) { + return go(token, i - 1); + } + tag = token[0]; + if (__indexOf.call(EXPR_START, tag) >= 0) { + ++levels; + } else if (__indexOf.call(EXPR_END, tag) >= 0) { + --levels; + } + ++i; + } +} function able(tokens, i, call){ var tag, _ref; i == null && (i = tokens.length); diff --git a/src/rewriter.co b/src/rewriter.co index bd3714dd6..7ef34234c 100644 --- a/src/rewriter.co +++ b/src/rewriter.co @@ -17,38 +17,24 @@ exports import {rewrite, able} # corrected before implicit parentheses can be wrapped around blocks of code. function rewrite -> - removeLeadingTerminators it - removeMidExpressionTerminators it - closeCalls it - addImplicitIndentation it - tagPostfixConditionals it - addImplicitBraces it - addImplicitParentheses it - ensureBalance it - rewriteClosingParens it - expandNumbers it + removeTerminators it + closeCalls it + addImplicitIndentation it + tagPostfixConditionals it + addImplicitBraces it + addImplicitParentheses it + ensureBalance it + rewriteClosingParens it + expandNumbers it it -function detectEnd (tokens, i, ok, go) -> - levels = 0 - while token = tokens[i] - if not levels then return go token, i if ok token, i - else if 0 > levels then return go token, i-1 - [tag] = token - if tag of EXPR_START then ++levels - else if tag of EXPR_END then --levels - ++i - void - -# Dispatch leading terminators that would introduce ambiguity in the grammar. -function removeLeadingTerminators (tokens) -> - break unless tag is \TERMINATOR for [tag], i of tokens - tokens.splice 0, i if i - void - -# Some blocks occur in the middle of expressions--when we're expecting -# this, remove their trailing terminators. -function removeMidExpressionTerminators (tokens) -> +# - Dispatch leading terminators that would introduce ambiguity in the grammar. +# - Some blocks occur in the middle of expressions. +# Remove their trailing terminators here to simplify things. +function removeTerminators (tokens) -> + i = -1 + break unless that.0 is \TERMINATOR while tokens[++i] + i and tokens.splice 0, i i = 1 while tokens[++i] continue unless tokens[i-1].0 is \TERMINATOR @@ -277,6 +263,21 @@ function expandNumbers (tokens) -> i += ts.length - 1 void +### Helpers + +# Seeks `tokens` from index `i` for a token of the same level matching `ok`, +# then calls `go`. +function detectEnd (tokens, i, ok, go) -> + levels = 0 + while token = tokens[i] + if not levels then return go token, i if ok token, i + else if 0 > levels then return go token, i-1 + [tag] = token + if tag of EXPR_START then ++levels + else if tag of EXPR_END then --levels + ++i + void + # Checks whether or not the previous token is {index,`call`}able. function able (tokens, i = tokens.length, call) -> tag = tokens[i-1].0 @@ -294,7 +295,7 @@ function indexOfPair (tokens, i) -> function carp (msg, lno) -> throw SyntaxError msg + ' on line ' + -~lno -#### Constants +### Constants # List of the token pairs that must be balanced. BALANCED_PAIRS = [