Refactoring into Syntax Parser, also float parsing

This commit is contained in:
vegowotenks 2025-01-20 19:53:28 +01:00
parent 212eecfdf7
commit 52e04d28cf
18 changed files with 287 additions and 176 deletions

View file

@ -0,0 +1,71 @@
module Ubc.Parse.Syntax.Struct
( Struct(..)
, parseStruct
)
where
import Data.Functor ( (<&>) )
import Control.Arrow ( (>>>) )
import Text.Parsec
( char,
choice,
getState,
lookAhead,
many,
modifyState,
try,
ParsecT )
import Ubc.Parse.Syntax.ParserState (ParserState)
import Ubc.Parse.Syntax.Scope.StructScope (StructScope(..))
import Ubc.Parse.Syntax.Scope (Scope(..))
import Ubc.Parse.Syntax.Data.Struct (Struct(..))
import qualified Ubc.Parse.Syntax.Language as UbcLanguage
import qualified Ubc.Parse.Syntax.Scope.StructScope as StructScope
import qualified Ubc.Parse.Syntax.ParserState as ParserState
import qualified Ubc.Parse.Syntax.Scope as Scope
import qualified Ubc.Parse.Syntax.VariableType as VariableType
parseStruct :: Monad m => ParsecT String ParserState m Struct
parseStruct = do
_ <- UbcLanguage.reserved "struct"
structIdentifier <- UbcLanguage.identifier
let structScope = StructScope
{ structName = structIdentifier
, variables = []
}
modifyState (ParserState.pushScope . ScopeStruct $ structScope)
_ <- UbcLanguage.braces (many structMember)
structScope' <- getState <&> Scope.expectScopeStruct . snd . ParserState.popScope
return $ Struct (StructScope.structName structScope') (StructScope.variables structScope')
structMember :: Monad m => ParsecT String ParserState m ()
structMember = choice [ structVariableOrFunction ]
structVariableOrFunction :: Monad m => ParsecT String ParserState m ()
structVariableOrFunction = do
(typeName, identifier) <- try $ do
typeName <- UbcLanguage.typeName
objectIdentifier <- UbcLanguage.identifier
return (typeName, objectIdentifier)
choice
[ lookAhead (char ';') *> parseVariable typeName identifier
] -- TODO: Functions on structs
parseVariable :: Monad m => String -> String -> ParsecT String ParserState m ()
parseVariable variableType variableName = do
_ <- UbcLanguage.semicolon
modifyState (ParserState.modifyScope (Scope.expectScopeStruct
>>> StructScope.modifyVariables ((variableName, VariableType.fromString variableType):)
>>> Scope.ScopeStruct
)
)