Parse local variables

This commit is contained in:
2024-11-06 22:23:49 +01:00
parent e2d4b76c0b
commit 060496fc6e
11 changed files with 115 additions and 91 deletions

View File

@ -6,7 +6,7 @@ module Language.Elna.Frontend.AST
, Statement(..)
, TypeExpression(..)
, VariableDeclaration(..)
--, VariableAccess(..)
, VariableAccess(..)
, Condition(..)
, Expression(..)
, Literal(..)
@ -70,8 +70,8 @@ instance Show TypeExpression
data Statement
= EmptyStatement
| IfStatement Condition Statement (Maybe Statement)
{-| AssignmentStatement VariableAccess Expression
| WhileStatement Condition Statement -}
| AssignmentStatement VariableAccess Expression
-- | WhileStatement Condition Statement
| CompoundStatement [Statement]
| CallStatement Identifier [Expression]
deriving Eq
@ -84,9 +84,9 @@ instance Show Statement
, show if'
, maybe "" ((<> " else ") . show) else'
]
{-show (AssignmentStatement lhs rhs) =
show (AssignmentStatement lhs rhs) =
concat [show lhs, " := ", show rhs, ";"]
show (WhileStatement expression statement) =
{-show (WhileStatement expression statement) =
concat ["while (", show expression, ") ", show statement, ";"]-}
show (CompoundStatement statements) =
concat ["{\n", unlines (show <$> statements), " }"]
@ -163,7 +163,7 @@ data Expression
| NegationExpression Expression
| ProductExpression Expression Expression
| DivisionExpression Expression Expression
-- | VariableExpression VariableAccess
| VariableExpression VariableAccess
deriving Eq
instance Show Expression
@ -174,19 +174,19 @@ instance Show Expression
show (NegationExpression negation) = '-' : show negation
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs]
-- show (VariableExpression variable) = show variable
{-
data VariableAccess
show (VariableExpression variable) = show variable
newtype VariableAccess
= VariableAccess Identifier
| ArrayAccess VariableAccess Expression
-- | ArrayAccess VariableAccess Expression
deriving Eq
instance Show VariableAccess
where
show (VariableAccess variableName) = show variableName
show (ArrayAccess arrayAccess elementIndex) =
concat [show arrayAccess, "[", show elementIndex, "]"]
-}
{- show (ArrayAccess arrayAccess elementIndex) =
concat [show arrayAccess, "[", show elementIndex, "]"] -}
data Condition
= EqualCondition Expression Expression
| NonEqualCondition Expression Expression

View File

