summaryrefslogtreecommitdiff
path: root/lib/Language/Elna
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Language/Elna')
-rw-r--r--lib/Language/Elna/NameAnalysis.hs42
-rw-r--r--lib/Language/Elna/SymbolTable.hs2
-rw-r--r--lib/Language/Elna/TypeAnalysis.hs2
-rw-r--r--lib/Language/Elna/Types.hs12
4 files changed, 44 insertions, 14 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
diff --git a/lib/Language/Elna/SymbolTable.hs b/lib/Language/Elna/SymbolTable.hs
index eb82073..b56d0c7 100644
--- a/lib/Language/Elna/SymbolTable.hs
+++ b/lib/Language/Elna/SymbolTable.hs
@@ -73,6 +73,6 @@ data ParameterInfo = ParameterInfo
data Info
= TypeInfo Type
- | VariableInfo Type Bool
+ | VariableInfo Bool Type
| ProcedureInfo SymbolTable (Vector ParameterInfo)
deriving (Eq, Show)
diff --git a/lib/Language/Elna/TypeAnalysis.hs b/lib/Language/Elna/TypeAnalysis.hs
index 040a022..c390196 100644
--- a/lib/Language/Elna/TypeAnalysis.hs
+++ b/lib/Language/Elna/TypeAnalysis.hs
@@ -125,7 +125,7 @@ expression globalTable = \case
AST.VariableExpression identifier -> do
localLookup <- TypeAnalysis $ asks $ SymbolTable.lookup identifier
case localLookup <|> SymbolTable.lookup identifier globalTable of
- Just (VariableInfo variableType _) -> pure variableType
+ Just (VariableInfo _ variableType) -> pure variableType
Just anotherInfo -> TypeAnalysis $ lift $ throwE
$ UnexpectedVariableInfoError anotherInfo
Nothing -> TypeAnalysis $ lift $ throwE
diff --git a/lib/Language/Elna/Types.hs b/lib/Language/Elna/Types.hs
index 80a88c0..ee76ec8 100644
--- a/lib/Language/Elna/Types.hs
+++ b/lib/Language/Elna/Types.hs
@@ -1,5 +1,6 @@
module Language.Elna.Types
( Type(..)
+ , addressByteSize
, booleanType
, intType
) where
@@ -8,18 +9,21 @@ import Data.Text (Text)
import Data.Word (Word32)
import Language.Elna.Location (showArrayType)
+addressByteSize :: Int
+addressByteSize = 4
+
data Type
- = PrimitiveType Text
+ = PrimitiveType Text Int
| ArrayType Word32 Type
deriving Eq
instance Show Type
where
- show (PrimitiveType typeName) = show typeName
+ show (PrimitiveType typeName _) = show typeName
show (ArrayType elementCount typeName) = showArrayType elementCount typeName
intType :: Type
-intType = PrimitiveType "int"
+intType = PrimitiveType "int" 4
booleanType :: Type
-booleanType = PrimitiveType "boolean"
+booleanType = PrimitiveType "boolean" 1