diff --git a/app/Main.hs b/app/Main.hs index cbbd268..0bd8497 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -6,4 +6,4 @@ main :: IO () main = do text <- getContents - print $ Parsec.parse (File.parse <* Parsec.eof) "" text + print $ Parsec.parse File.parse "" text diff --git a/src/Ubc/Parse/Syntax/Data/Struct.hs b/src/Ubc/Parse/Syntax/Data/Struct.hs new file mode 100644 index 0000000..ece3e8d --- /dev/null +++ b/src/Ubc/Parse/Syntax/Data/Struct.hs @@ -0,0 +1,23 @@ +module Ubc.Parse.Syntax.Data.Struct +( Struct(..) +, addVariable +, addFunction) +where + +import Ubc.Parse.Syntax.VariableType (VariableType) +import Ubc.Parse.Syntax.Function (Function) + +type VariableName = String + +data Struct = Struct + { name :: String + , variables :: [(VariableName, VariableType)] + , functions :: [Function] + } + deriving (Show) + +addVariable :: Struct -> VariableName -> VariableType -> Struct +addVariable (Struct sn vs fs) n t = Struct sn ((n, t): vs) fs + +addFunction :: Struct -> Function -> Struct +addFunction (Struct sn vs fs) f = Struct sn vs (f:fs) diff --git a/src/Ubc/Parse/Syntax/Enumeration.hs b/src/Ubc/Parse/Syntax/Enumeration.hs deleted file mode 100644 index d891217..0000000 --- a/src/Ubc/Parse/Syntax/Enumeration.hs +++ /dev/null @@ -1,23 +0,0 @@ -module Ubc.Parse.Syntax.Enumeration -( Enumeration(..) -, parse -) -where -import qualified Ubc.Parse.Syntax.Language as UbcLanguage -import Text.Parsec (ParsecT, many, ()) - -type EnumerationMember = String -data Enumeration = Enumeration - { name :: String - , members :: [EnumerationMember] - } - deriving (Show) - -parse :: Monad m => ParsecT String u m Enumeration -parse = do - UbcLanguage.reserved "enum" - identifier <- UbcLanguage.identifier "enum identifier" - values <- UbcLanguage.braces $ many UbcLanguage.identifier - - return $ Enumeration identifier values - diff --git a/src/Ubc/Parse/Syntax/File.hs b/src/Ubc/Parse/Syntax/File.hs index 6bd3d94..1548c52 100644 --- a/src/Ubc/Parse/Syntax/File.hs +++ b/src/Ubc/Parse/Syntax/File.hs @@ -8,45 +8,38 @@ import Control.Monad ((<$!>)) import Text.Parsec (choice, ParsecT, many) -import Ubc.Parse.Syntax.Struct ( Struct ) +import Ubc.Parse.Syntax.Data.Struct ( Struct ) import Ubc.Parse.Syntax.Function (Function) import Ubc.Parse.Syntax.Statement (Statement) -import Ubc.Parse.Syntax.Enumeration (Enumeration) - import qualified Ubc.Parse.Syntax.Struct as Struct import qualified Ubc.Parse.Syntax.Function as Function import qualified Ubc.Parse.Syntax.Statement as Statement -import qualified Ubc.Parse.Syntax.Enumeration as Enumeration data File = File { name :: String , structs :: [Struct] , functions :: [Function] , statements :: [Statement] - , enumerations :: [Enumeration] } deriving (Show) data FileMember = FileFunction Function | FileStruct Struct - | FileEnumeration Enumeration | FileStatement Statement accumulateFile :: File -> FileMember -> File -accumulateFile (File name_ sss fs sts es) (FileStruct s) = File name_ (s:sss) fs sts es -accumulateFile (File name_ sss fs sts es) (FileFunction f) = File name_ sss (f:fs) sts es -accumulateFile (File name_ sss fs sts es) (FileStatement s) = File name_ sss fs (s:sts) es -accumulateFile (File name_ sss fs sts es) (FileEnumeration e) = File name_ sss fs sts (e:es) +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 = foldr (flip accumulateFile) (File "" [] [] [] []) <$!> many fileMember +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 - , FileEnumeration <$!> Enumeration.parse ] diff --git a/src/Ubc/Parse/Syntax/Language.hs b/src/Ubc/Parse/Syntax/Language.hs index c18f683..fe67728 100644 --- a/src/Ubc/Parse/Syntax/Language.hs +++ b/src/Ubc/Parse/Syntax/Language.hs @@ -56,7 +56,6 @@ languageDef = LanguageDef { , opStart = oneOf "+-*/%" , opLetter = oneOf "+-*/%" , reservedNames = [ "struct" - , "enum" , "u32" , "i32" , "f32" diff --git a/src/Ubc/Parse/Syntax/Struct.hs b/src/Ubc/Parse/Syntax/Struct.hs index 03ab5ee..77d02df 100644 --- a/src/Ubc/Parse/Syntax/Struct.hs +++ b/src/Ubc/Parse/Syntax/Struct.hs @@ -1,14 +1,9 @@ -{-# LANGUAGE DerivingVia #-} -{-# LANGUAGE DeriveGeneric #-} module Ubc.Parse.Syntax.Struct ( Struct(..) , parse ) where --- yay, explicit dependency on ghc -import GHC.Generics (Generic) - import Control.Monad ((<$!>)) import Text.Parsec @@ -18,41 +13,33 @@ import Text.Parsec ParsecT, ) +import Ubc.Parse.Syntax.Data.Struct (Struct(..)) import Ubc.Parse.Syntax.VariableType (VariableType) -import Ubc.Parse.Syntax.Function (Function) - 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 Struct = Struct - { name :: String - , body :: StructBody - } - deriving (Show) - -data StructBody = StructBody - { variables :: [(VariableName, VariableType)] - , functions :: [Function] - } - deriving stock (Generic, Show) - deriving (Semigroup, Monoid) via StructBody +data StructStatement = Variable VariableName VariableType + | Function Function.Function parse :: Monad m => ParsecT String u m Struct parse = do _ <- UbcLanguage.reserved "struct" structIdentifier <- UbcLanguage.identifier - structBody <- mconcat <$!> UbcLanguage.braces (many structMember) - pure $ Struct structIdentifier structBody + foldl accumulateStruct (Struct structIdentifier [] []) <$!> UbcLanguage.braces (many structMember) -structMember :: Monad m => ParsecT String u m StructBody +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 StructBody +structVariableOrFunction :: Monad m => ParsecT String u m StructStatement structVariableOrFunction = do (typeName, identifier) <- try $ do typeName <- UbcLanguage.typeName @@ -60,10 +47,10 @@ structVariableOrFunction = do return (VariableType.fromString typeName, objectIdentifier) choice [ parseVariable typeName identifier - , (\ f -> mempty { functions = [f] }) <$!> Function.parsePrefixed typeName identifier - ] + , Function <$!> Function.parsePrefixed typeName identifier + ] -- TODO: Functions on structs -parseVariable :: Monad m => VariableType -> String -> ParsecT String u m StructBody +parseVariable :: Monad m => VariableType -> String -> ParsecT String u m StructStatement parseVariable variableType variableName = do _ <- UbcLanguage.semicolon - return $ mempty { variables = [(variableName, variableType)] } + return $ Variable variableName variableType diff --git a/src/Ubc/Parse/Syntax/TypeExpression.hs b/src/Ubc/Parse/Syntax/TypeExpression.hs index ad0db90..6430128 100644 --- a/src/Ubc/Parse/Syntax/TypeExpression.hs +++ b/src/Ubc/Parse/Syntax/TypeExpression.hs @@ -9,7 +9,7 @@ import Control.Monad ((<$!>)) import Text.Parsec (choice, ParsecT) import Ubc.Parse.Syntax.VariableType (VariableType) -import Ubc.Parse.Syntax.Struct (Struct) +import Ubc.Parse.Syntax.Data.Struct (Struct) import qualified Ubc.Parse.Syntax.Language as UbcLanguage import qualified Ubc.Parse.Syntax.VariableType as VariableType diff --git a/ubcc.cabal b/ubcc.cabal index ace0687..5ccb58e 100644 --- a/ubcc.cabal +++ b/ubcc.cabal @@ -26,7 +26,7 @@ source-repository head library exposed-modules: Ubc.Parse.Syntax.Config - Ubc.Parse.Syntax.Enumeration + Ubc.Parse.Syntax.Data.Struct Ubc.Parse.Syntax.Expression Ubc.Parse.Syntax.File Ubc.Parse.Syntax.Function