Create procedure local symbol table

This commit is contained in:
2024-08-04 12:23:19 +02:00
parent 5f8d9abe76
commit 9cb9ab536f
4 changed files with 56 additions and 16 deletions

View File

@ -8,7 +8,7 @@ import Control.Monad.Trans.Reader (ReaderT(..), ask, runReaderT, withReaderT)
import Data.Functor ((<&>))
import qualified Language.Elna.AST as AST
import Language.Elna.Location (Identifier(..))
import Language.Elna.SymbolTable (Info(..), SymbolTable, symbolTable)
import Language.Elna.SymbolTable (Info(..), SymbolTable, builtInSymbolTable)
import qualified Language.Elna.SymbolTable as SymbolTable
import Language.Elna.Types (Type(..))
import Control.Monad.Trans.Class (MonadTrans(..))
@ -38,7 +38,7 @@ instance Monad NameAnalysis
nameAnalysis :: AST.Program -> Either Error SymbolTable
nameAnalysis = runExcept
. flip runReaderT symbolTable
. flip runReaderT builtInSymbolTable
. runNameAnalysis
. program
@ -51,9 +51,21 @@ declaration :: SymbolTable -> AST.Declaration -> NameAnalysis SymbolTable
declaration globalTable (AST.TypeDefinition identifier typeExpression)
= flip (SymbolTable.enter identifier) globalTable . TypeInfo
<$> withSymbolTable globalTable (dataType typeExpression)
declaration globalTable (AST.ProcedureDefinition identifier _parameters _variables _body) =
let localTable = SymbolTable.empty
in pure $ SymbolTable.enter identifier (ProcedureInfo localTable mempty) globalTable
declaration globalTable (AST.ProcedureDefinition identifier parameters variables _body) = do
parametersInfo <- mapM parameter parameters
variableInfo <- mapM variableDeclaration variables
let localTable = SymbolTable.fromList $ parametersInfo <> variableInfo
pure $ SymbolTable.enter identifier (ProcedureInfo localTable mempty) globalTable
variableDeclaration :: AST.VariableDeclaration -> NameAnalysis (Identifier, Info)
variableDeclaration (AST.VariableDeclaration identifier typeExpression)
= (identifier,) . flip VariableInfo False
<$> dataType typeExpression
parameter :: AST.Parameter -> NameAnalysis (Identifier, Info)
parameter (AST.Parameter identifier typeExpression isReferenceParameter')
= (identifier,) . flip VariableInfo isReferenceParameter'
<$> dataType typeExpression
withSymbolTable :: forall a. SymbolTable -> NameAnalysis a -> NameAnalysis a
withSymbolTable symbolTable' = NameAnalysis

View File

@ -4,8 +4,9 @@ module Language.Elna.SymbolTable
, SymbolTable
, empty
, enter
, fromList
, lookup
, symbolTable
, builtInSymbolTable
) where
import Data.HashMap.Strict (HashMap)
@ -26,8 +27,8 @@ instance Monoid SymbolTable
where
mempty = SymbolTable HashMap.empty
symbolTable :: SymbolTable
symbolTable = SymbolTable $ HashMap.fromList
builtInSymbolTable :: SymbolTable
builtInSymbolTable = SymbolTable $ HashMap.fromList
[ ("boolean", TypeInfo booleanType)
, ("int", TypeInfo intType)
]
@ -42,6 +43,9 @@ enter identifier info (SymbolTable table) = SymbolTable
lookup :: Identifier -> SymbolTable -> Maybe Info
lookup identifier (SymbolTable table) = HashMap.lookup identifier table
fromList :: [(Identifier, Info)] -> SymbolTable
fromList = SymbolTable . HashMap.fromList
data ParameterInfo = ParameterInfo
{ name :: Identifier
, type' :: Type