INDENTABLE.add(SCLTerminals.WHEN);
INDENTABLE.add(SCLTerminals.FOLLOWS);
INDENTABLE.add(SCLTerminals.EQ);
+ INDENTABLE.add(SCLTerminals.LAMBDA_MATCH);
+ INDENTABLE.add(SCLTerminals.THEN_AFTER_WHEN);
NO_SEMICOLON_BEFORE.add(SCLTerminals.EOF);
NO_SEMICOLON_BEFORE.add(SCLTerminals.SYMBOL);
NO_SEMICOLON_BEFORE.add(SCLTerminals.THEN);
- NO_SEMICOLON_BEFORE.add(SCLTerminals.ELSE);
NO_SEMICOLON_BEFORE.add(SCLTerminals.IN);
NO_SEMICOLON_BEFORE.add(SCLTerminals.RBRACE);
NO_SEMICOLON_BEFORE.add(SCLTerminals.RBRACKET);
NO_SEMICOLON_BEFORE.add(SCLTerminals.RPAREN);
+ NO_SEMICOLON_BEFORE.add(SCLTerminals.SEMICOLON);
NO_SEMICOLON_AFTER.add(SCLTerminals.EOF);
NO_SEMICOLON_AFTER.add(SCLTerminals.SYMBOL);
Token[] queue = new Token[16];
int queuePos=0, queueSize=0;
TIntArrayList indentations = new TIntArrayList();
+ TIntArrayList indentationTokens = new TIntArrayList();
Token curToken = null;
int lineStart = 0;
boolean firstTokenOfLine = true;
{
indentations.add(0);
+ indentationTokens.add(SCLTerminals.EOF);
}
public SCLPostLexer(SCLLexer lexer) {
}
private void push(Token symbol) {
+ /*System.out.println("TOKEN " + symbol.text + " (" + SCLParser.TERMINAL_NAMES[symbol.id] + ")" +
+ " ["
+ + Locations.beginOf(symbol.location) + ".."
+ + Locations.endOf(symbol.location) + "]");*/
if(queueSize == queue.length)
queue = Arrays.copyOf(queue, queueSize*2);
queue[queueSize++] = symbol;
int symbolEnd = Locations.endOf(symbol.location);
if(INDENTABLE.contains(prevTokenId) && symbolId != SCLTerminals.LBRACE) {
- if(prevTokenId == SCLTerminals.LET)
- indentations.add(-1);
push(new Token(SCLTerminals.LBRACE, symbolStart, symbolStart, "implicit {"));
int symbolIndentation = symbolStart-lineStart;
//System.out.println("symbolIndentation = " + symbolIndentation);
indentations.add(symbolIndentation);
+ indentationTokens.add(prevTokenId);
firstTokenOfLine = false;
}
else if(firstTokenOfLine) {
//System.out.println("level = " + level);
if(indentations.get(indentations.size()-1) >= level) {
while(indentations.get(indentations.size()-1) > level) {
+ indentationTokens.removeAt(indentations.size()-1);
indentations.removeAt(indentations.size()-1);
int loc = Locations.endOf(prevToken.location);
push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }"));
}
- if(indentations.get(indentations.size()-1) == level)
+ if(indentations.get(indentations.size()-1) == level && symbolId != SCLTerminals.ELSE)
push(new Token(SCLTerminals.SEMICOLON, symbolStart, symbolStart, "implicit ;"));
}
}
case SCLTerminals.LPAREN:
case SCLTerminals.LBRACKET:
case SCLTerminals.IF:
+ case SCLTerminals.WHEN:
+ case SCLTerminals.LET:
indentations.add(-1);
+ indentationTokens.add(symbolId);
push(symbol);
return;
+ case SCLTerminals.THEN:
+ /*for(int tt : indentationTokens.toArray())
+ System.out.print(SCLParser.TERMINAL_NAMES[tt] + " ");
+ System.out.println();*/
+ if(prevTokenId == SCLTerminals.COMMA) {
+ // for list comprehension syntax
+ push(symbol);
+ break;
+ }
case SCLTerminals.RBRACE:
case SCLTerminals.RPAREN:
case SCLTerminals.RBRACKET:
- case SCLTerminals.ELSE:
+ //case SCLTerminals.ELSE:
case SCLTerminals.IN:
- while(!indentations.isEmpty() && indentations.removeAt(indentations.size()-1) >= 0) {
- int loc = Locations.endOf(prevToken.location);
- push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }"));
+ int removedToken = SCLTerminals.EOF;
+ while(!indentations.isEmpty()) {
+ removedToken = indentationTokens.removeAt(indentations.size()-1);
+ //System.out.println(" removed " + SCLParser.TERMINAL_NAMES[removedToken]);
+ if(indentations.removeAt(indentations.size()-1) < 0)
+ break;
+ long loc = prevToken != null ? Locations.location(Locations.endOf(prevToken.location), Locations.endOf(prevToken.location)) : symbol.location;
+ push(new Token(SCLTerminals.RBRACE, loc, "implicit }"));
}
if(indentations.isEmpty())
throw error(symbolStart, symbolEnd, "No corresponding opening parenthesis for '" + symbol.text + "'.");
+ if(symbolId == SCLTerminals.THEN && removedToken == SCLTerminals.WHEN)
+ curToken = symbol = new Token(SCLTerminals.THEN_AFTER_WHEN, symbol.location, symbol.text);
push(symbol);
- return;
- case SCLTerminals.THEN: // 'then' both closes and opens a block
- while(!indentations.isEmpty() && indentations.removeAt(indentations.size()-1) >= 0) {
- int loc = Locations.endOf(prevToken.location);
- push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }"));
- }
- if(indentations.isEmpty())
- throw error(symbolStart, symbolEnd, "No corresponding opening parenthesis for '" + symbol.text + "'.");
- push(symbol);
- indentations.add(-1);
+ //if(symbolId == SCLTerminals.THEN)
+ // indentations.add(-1);
return;
case SCLTerminals.EOF:
while(indentations.size() > 1 && indentations.get(indentations.size()-1) >= 0) {
- int loc = Locations.endOf(prevToken.location);
- push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }"));
+ long loc = prevToken != null ? Locations.location(Locations.endOf(prevToken.location), Locations.endOf(prevToken.location)) : symbol.location;
+ push(new Token(SCLTerminals.RBRACE, loc, "implicit }"));
+ indentationTokens.removeAt(indentations.size()-1);
indentations.removeAt(indentations.size()-1);
}
if(indentations.size() > 1)