diff options
| author | Eugen Wissner <belka@caraus.de> | 2024-07-29 08:26:47 +0300 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2024-07-29 08:26:47 +0300 |
| commit | 92990e52f017c3fa0b9ff99f517171051d8c7c18 (patch) | |
| tree | b141a70bbd7fb9454c34f042605791e85d0522a5 /lib/Language/Elna/NameAnalysis.hs | |
| parent | ce7652c6189b289ffbc749dc3d1ffb465c758c01 (diff) | |
| download | elna-92990e52f017c3fa0b9ff99f517171051d8c7c18.tar.gz | |
Add typeExpression to type converter
Diffstat (limited to 'lib/Language/Elna/NameAnalysis.hs')
| -rw-r--r-- | lib/Language/Elna/NameAnalysis.hs | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/lib/Language/Elna/NameAnalysis.hs b/lib/Language/Elna/NameAnalysis.hs index 7388851..abbfb93 100644 --- a/lib/Language/Elna/NameAnalysis.hs +++ b/lib/Language/Elna/NameAnalysis.hs @@ -1,3 +1,65 @@ module Language.Elna.NameAnalysis - ( + ( Error(..) + , nameAnalysis ) where + +import Control.Monad.Trans.Except (ExceptT(..), runExceptT, throwE) +import Control.Monad.Trans.Reader (Reader, ask, runReader) +import Data.Functor ((<&>)) +import qualified Language.Elna.AST as AST +import Language.Elna.Location (Identifier(..)) +import Language.Elna.SymbolTable (Info(..), SymbolTable, symbolTable) +import qualified Language.Elna.SymbolTable as SymbolTable +import Language.Elna.Types (Type(..)) +import Control.Monad.Trans.Class (MonadTrans(..)) + +data Error + = UndefinedTypeError Identifier + | UnexpectedTypeInfoError Info + deriving (Eq, Show) + +newtype NameAnalysis a = NameAnalysis + { runNameAnalysis :: ExceptT Error (Reader SymbolTable) a + } + +instance Functor NameAnalysis + where + fmap f (NameAnalysis x) = NameAnalysis $ f <$> x + +instance Applicative NameAnalysis + where + pure x = NameAnalysis $ pure x + (NameAnalysis f) <*> (NameAnalysis x) = NameAnalysis $ f <*> x + +instance Monad NameAnalysis + where + (NameAnalysis x) >>= f = NameAnalysis $ x >>= (runNameAnalysis . f) + +nameAnalysis :: AST.Program -> Either Error SymbolTable +nameAnalysis = flip runReader symbolTable + . runExceptT + . runNameAnalysis + . program + +program :: AST.Program -> NameAnalysis SymbolTable +program (AST.Program declarations) = do + globalDeclarations <- traverse declaration declarations + NameAnalysis $ lift ask + +declaration :: AST.Declaration -> NameAnalysis (Identifier, Info) +declaration (AST.TypeDefinition identifier typeExpression) = + (identifier,) . TypeInfo <$> dataType typeExpression +declaration (AST.ProcedureDefinition identifier _parameters _variables _body) = do + environmentSymbolTable <- NameAnalysis $ lift ask + pure (identifier, ProcedureInfo environmentSymbolTable mempty) + +dataType :: AST.TypeExpression -> NameAnalysis Type +dataType (AST.NamedType baseType) = do + environmentSymbolTable <- NameAnalysis $ lift ask + case SymbolTable.lookup baseType environmentSymbolTable of + Just baseInfo + | TypeInfo baseType' <- baseInfo -> pure baseType' + | otherwise -> NameAnalysis $ throwE $ UnexpectedTypeInfoError baseInfo + _ -> NameAnalysis $ throwE $ UndefinedTypeError baseType +dataType (AST.ArrayType arraySize baseType) = + dataType baseType <&> ArrayType arraySize |
