]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLPostLexer.java
Merged changes from feature/scl to master.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / parsing / parser / SCLPostLexer.java
index 866fb8c985c4126b6e368746b83c767953c66cda..3d3b7b2f512033d90e13119b8edbfa8960cbaafd 100644 (file)
@@ -31,15 +31,17 @@ public class SCLPostLexer {
         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);
@@ -49,6 +51,7 @@ public class SCLPostLexer {
     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;
@@ -56,6 +59,7 @@ public class SCLPostLexer {
             
     {
         indentations.add(0);
+        indentationTokens.add(SCLTerminals.EOF);
     }
     
     public SCLPostLexer(SCLLexer lexer) {
@@ -125,6 +129,7 @@ public class SCLPostLexer {
             int symbolIndentation = symbolStart-lineStart;
             //System.out.println("symbolIndentation = " + symbolIndentation);
             indentations.add(symbolIndentation);
+            indentationTokens.add(prevTokenId);
             firstTokenOfLine = false;
         }
         else if(firstTokenOfLine) {
@@ -135,11 +140,12 @@ public class SCLPostLexer {
                 //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 ;"));
                 }
             }
@@ -151,37 +157,48 @@ public class SCLPostLexer {
         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)