diff options
Diffstat (limited to 'lib/Language/Elna/NameAnalysis.hs')
| -rw-r--r-- | lib/Language/Elna/NameAnalysis.hs | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/lib/Language/Elna/NameAnalysis.hs b/lib/Language/Elna/NameAnalysis.hs index 57c41b3..7078691 100644 --- a/lib/Language/Elna/NameAnalysis.hs +++ b/lib/Language/Elna/NameAnalysis.hs @@ -14,19 +14,26 @@ import Control.Monad.Trans.Reader import Data.Functor ((<&>)) import qualified Language.Elna.AST as AST import Language.Elna.Location (Identifier(..)) -import Language.Elna.SymbolTable (Info(..), SymbolTable, builtInSymbolTable) +import Language.Elna.SymbolTable + ( Info(..) + , ParameterInfo(..) + , SymbolTable + , builtInSymbolTable + ) import qualified Language.Elna.SymbolTable as SymbolTable import Language.Elna.Types (Type(..)) import Control.Monad.Trans.Class (MonadTrans(..)) import Control.Monad (foldM, unless) import qualified Data.List.NonEmpty as NonEmpty import Data.Foldable (traverse_) +import qualified Data.Vector as Vector data Error = UndefinedTypeError Identifier | UnexpectedTypeInfoError Info | IdentifierAlreadyDefinedError Identifier | UndefinedSymbolError Identifier + | UnexpectedArrayByValue Identifier deriving (Eq, Show) newtype NameAnalysis a = NameAnalysis @@ -66,9 +73,12 @@ declaration globalTable (AST.ProcedureDefinition identifier parameters variables variableInfo <- mapM variableDeclaration variables newTable <- either (identifierAlreadyDefinedError . NonEmpty.head) pure $ SymbolTable.fromList - $ parametersInfo <> variableInfo + $ fmap parameterToVariableInfo parametersInfo + <> variableInfo traverse_ (statement globalTable) body - enter identifier (ProcedureInfo newTable mempty) globalTable + let procedureInfo = ProcedureInfo newTable + $ Vector.fromList parametersInfo + enter identifier procedureInfo globalTable statement :: SymbolTable -> AST.Statement -> NameAnalysis () statement _ AST.EmptyStatement = pure () @@ -151,13 +161,29 @@ identifierAlreadyDefinedError = NameAnalysis variableDeclaration :: AST.VariableDeclaration -> NameAnalysis (Identifier, Info) variableDeclaration (AST.VariableDeclaration identifier typeExpression) - = (identifier,) . flip VariableInfo False + = (identifier,) . VariableInfo False <$> dataType typeExpression -parameter :: AST.Parameter -> NameAnalysis (Identifier, Info) -parameter (AST.Parameter identifier typeExpression isReferenceParameter') - = (identifier,) . flip VariableInfo isReferenceParameter' - <$> dataType typeExpression +parameter :: AST.Parameter -> NameAnalysis ParameterInfo +parameter (AST.Parameter identifier typeExpression isReferenceParameter') = do + parameterType <- dataType typeExpression + case parameterType of + ArrayType _ _ + | not isReferenceParameter' -> NameAnalysis + $ lift $ throwE $ UnexpectedArrayByValue identifier + _ -> + let parameterInfo = ParameterInfo + { name = identifier + , type' = parameterType + , isReferenceParameter = isReferenceParameter' + } + in pure parameterInfo + +parameterToVariableInfo :: ParameterInfo -> (Identifier, Info) +parameterToVariableInfo ParameterInfo{..} = + ( name + , VariableInfo isReferenceParameter type' + ) withSymbolTable :: forall a. SymbolTable -> NameAnalysis a -> NameAnalysis a withSymbolTable symbolTable' = NameAnalysis |