@ -158,9 +158,9 @@ expression globalTable (AST.ProductExpression lhs rhs)
expression globalTable (AST.DivisionExpression lhs rhs)
= expression globalTable lhs
>> expression globalTable rhs
{- expression globalTable (AST.VariableExpression variableExpression) =
expression globalTable (AST.VariableExpression variableExpression) =
variableAccess globalTable variableExpression
-}
statement :: SymbolTable -> AST.Statement -> NameAnalysis ()
statement _ AST.EmptyStatement = pure ()
statement globalTable (AST.CallStatement name arguments)
@ -172,9 +172,9 @@ statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement)
= condition globalTable ifCondition
>> statement globalTable ifStatement
>> maybe (pure ()) (statement globalTable) elseStatement
-- statement globalTable (AST.AssignmentStatement lvalue rvalue)
-- = variableAccess globalTable lvalue
-- >> expression globalTable rvalue
statement globalTable (AST.AssignmentStatement lvalue rvalue)
= variableAccess globalTable lvalue
>> expression globalTable rvalue
--statement globalTable (AST.WhileStatement whileCondition loop)
-- = condition globalTable whileCondition
-- >> statement globalTable loop
@ -198,13 +198,13 @@ condition globalTable (AST.LessOrEqualCondition lhs rhs)
condition globalTable (AST.GreaterOrEqualCondition lhs rhs)
= expression globalTable lhs
>> expression globalTable rhs
{-
variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
= variableAccess globalTable arrayExpression
>> expression globalTable indexExpression
variableAccess globalTable (AST.VariableAccess identifier) =
checkSymbol globalTable identifier
{- variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
= variableAccess globalTable arrayExpression
>> expression globalTable indexExpression
enter :: Identifier -> Info -> SymbolTable -> NameAnalysis SymbolTable
enter identifier info table
@ -216,9 +216,4 @@ identifierAlreadyDefinedError = NameAnalysis
. lift
. throwE
. IdentifierAlreadyDefinedError
variableDeclaration :: AST.VariableDeclaration -> NameAnalysis (Identifier, Info)
variableDeclaration (AST.VariableDeclaration identifier typeExpression)
= (identifier,) . VariableInfo False
<$> dataType typeExpression
-}

View File

@ -16,7 +16,7 @@ import Language.Elna.Frontend.AST
, Statement(..)
, TypeExpression(..)
, VariableDeclaration(..)
--, VariableAccess(..)
, VariableAccess(..)
, Condition(..)
, Expression(..)
, Literal(..)
@ -64,7 +64,7 @@ termP :: Parser Expression
termP = choice
[ parensP expressionP
, LiteralExpression <$> literalP
-- , VariableExpression <$> variableAccessP
, VariableExpression <$> variableAccessP
]
operatorTable :: [[Operator Parser Expression]]
@ -91,13 +91,13 @@ operatorTable =
expressionP :: Parser Expression
expressionP = makeExprParser termP operatorTable
{-
variableAccessP :: Parser VariableAccess
variableAccessP = do
variableAccessP = VariableAccess <$> identifierP {- do
identifier <- identifierP
indices <- many $ bracketsP expressionP
pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices
-}
pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices -}
conditionP :: Parser Condition
conditionP = do
lhs <- expressionP
@ -187,8 +187,8 @@ statementP
= EmptyStatement <$ semicolonP
<|> ifElseP
<|> CompoundStatement <$> blockP (many statementP)
{-<|> try assignmentP
<|> try whileP -}
<|> try assignmentP
-- <|> try whileP
<|> callP
<?> "statement"
where
@ -202,12 +202,12 @@ statementP
<*> optional (symbol "else" *> statementP)
{-whileP = WhileStatement
<$> (symbol "while" *> parensP conditionP)
<*> statementP
<*> statementP -}
assignmentP = AssignmentStatement
<$> variableAccessP
<* symbol ":="
<*> expressionP
<* semicolonP -}
<* semicolonP
variableDeclarationP :: Parser VariableDeclaration
variableDeclarationP = VariableDeclaration

View File

@ -3,10 +3,11 @@ module Language.Elna.Frontend.TypeAnalysis
, -- Error(..)
) where
import Control.Applicative (Alternative(..))
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 Control.Monad.Trans.Reader (ReaderT, runReaderT, withReaderT, ask, asks)
import Data.Foldable (traverse_)
import qualified Data.Vector as Vector
import qualified Language.Elna.Frontend.AST as AST
@ -22,9 +23,6 @@ typeAnalysis globalTable = either Just (const Nothing)
. runTypeAnalysis
. program
{-
import Control.Applicative (Alternative(..))
-}
data Error
= UnexpectedProcedureInfoError Info
| UndefinedSymbolError Identifier
@ -96,14 +94,14 @@ 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
{- AST.WhileStatement whileCondition whileStatement -> do
conditionType <- condition globalTable whileCondition
unless (conditionType == booleanType)
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError conditionType
@ -136,7 +134,7 @@ statement globalTable = \case
when (isReferenceParameter && not (isLvalue argument))
$ TypeAnalysis $ lift $ throwE $ ExpectedLvalueError argument
isLvalue (AST.VariableExpression _) = True
isLvalue _ = False
isLvalue _ = False -}
variableAccess :: SymbolTable -> AST.VariableAccess -> TypeAnalysis Type
variableAccess globalTable (AST.VariableAccess identifier) = do
@ -147,7 +145,7 @@ variableAccess globalTable (AST.VariableAccess identifier) = do
$ UnexpectedVariableInfoError anotherInfo
Nothing -> TypeAnalysis $ lift $ throwE
$ UndefinedSymbolError identifier
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = do
{-variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = do
arrayType <- variableAccess globalTable arrayExpression
indexType <- expression globalTable indexExpression
unless (indexType == intType)
@ -159,8 +157,8 @@ variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = d
-}
expression :: SymbolTable -> AST.Expression -> TypeAnalysis Type
expression globalTable = \case
{- AST.VariableExpression variableExpression -> do
variableAccess globalTable variableExpression -}
AST.VariableExpression variableExpression ->
variableAccess globalTable variableExpression
AST.LiteralExpression literal' -> literal literal'
AST.NegationExpression negation -> do
operandType <- expression globalTable negation