getting there with the rewriter

This commit is contained in:
Jeremy Ashkenas 2010-01-30 17:47:19 -05:00
parent 557cdbba71
commit c6457e010d
2 changed files with 62 additions and 2 deletions

View File

@ -53,7 +53,7 @@
this.remove_mid_expression_newlines();
this.move_commas_outside_outdents();
this.close_open_calls_and_indexes();
// this.add_implicit_parentheses()
this.add_implicit_parentheses();
this.add_implicit_indentation();
// this.ensure_balance(BALANCED_PAIRS)
// this.rewrite_closing_parens()
@ -182,6 +182,44 @@
});
})(this));
};
// Methods may be optionally called without parentheses, for simple cases.
// Insert the implicit parentheses here, so that the parser doesn't have to
// deal with them.
re.prototype.add_implicit_parentheses = function add_implicit_parentheses() {
var stack;
stack = [0];
return this.scan_tokens((function(__this) {
var __func = function(prev, token, post, i) {
var __i, __j, __k, __l, idx, last, size, tmp;
if (token[0] === 'INDENT') {
stack.push(0);
}
if (token[0] === 'OUTDENT') {
last = stack.pop();
stack[stack.length - 1] += last;
}
if (stack[stack.length - 1] > 0 && (IMPLICIT_END.indexOf(token[0]) >= 0 || !(typeof post !== "undefined" && post !== null))) {
idx = token[0] === 'OUTDENT' ? i + 1 : i;
__k = 0; __l = stack[stack.length - 1];
for (__j=0, tmp=__k; (__k <= __l ? tmp < __l : tmp > __l); (__k <= __l ? tmp += 1 : tmp -= 1), __j++) {
this.tokens.splice(idx, 0, ['CALL_END', ')']);
}
size = stack[stack.length - 1] + 1;
stack[stack.length - 1] = 0;
return size;
}
if (!(prev && IMPLICIT_FUNC.indexOf(prev[0]) >= 0 && IMPLICIT_CALL.indexOf(token[0]) >= 0)) {
return 1;
}
this.tokens.splice(i, 0, ['CALL_START', '(']);
stack[stack.length - 1] += 1;
return 2;
};
return (function() {
return __func.apply(__this, arguments);
});
})(this));
};
// Because our grammar is LALR(1), it can't handle some single-line
// expressions that lack ending delimiters. Use the lexer to add the implicit
// blocks, so it doesn't need to.

View File

@ -45,7 +45,7 @@ re::rewrite: (tokens) ->
this.remove_mid_expression_newlines()
this.move_commas_outside_outdents()
this.close_open_calls_and_indexes()
# this.add_implicit_parentheses()
this.add_implicit_parentheses()
this.add_implicit_indentation()
# this.ensure_balance(BALANCED_PAIRS)
# this.rewrite_closing_parens()
@ -132,6 +132,28 @@ re::close_open_calls_and_indexes: ->
brackets[brackets.length - 1] -= 1
return 1
# Methods may be optionally called without parentheses, for simple cases.
# Insert the implicit parentheses here, so that the parser doesn't have to
# deal with them.
re::add_implicit_parentheses: ->
stack: [0]
this.scan_tokens (prev, token, post, i) =>
stack.push(0) if token[0] is 'INDENT'
if token[0] is 'OUTDENT'
last: stack.pop()
stack[stack.length - 1] += last
if stack[stack.length - 1] > 0 and (IMPLICIT_END.indexOf(token[0]) >= 0 or !post?)
idx: if token[0] is 'OUTDENT' then i + 1 else i
for tmp in [0...stack[stack.length - 1]]
this.tokens.splice(idx, 0, ['CALL_END', ')'])
size: stack[stack.length - 1] + 1
stack[stack.length - 1]: 0
return size
return 1 unless prev and IMPLICIT_FUNC.indexOf(prev[0]) >= 0 and IMPLICIT_CALL.indexOf(token[0]) >= 0
this.tokens.splice(i, 0, ['CALL_START', '('])
stack[stack.length - 1] += 1
return 2
# Because our grammar is LALR(1), it can't handle some single-line
# expressions that lack ending delimiters. Use the lexer to add the implicit
# blocks, so it doesn't need to.