Make the alternative layout rule cope with file pragmas
[ghc-hetmet.git] / compiler / parser / Lexer.x
index de0ccb6..43ddf7c 100644 (file)
@@ -1135,7 +1135,7 @@ do_layout_left span _buf _len = do
 setLine :: Int -> Action
 setLine code span buf len = do
   let line = parseUnsignedInteger buf len 10 octDecDigit
-  setSrcLoc (mkSrcLoc (srcSpanFile span) (fromIntegral line - 1) 0)
+  setSrcLoc (mkSrcLoc (srcSpanFile span) (fromIntegral line - 1) 1)
        -- subtract one: the line number refers to the *following* line
   _ <- popLexState
   pushLexState code
@@ -1144,6 +1144,7 @@ setLine code span buf len = do
 setFile :: Int -> Action
 setFile code span buf len = do
   let file = lexemeToFastString (stepOn buf) (len-2)
+  setAlrLastLoc noSrcSpan
   setSrcLoc (mkSrcLoc file (srcSpanEndLine span) (srcSpanEndCol span))
   _ <- popLexState
   pushLexState code
@@ -1981,7 +1982,8 @@ alternativeLayoutRuleToken t
          mExpectingOCurly <- getAlrExpectingOCurly
          let thisLoc = getLoc t
              thisCol = srcSpanStartCol thisLoc
-             newLine = srcSpanStartLine thisLoc > srcSpanEndLine lastLoc
+             newLine = (lastLoc == noSrcSpan)
+                    || (srcSpanStartLine thisLoc > srcSpanEndLine lastLoc)
          case (unLoc t, context, mExpectingOCurly) of
              -- I think our implicit open-curly handling is slightly
              -- different to John's, in how it interacts with newlines
@@ -1991,7 +1993,9 @@ alternativeLayoutRuleToken t
                     setNextToken t
                     lexTokenAlr
              (_, ALRLayout _ col : ls, Just expectingOCurly)
-              | thisCol > col ->
+              | (thisCol > col) ||
+                (thisCol == col &&
+                 isNonDecreasingIntentation expectingOCurly) ->
                  do setAlrExpectingOCurly Nothing
                     setALRContext (ALRLayout expectingOCurly thisCol : context)
                     setNextToken t
@@ -2089,6 +2093,10 @@ isALRclose ITccurly = True
 isALRclose ITcubxparen = True
 isALRclose _        = False
 
+isNonDecreasingIntentation :: ALRLayout -> Bool
+isNonDecreasingIntentation ALRLayoutDo = True
+isNonDecreasingIntentation _           = False
+
 containsCommas :: Token -> Bool
 containsCommas IToparen = True
 containsCommas ITobrack = True