Skip to content

Commit

Permalink
add: TypeDefinition
Browse files Browse the repository at this point in the history
  • Loading branch information
oriollinan committed Jan 7, 2025
1 parent e51a7ee commit 089848f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 51 deletions.
9 changes: 5 additions & 4 deletions glados.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ library
import: warnings
exposed-modules:
Ast.Parser
Ast.Types
Ast.Utils
Ast.Parser.Env
Ast.Parser.Literal
Ast.Parser.Operation
Ast.Parser.UnaryOperation
Ast.Parser.Type
Ast.Parser.TypeDefinition
Ast.Parser.UnaryOperation
Ast.Types
Ast.Utils
Codegen.Codegen
Codegen.Utils
Misc
Expand Down Expand Up @@ -80,4 +81,4 @@ test-suite glados-test
hspec,
hspec-discover,
megaparsec >=9.7.0,
mtl >=2.2.2 && <2.3
mtl >=2.2.2 && <2.3
48 changes: 1 addition & 47 deletions lib/Ast/Parser/Type.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import qualified Text.Megaparsec.Char.Lexer as ML
-- | Parse a general type. This function combines multiple specific type parsers.
-- It tries to match typedefs, structs, unions, functions, mutable types, pointers, and base types.
parseType :: AU.Parser AT.Type
parseType = AU.triedChoice [structType, unionType, typedefType, functionType, mutableType, arrayType, pointerType, customIntType, baseType, customType]
parseType = AU.triedChoice [functionType, mutableType, arrayType, pointerType, customIntType, baseType, customType]

-- | A list of predefined base types along with their associated keywords.
-- These include basic types such as int, float, double, char, bool, and void.
Expand Down Expand Up @@ -58,42 +58,6 @@ arrayType = do
elemType <- parseType
return $ AT.TArray elemType size

-- | Parses a struct type definition.
-- A struct is defined with the "struct" keyword followed by an optional name and a list of fields enclosed in braces.
-- Example: "struct { x -> int, y -> float }".
structType :: AU.Parser AT.Type
structType = do
name <- AU.identifier
_ <- AU.symbol "::" <* AU.symbol "struct"
fields <- M.between (AU.symbol "{") (AU.symbol "}") $ M.many parseField
let newStructType = AT.TStruct {AT.structName = name, AT.fields = fields}
S.modify (E.insertType name newStructType)
return newStructType

-- | Parses a union type definition.
-- A union is defined with the "union" keyword followed by an optional name and a list of variants enclosed in braces.
-- Example: "union { data -> *char, error -> int }".
unionType :: AU.Parser AT.Type
unionType = do
name <- AU.identifier
_ <- AU.symbol "::" <* AU.symbol "union"
variants <- M.between (AU.symbol "{") (AU.symbol "}") $ M.many parseField
let newUnionType = AT.TUnion {AT.unionName = name, AT.variants = variants}
S.modify (E.insertType name newUnionType)
return newUnionType

-- | Parses a typedef.
-- A typedef associates a new name with an existing type using the "::" syntax.
-- Example: "Vector2i :: Vector".
typedefType :: AU.Parser AT.Type
typedefType = do
name <- AU.identifier
_ <- AU.symbol "::"
parentType <- parseType
let typedef = AT.TTypedef name parentType
S.modify (E.insertType name typedef)
return typedef

-- | Parses a function type.
-- A function type is defined by its parameter types enclosed in parentheses, followed by "->", and the return type also enclosed in parentheses.
-- Example: "(int) -> (float)" or "(int int) -> (void)".
Expand All @@ -112,13 +76,3 @@ customType = do
case E.lookupType name env of
Just ty -> return ty
Nothing -> fail $ "Unknown type: " ++ name

-- | Parses a single field within a struct or union.
-- Each field consists of a name followed by "->" and its type.
-- Example: "x -> int".
parseField :: AU.Parser (String, AT.Type)
parseField = do
fieldName <- AU.lexeme AU.identifier
_ <- AU.symbol "->"
fieldType <- parseType
return (fieldName, fieldType)
60 changes: 60 additions & 0 deletions lib/Ast/Parser/TypeDefinition.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module Ast.Parser.TypeDefinition where

import qualified Ast.Parser.Env as E
import qualified Ast.Parser.Type as T
import qualified Ast.Types as AT
import qualified Ast.Utils as AU
import qualified Control.Monad.State as S
import qualified Text.Megaparsec as M

-- | Parse a type definition. This function combines multiple specific type
-- definition.
-- It tries to match typedefs, structs, and unions.
parseTypeDefinition :: AU.Parser ()
parseTypeDefinition = AU.triedChoice [structType, unionType, typedefType]

-- | Parses a struct type definition.
-- A struct is defined with the "struct" keyword followed by an optional name and a list of fields enclosed in braces.
-- Example: "struct { x -> int, y -> float }".
structType :: AU.Parser ()
structType = do
name <- AU.identifier
_ <- AU.symbol "::" <* AU.symbol "struct"
fields <- M.between (AU.symbol "{") (AU.symbol "}") $ M.many parseField
let newStructType = AT.TStruct {AT.structName = name, AT.fields = fields}
S.modify (E.insertType name newStructType)
return ()

-- | Parses a union type definition.
-- A union is defined with the "union" keyword followed by an optional name and a list of variants enclosed in braces.
-- Example: "union { data -> *char, error -> int }".
unionType :: AU.Parser ()
unionType = do
name <- AU.identifier
_ <- AU.symbol "::" <* AU.symbol "union"
variants <- M.between (AU.symbol "{") (AU.symbol "}") $ M.many parseField
let newUnionType = AT.TUnion {AT.unionName = name, AT.variants = variants}
S.modify (E.insertType name newUnionType)
return ()

-- | Parses a typedef.
-- A typedef associates a new name with an existing type using the "::" syntax.
-- Example: "Vector2i :: Vector".
typedefType :: AU.Parser ()
typedefType = do
name <- AU.identifier
_ <- AU.symbol "::"
parentType <- T.parseType
let typedef = AT.TTypedef name parentType
S.modify (E.insertType name typedef)
return ()

-- | Parses a single field within a struct or union.
-- Each field consists of a name followed by "->" and its type.
-- Example: "x -> int".
parseField :: AU.Parser (String, AT.Type)
parseField = do
fieldName <- AU.lexeme AU.identifier
_ <- AU.symbol "->"
fieldType <- T.parseType
return (fieldName, fieldType)

0 comments on commit 089848f

Please # to comment.