private Token unwindTo ( int targetIndent , Token copyFrom ) { assert dentsBuffer . isEmpty ( ) : dentsBuffer ; dentsBuffer . add ( createToken ( nlToken , copyFrom ) ) ; // To make things easier, we'll queue up ALL of the dedents, and then pop off the first one. // For example, here's how some text is analyzed: // // Text : Indentation : Action : Indents Deque // [ baseline ] : 0 : nothing : [0] // [ foo ] : 2 : INDENT : [0, 2] // [ bar ] : 3 : INDENT : [0, 2, 3] // [ baz ] : 0 : DEDENT x2 : [0] while ( true ) { int prevIndent = indentations . pop ( ) ; if ( prevIndent == targetIndent ) { break ; } if ( targetIndent > prevIndent ) { // "weird" condition above indentations . push ( prevIndent ) ; // restore previous indentation, since we've indented from it dentsBuffer . add ( createToken ( indentToken , copyFrom ) ) ; break ; } dentsBuffer . add ( createToken ( dedentToken , copyFrom ) ) ; } indentations . push ( targetIndent ) ; return dentsBuffer . remove ( ) ; }
Returns a DEDENT token and also queues up additional DEDENTS as necessary .