56 lines
1.9 KiB
Haskell
56 lines
1.9 KiB
Haskell
module Ubc.Parse.Syntax.Struct
|
|
( Struct(..)
|
|
, parse
|
|
)
|
|
where
|
|
|
|
import Control.Monad ((<$!>))
|
|
|
|
import Text.Parsec
|
|
( choice,
|
|
many,
|
|
try,
|
|
ParsecT,
|
|
)
|
|
|
|
import Ubc.Parse.Syntax.Data.Struct (Struct(..))
|
|
import Ubc.Parse.Syntax.VariableType (VariableType)
|
|
|
|
import qualified Ubc.Parse.Syntax.Language as UbcLanguage
|
|
import qualified Ubc.Parse.Syntax.VariableType as VariableType
|
|
import qualified Ubc.Parse.Syntax.Data.Struct as Struct
|
|
import qualified Ubc.Parse.Syntax.Function as Function
|
|
|
|
type VariableName = String
|
|
data StructStatement = Variable VariableName VariableType
|
|
| Function Function.Function
|
|
|
|
parse :: Monad m => ParsecT String u m Struct
|
|
parse = do
|
|
_ <- UbcLanguage.reserved "struct"
|
|
structIdentifier <- UbcLanguage.identifier
|
|
|
|
foldl accumulateStruct (Struct structIdentifier [] []) <$!> UbcLanguage.braces (many structMember)
|
|
|
|
accumulateStruct :: Struct -> StructStatement -> Struct
|
|
accumulateStruct s (Variable n t) = Struct.addVariable s n t
|
|
accumulateStruct s (Function f) = Struct.addFunction s f
|
|
|
|
structMember :: Monad m => ParsecT String u m StructStatement
|
|
structMember = choice [ structVariableOrFunction ]
|
|
|
|
structVariableOrFunction :: Monad m => ParsecT String u m StructStatement
|
|
structVariableOrFunction = do
|
|
(typeName, identifier) <- try $ do
|
|
typeName <- UbcLanguage.typeName
|
|
objectIdentifier <- UbcLanguage.identifier
|
|
return (VariableType.fromString typeName, objectIdentifier)
|
|
choice
|
|
[ parseVariable typeName identifier
|
|
, Function <$!> Function.parsePrefixed typeName identifier
|
|
] -- TODO: Functions on structs
|
|
|
|
parseVariable :: Monad m => VariableType -> String -> ParsecT String u m StructStatement
|
|
parseVariable variableType variableName = do
|
|
_ <- UbcLanguage.semicolon
|
|
return $ Variable variableName variableType
|