summaryrefslogtreecommitdiff
path: root/lib/Language/Elna/NameAnalysis.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Language/Elna/NameAnalysis.hs')
-rw-r--r--lib/Language/Elna/NameAnalysis.hs42
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