module Ubc.Parse.Syntax.File ( File(..) , parse ) where import Control.Monad ((<$!>)) import Text.Parsec (choice, ParsecT, many) import Ubc.Parse.Syntax.Data.Struct ( Struct ) import Ubc.Parse.Syntax.Function (Function) import Ubc.Parse.Syntax.Statement (Statement) import qualified Ubc.Parse.Syntax.Struct as Struct import qualified Ubc.Parse.Syntax.Function as Function import qualified Ubc.Parse.Syntax.Statement as Statement data File = File { name :: String , structs :: [Struct] , functions :: [Function] , statements :: [Statement] } deriving (Show) data FileMember = FileFunction Function | FileStruct Struct | FileStatement Statement accumulateFile :: File -> FileMember -> File accumulateFile (File name_ struct_ functions_ statements_) (FileFunction f) = File name_ struct_ (f:functions_) statements_ accumulateFile (File name_ struct_ functions_ statements_) (FileStatement s) = File name_ struct_ functions_ (s:statements_) accumulateFile (File name_ struct_ functions_ statements_) (FileStruct s) = File name_ (s:struct_) functions_ statements_ parse :: Monad m => ParsecT String u m File parse = foldl accumulateFile (File "" [] [] []) <$!> many fileMember fileMember :: Monad m => ParsecT String u m FileMember fileMember = choice [ FileStruct <$!> Struct.parse , FileFunction <$!> Function.parse , FileStatement <$!> Statement.parse ]