Introducing the notion of 'indebt' to mirror 'outdebt', but for suppressed indentation with trailing operators etc. Issue #639.

This commit is contained in:
Jeremy Ashkenas 2010-09-08 22:46:13 -04:00
parent 18cbddff6a
commit 9bd3cca7c4
3 changed files with 23 additions and 6 deletions

View File

@ -26,6 +26,7 @@
this.i = 0;
this.line = o.line || 0;
this.indent = 0;
this.indebt = 0;
this.outdebt = 0;
this.indents = [];
this.tokens = [];
@ -245,20 +246,22 @@
size = indent.match(LAST_DENTS).reverse()[0].match(LAST_DENT)[1].length;
nextCharacter = this.match(NEXT_CHARACTER, 1);
noNewlines = nextCharacter === '.' || nextCharacter === ',' || this.unfinished();
if (size === this.indent) {
if (size - this.indebt === this.indent) {
if (noNewlines) {
return this.suppressNewlines();
}
return this.newlineToken(indent);
} else if (size > this.indent) {
if (noNewlines) {
this.indebt = size - this.indent;
return this.suppressNewlines();
}
diff = size - this.indent + this.outdebt;
this.token('INDENT', diff);
this.indents.push(diff);
this.outdebt = 0;
this.outdebt = (this.indebt = 0);
} else {
this.indebt = 0;
this.outdentToken(this.indent - size, noNewlines);
}
this.indent = size;

View File

@ -46,7 +46,8 @@ exports.Lexer = class Lexer
@i = 0 # Current character position we're parsing.
@line = o.line or 0 # The current line.
@indent = 0 # The current indentation level.
@outdebt = 0 # The under-outdentation of the last outdent.
@indebt = 0 # The over-indentation at the current level.
@outdebt = 0 # The under-outdentation at the current level.
@indents = [] # The stack of all current indentation levels.
@tokens = [] # Stream of parsed tokens in the form ['TYPE', value, line]
while @i < @code.length
@ -203,16 +204,19 @@ exports.Lexer = class Lexer
size = indent.match(LAST_DENTS).reverse()[0].match(LAST_DENT)[1].length
nextCharacter = @match NEXT_CHARACTER, 1
noNewlines = nextCharacter is '.' or nextCharacter is ',' or @unfinished()
if size is @indent
if size - @indebt is @indent
return @suppressNewlines() if noNewlines
return @newlineToken indent
else if size > @indent
return @suppressNewlines() if noNewlines
if noNewlines
@indebt = size - @indent
return @suppressNewlines()
diff = size - @indent + @outdebt
@token 'INDENT', diff
@indents.push diff
@outdebt = 0
@outdebt = @indebt = 0
else
@indebt = 0
@outdentToken @indent - size, noNewlines
@indent = size
true

View File

@ -118,3 +118,13 @@ isTrue = (x) -> x is true
if isTrue yes then i += 1
ok i is 2
# If/else with a suppressed indentation via assignment.
result =
if false then 10
else if no then 20
else if 0 then 30
else if NaN then 40
else 50
ok result is 50