summaryrefslogtreecommitdiff
path: root/lib/Language
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2024-10-31 22:19:48 +0100
committerEugen Wissner <belka@caraus.de>2024-10-31 22:19:48 +0100
commite2d4b76c0bbad6c0740f5322e862a02971802e87 (patch)
tree1ef1d5cc96004ea8b88efc419cde2b6118b63089 /lib/Language
parent43882a3a0697945b35194c2b5940605e9f4dd846 (diff)
downloadelna-e2d4b76c0bbad6c0740f5322e862a02971802e87.tar.gz
Check argument list length
Diffstat (limited to 'lib/Language')
-rw-r--r--lib/Language/Elna/Frontend/TypeAnalysis.hs91
1 files changed, 54 insertions, 37 deletions
diff --git a/lib/Language/Elna/Frontend/TypeAnalysis.hs b/lib/Language/Elna/Frontend/TypeAnalysis.hs
index 7d0b050..2ddbd1c 100644
--- a/lib/Language/Elna/Frontend/TypeAnalysis.hs
+++ b/lib/Language/Elna/Frontend/TypeAnalysis.hs
@@ -3,42 +3,61 @@ module Language.Elna.Frontend.TypeAnalysis
, -- Error(..)
) where
+import Control.Monad (unless)
+import Control.Monad.Trans.Class (MonadTrans(..))
+import Control.Monad.Trans.Except (Except, runExcept, throwE)
+import Control.Monad.Trans.Reader (ReaderT, runReaderT, withReaderT, ask)
+import Data.Foldable (traverse_)
+import qualified Data.Vector as Vector
import qualified Language.Elna.Frontend.AST as AST
-import Language.Elna.Frontend.SymbolTable ({-Info(..), ParameterInfo(..), -}SymbolTable)
+import Language.Elna.Frontend.SymbolTable (Info(..), {-ParameterInfo(..), -}SymbolTable)
+import qualified Language.Elna.Frontend.SymbolTable as SymbolTable
+import Language.Elna.Frontend.Types (Type(..), booleanType, intType)
+import Language.Elna.Location (Identifier(..))
-typeAnalysis :: SymbolTable -> AST.Program -> () -- Maybe Error
-typeAnalysis _globalTable = const () {- either Just (const Nothing)
+typeAnalysis :: SymbolTable -> AST.Program -> Maybe Error
+typeAnalysis globalTable = either Just (const Nothing)
. runExcept
. flip runReaderT globalTable
. runTypeAnalysis
- . program -}
+ . program
{-
import Control.Applicative (Alternative(..))
-import Control.Monad.Trans.Except (Except, runExcept, throwE)
-import Control.Monad.Trans.Reader (ReaderT, asks, runReaderT, withReaderT, ask)
-import qualified Data.Vector as Vector
-import Language.Elna.Location (Identifier(..))
-import qualified Language.Elna.SymbolTable as SymbolTable
-import Language.Elna.Types (Type(..), booleanType, intType)
-import Control.Monad.Trans.Class (MonadTrans(..))
-import Control.Monad (unless, when)
-import Data.Foldable (traverse_)
-
+-}
data Error
- = ArithmeticExpressionError Type
- | ComparisonExpressionError Type Type
- | UnexpectedVariableInfoError Info
- | UnexpectedProcedureInfoError Info
+ = UnexpectedProcedureInfoError Info
| UndefinedSymbolError Identifier
+ | ParameterCountMismatchError Int Int
+ | UnexpectedVariableInfoError Info
+ | ArithmeticExpressionError Type
+ | ComparisonExpressionError Type Type
| InvalidConditionTypeError Type
- | InvalidAssignmentError Type
+{- | InvalidAssignmentError Type
| ExpectedLvalueError AST.Expression
- | ParameterCountMismatchError Int Int
| ArgumentTypeMismatchError Type Type
| ArrayIndexError Type
- | ArrayAccessError Type
- deriving (Eq, Show)
+ | ArrayAccessError Type -}
+ deriving Eq
+
+instance Show Error
+ where
+ show (UnexpectedProcedureInfoError info) =
+ "Expected to encounter a procedure, got: " <> show info
+ show (UndefinedSymbolError identifier) =
+ concat ["Symbol \"", show identifier, "\" is not defined"]
+ show (ParameterCountMismatchError parameterCount argumentCount)
+ = "The function was expected to receive " <> show argumentCount
+ <> " arguments, but got " <> show parameterCount
+ show (UnexpectedVariableInfoError info) =
+ "Expected to encounter a variable, got: " <> show info
+ show (ArithmeticExpressionError got) =
+ "Expected an arithmetic expression to be an integer, got: " <> show got
+ show (ComparisonExpressionError lhs rhs)
+ = "Expected an arithmetic expression to be an integer, got \""
+ <> show lhs <> "\" and \"" <> show rhs <> "\""
+ show (InvalidConditionTypeError got) =
+ "Expected a condition to be a boolean, got: " <> show got
newtype TypeAnalysis a = TypeAnalysis
{ runTypeAnalysis :: ReaderT SymbolTable (Except Error) a
@@ -61,7 +80,7 @@ program :: AST.Program -> TypeAnalysis ()
program (AST.Program declarations) = traverse_ declaration declarations
declaration :: AST.Declaration -> TypeAnalysis ()
-declaration (AST.ProcedureDefinition procedureName _ _ body) = do
+declaration (AST.ProcedureDeclaration procedureName _ _ body) = do
globalTable <- TypeAnalysis ask
case SymbolTable.lookup procedureName globalTable of
Just (ProcedureInfo localTable _) -> TypeAnalysis
@@ -72,29 +91,29 @@ declaration (AST.ProcedureDefinition procedureName _ _ body) = do
$ UnexpectedProcedureInfoError anotherInfo
Nothing -> TypeAnalysis $ lift $ throwE
$ UndefinedSymbolError procedureName
-declaration _ = pure ()
+declaration (AST.TypeDefinition _ _) = pure ()
statement :: SymbolTable -> AST.Statement -> TypeAnalysis ()
statement globalTable = \case
AST.EmptyStatement -> pure ()
- AST.AssignmentStatement lhs rhs -> do
+ {- AST.AssignmentStatement lhs rhs -> do
lhsType <- variableAccess globalTable lhs
rhsType <- expression globalTable rhs
unless (lhsType == intType)
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError lhsType
unless (rhsType == intType)
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError rhsType
+ AST.WhileStatement whileCondition whileStatement -> do
+ conditionType <- condition globalTable whileCondition
+ unless (conditionType == booleanType)
+ $ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError conditionType
+ statement globalTable whileStatement -}
AST.IfStatement ifCondition ifStatement elseStatement -> do
conditionType <- condition globalTable ifCondition
unless (conditionType == booleanType)
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError conditionType
statement globalTable ifStatement
maybe (pure ()) (statement globalTable) elseStatement
- AST.WhileStatement whileCondition whileStatement -> do
- conditionType <- condition globalTable whileCondition
- unless (conditionType == booleanType)
- $ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError conditionType
- statement globalTable whileStatement
AST.CompoundStatement statements -> traverse_ (statement globalTable) statements
AST.CallStatement procedureName arguments ->
case SymbolTable.lookup procedureName globalTable of
@@ -110,7 +129,7 @@ statement globalTable = \case
Nothing -> TypeAnalysis $ lift $ throwE
$ UndefinedSymbolError procedureName
where
- checkArgument ParameterInfo{..} argument = do
+ checkArgument SymbolTable.ParameterInfo{} _argument = pure () {-
argumentType <- expression globalTable argument
unless (argumentType == type')
$ TypeAnalysis $ lift $ throwE $ ArgumentTypeMismatchError type' argumentType
@@ -137,11 +156,11 @@ variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = d
ArrayType _ baseType -> pure baseType
nonArrayType -> TypeAnalysis $ lift $ throwE
$ ArrayAccessError nonArrayType
-
+-}
expression :: SymbolTable -> AST.Expression -> TypeAnalysis Type
expression globalTable = \case
- AST.VariableExpression variableExpression -> do
- variableAccess globalTable variableExpression
+ {- AST.VariableExpression variableExpression -> do
+ variableAccess globalTable variableExpression -}
AST.LiteralExpression literal' -> literal literal'
AST.NegationExpression negation -> do
operandType <- expression globalTable negation
@@ -179,8 +198,6 @@ condition globalTable = \case
else TypeAnalysis $ lift $ throwE $ ComparisonExpressionError lhsType rhsType
literal :: AST.Literal -> TypeAnalysis Type
-literal (AST.IntegerLiteral _) = pure intType
+literal (AST.DecimalLiteral _) = pure intType
literal (AST.HexadecimalLiteral _) = pure intType
literal (AST.CharacterLiteral _) = pure intType
-literal (AST.BooleanLiteral _) = pure booleanType
--}