Create procedure local symbol table
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user