rail-compiler-editor-0.3.0.0: src/RailCompiler/Preprocessor.hs
{- |
Module : Preprocessor.hs
Description : .
Maintainer : (c) Christopher Pockrandt, Nicolas Lehmann
License : MIT
Stability : stable
Preprocessor gets the content of the input file and puts each rail function
into a list of strings such that the first character of the first line is a
dollar sign. Leading lines without a dollar sign in the input file are removed.
-}
module Preprocessor (
process -- main function of the module "Preprocessor"
)
where
-- imports --
import InterfaceDT as IDT
import ErrorHandling as EH
import Data.List
import Control.Arrow
import qualified Data.Map as Map
-- functions --
process :: IDT.Input2PreProc -> IDT.PreProc2Lexer
process (IDT.IIP input) = IDT.IPL output
where
output = map (Control.Arrow.first convert . Control.Arrow.first maximize) groups
groups = (groupFunctions . removeLines . lines) input
convert :: [String] -> Grid2D
convert code = Map.fromList $ zip [0..] (map (Map.fromList . zip [0..]) code)
-- |Makes the first line as long as max(max(lines),#lines)
-- this is useful for the lexer to determine an upper bound for empty endless loops
maximize :: [String] -> [String]
maximize [] = []
maximize (x:xs) = stretchto (max maxlines maxcols) x:xs
where
stretchto count line = take count (line ++ repeat ' ')
maxlines = maximum $ map length (x:xs)
maxcols = length (x:xs)
-- |Return False iff the first character is a dollar sign.
notStartingWithDollar :: String -> Bool
notStartingWithDollar x = null x || head x /= '$'
-- |Removes all leading strings from list until first string begins with a
-- dollar sign.
removeLines :: [String] -> ([String], Int)
removeLines grid
| null $ fst $ result grid 0 = error noStartSymbolFound
| otherwise = result grid 0
where
result grid n
| null grid = (grid, n)
| not $ notStartingWithDollar $ head grid = (grid, n)
| otherwise = result (tail grid) (n + 1)
-- |Puts every rail function/program into its on grid such that the dollar
-- sign is the first character in the first line.
groupFunctions :: ([String], Int) -> [([String], Int)]
groupFunctions ([], _) = []
groupFunctions (grid, offset) = (head grid:func, offset):groupFunctions (other, offset + 1 + length func)
where
(func, other) = span notStartingWithDollar $ tail grid