From f5345f38150f9491b4b4899c9ee0a35aa68826a4 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Thu, 26 Apr 2007 02:46:19 +0000 Subject: [PATCH] Handle lines consisting of only spaces, and report errors better --- fco2/Indentation.hs | 25 ++++++++++++++++++------- fco2/Parse.hs | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/fco2/Indentation.hs b/fco2/Indentation.hs index 7222e25..0a83c53 100644 --- a/fco2/Indentation.hs +++ b/fco2/Indentation.hs @@ -2,6 +2,7 @@ module Indentation (removeIndentation, indentMarker, outdentMarker, eolMarker) where import Control.Monad +import Control.Monad.Error import Control.Monad.State import Data.List @@ -24,19 +25,28 @@ eolMarker = "__eol" -- FIXME: There's probably a nicer way of doing this. -- (Well, trivially, use a WriterT...) -removeIndentation :: String -> PassM String -removeIndentation orig - = do modify $ (\ps -> ps { psIndentLinesIn = lines orig, +-- | Preprocess occam source code to remove comments and turn indentation into +-- explicit markers. +removeIndentation :: String -> String -> PassM String +removeIndentation filename orig + = do modify $ (\ps -> ps { psIndentLinesIn = origLines, psIndentLinesOut = [] }) - -- FIXME Catch errors and figure out the source position based on the - -- input lines. - nextLine 0 + catchError (nextLine 0) reportError ps <- get let out = concat $ intersperse "\n" $ reverse $ psIndentLinesOut ps modify $ (\ps -> ps { psIndentLinesIn = [], psIndentLinesOut = [] }) return out where + origLines = lines orig + + -- | When something goes wrong, figure out how far through the file we'd got. + reportError :: String -> PassM () + reportError error + = do ps <- get + let lineNumber = length origLines - length (psIndentLinesIn ps) + die $ filename ++ ":" ++ show lineNumber ++ ": " ++ error + -- | Get the next raw line from the input. getLine :: PassM (Maybe String) getLine @@ -90,7 +100,8 @@ removeIndentation orig -- Tabs are 8 spaces. countIndent ('\t':cs) soFar = countIndent cs (soFar + 4) countIndent (' ':' ':cs) soFar = countIndent cs (soFar + 1) - countIndent (' ':cs) soFar + countIndent [' '] soFar = return (soFar, []) + countIndent (' ':_) soFar = die "bad indentation (odd number of spaces)" countIndent cs soFar = return (soFar, cs) diff --git a/fco2/Parse.hs b/fco2/Parse.hs index 6c509fc..425815f 100644 --- a/fco2/Parse.hs +++ b/fco2/Parse.hs @@ -1783,7 +1783,7 @@ loadSource file = load file file Nothing -> do progress $ "Loading source file " ++ realName rawSource <- liftIO $ readSource realName - source <- removeIndentation (rawSource ++ "\n" ++ mainMarker) + source <- removeIndentation realName (rawSource ++ "\n" ++ mainMarker) debug $ "Preprocessed source:" debug $ numberLines source modify $ (\ps -> ps { psSourceFiles = (file, source) : psSourceFiles ps })