Parse local variables
This commit is contained in:
parent
e2d4b76c0b
commit
060496fc6e
17
TODO
17
TODO
@ -1,9 +1,12 @@
|
|||||||
# Intermediate code generation
|
# Intermediate code generation
|
||||||
|
|
||||||
- To access named parameters and local variables inside a procedure, IR should
|
- To access named parameters inside a procedure, IR should be able to reference
|
||||||
be able to reference them. During the generation the needed information (e.g.
|
them. During the generation the needed information (e.g. offsets or registers)
|
||||||
offsets or registers) can be extracted from the symbol table and saved in the
|
can be extracted from the symbol table and saved in the operands.
|
||||||
operands.
|
- Glue always generates the same intermediate variable (LocalVariable 0) for
|
||||||
|
local variables. (LocalVariable 0) is handled the same as temporary variables
|
||||||
|
that are currently saved only in registers. There space on the stack allocated
|
||||||
|
for local variables.
|
||||||
|
|
||||||
# ELF generation
|
# ELF generation
|
||||||
|
|
||||||
@ -15,3 +18,9 @@
|
|||||||
- Each temporary variable gets a tn register where n is the variable index. If
|
- Each temporary variable gets a tn register where n is the variable index. If
|
||||||
there more variables the allocation will fail with out of bounds runtime
|
there more variables the allocation will fail with out of bounds runtime
|
||||||
error. Implement spill over.
|
error. Implement spill over.
|
||||||
|
- The allocator puts temporary and local variables into the same registers,
|
||||||
|
causing conflicts.
|
||||||
|
|
||||||
|
# Language
|
||||||
|
|
||||||
|
- Array support.
|
||||||
|
@ -30,26 +30,21 @@ allocate MachineConfiguration{..} = fmap function
|
|||||||
quadruple (ParameterQuadruple operand1) =
|
quadruple (ParameterQuadruple operand1) =
|
||||||
ParameterQuadruple (operand operand1)
|
ParameterQuadruple (operand operand1)
|
||||||
quadruple (CallQuadruple name count) = CallQuadruple name count
|
quadruple (CallQuadruple name count) = CallQuadruple name count
|
||||||
quadruple (AddQuadruple operand1 operand2 (TempVariable index))
|
quadruple (AddQuadruple operand1 operand2 variable)
|
||||||
= AddQuadruple (operand operand1) (operand operand2)
|
= AddQuadruple (operand operand1) (operand operand2)
|
||||||
$ Store
|
$ storeVariable variable
|
||||||
$ temporaryRegisters !! fromIntegral index
|
quadruple (SubtractionQuadruple operand1 operand2 variable)
|
||||||
quadruple (SubtractionQuadruple operand1 operand2 (TempVariable index))
|
|
||||||
= SubtractionQuadruple (operand operand1) (operand operand2)
|
= SubtractionQuadruple (operand operand1) (operand operand2)
|
||||||
$ Store
|
$ storeVariable variable
|
||||||
$ temporaryRegisters !! fromIntegral index
|
quadruple (NegationQuadruple operand1 variable)
|
||||||
quadruple (NegationQuadruple operand1 (TempVariable index))
|
|
||||||
= NegationQuadruple (operand operand1)
|
= NegationQuadruple (operand operand1)
|
||||||
$ Store
|
$ storeVariable variable
|
||||||
$ temporaryRegisters !! fromIntegral index
|
quadruple (ProductQuadruple operand1 operand2 variable)
|
||||||
quadruple (ProductQuadruple operand1 operand2 (TempVariable index))
|
|
||||||
= ProductQuadruple (operand operand1) (operand operand2)
|
= ProductQuadruple (operand operand1) (operand operand2)
|
||||||
$ Store
|
$ storeVariable variable
|
||||||
$ temporaryRegisters !! fromIntegral index
|
quadruple (DivisionQuadruple operand1 operand2 variable)
|
||||||
quadruple (DivisionQuadruple operand1 operand2 (TempVariable index))
|
|
||||||
= DivisionQuadruple (operand operand1) (operand operand2)
|
= DivisionQuadruple (operand operand1) (operand operand2)
|
||||||
$ Store
|
$ storeVariable variable
|
||||||
$ temporaryRegisters !! fromIntegral index
|
|
||||||
quadruple (LabelQuadruple label) = LabelQuadruple label
|
quadruple (LabelQuadruple label) = LabelQuadruple label
|
||||||
quadruple (GoToQuadruple label) = GoToQuadruple label
|
quadruple (GoToQuadruple label) = GoToQuadruple label
|
||||||
quadruple (EqualQuadruple operand1 operand2 goToLabel) =
|
quadruple (EqualQuadruple operand1 operand2 goToLabel) =
|
||||||
@ -64,9 +59,20 @@ allocate MachineConfiguration{..} = fmap function
|
|||||||
LessOrEqualQuadruple (operand operand1) (operand operand2) goToLabel
|
LessOrEqualQuadruple (operand operand1) (operand operand2) goToLabel
|
||||||
quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel) =
|
quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel) =
|
||||||
GreaterOrEqualQuadruple (operand operand1) (operand operand2) goToLabel
|
GreaterOrEqualQuadruple (operand operand1) (operand operand2) goToLabel
|
||||||
|
quadruple (AssignQuadruple operand1 variable)
|
||||||
|
= AssignQuadruple (operand operand1)
|
||||||
|
$ storeVariable variable
|
||||||
operand :: Operand Variable -> Operand (Store r)
|
operand :: Operand Variable -> Operand (Store r)
|
||||||
operand (IntOperand x) = IntOperand x
|
operand (IntOperand x) = IntOperand x
|
||||||
operand (VariableOperand (TempVariable index))
|
operand (VariableOperand (TempVariable index))
|
||||||
= VariableOperand
|
= VariableOperand
|
||||||
$ Store
|
$ Store
|
||||||
$ temporaryRegisters !! fromIntegral index
|
$ temporaryRegisters !! fromIntegral index
|
||||||
|
operand (VariableOperand (LocalVariable index))
|
||||||
|
= VariableOperand
|
||||||
|
$ Store
|
||||||
|
$ temporaryRegisters !! fromIntegral index
|
||||||
|
storeVariable (TempVariable index) =
|
||||||
|
Store $ temporaryRegisters !! fromIntegral index
|
||||||
|
storeVariable (LocalVariable index) =
|
||||||
|
Store $ temporaryRegisters !! fromIntegral index
|
||||||
|
@ -17,12 +17,12 @@ instance Show Label
|
|||||||
where
|
where
|
||||||
show (Label label) = '.' : Text.unpack label
|
show (Label label) = '.' : Text.unpack label
|
||||||
|
|
||||||
newtype Variable = TempVariable Word32 -- | Variable Text
|
data Variable = TempVariable Word32 | LocalVariable Word32
|
||||||
deriving Eq
|
deriving Eq
|
||||||
|
|
||||||
instance Show Variable
|
instance Show Variable
|
||||||
where
|
where
|
||||||
-- show (Variable variable) = '$' : Text.unpack variable
|
show (LocalVariable variable) = '@' : show variable
|
||||||
show (TempVariable variable) = '$' : show variable
|
show (TempVariable variable) = '$' : show variable
|
||||||
|
|
||||||
data Operand v
|
data Operand v
|
||||||
@ -41,8 +41,8 @@ data Quadruple v
|
|||||||
| ProductQuadruple (Operand v) (Operand v) v
|
| ProductQuadruple (Operand v) (Operand v) v
|
||||||
| DivisionQuadruple (Operand v) (Operand v) v
|
| DivisionQuadruple (Operand v) (Operand v) v
|
||||||
| GoToQuadruple Label
|
| GoToQuadruple Label
|
||||||
{-| AssignQuadruple Operand Variable
|
| AssignQuadruple (Operand v) v
|
||||||
| ArrayQuadruple Variable Operand Variable
|
{-| ArrayQuadruple Variable Operand Variable
|
||||||
| ArrayAssignQuadruple Operand Operand Variable -}
|
| ArrayAssignQuadruple Operand Operand Variable -}
|
||||||
| LessOrEqualQuadruple (Operand v) (Operand v) Label
|
| LessOrEqualQuadruple (Operand v) (Operand v) Label
|
||||||
| GreaterOrEqualQuadruple (Operand v) (Operand v) Label
|
| GreaterOrEqualQuadruple (Operand v) (Operand v) Label
|
||||||
|
@ -6,7 +6,7 @@ module Language.Elna.Frontend.AST
|
|||||||
, Statement(..)
|
, Statement(..)
|
||||||
, TypeExpression(..)
|
, TypeExpression(..)
|
||||||
, VariableDeclaration(..)
|
, VariableDeclaration(..)
|
||||||
--, VariableAccess(..)
|
, VariableAccess(..)
|
||||||
, Condition(..)
|
, Condition(..)
|
||||||
, Expression(..)
|
, Expression(..)
|
||||||
, Literal(..)
|
, Literal(..)
|
||||||
@ -70,8 +70,8 @@ instance Show TypeExpression
|
|||||||
data Statement
|
data Statement
|
||||||
= EmptyStatement
|
= EmptyStatement
|
||||||
| IfStatement Condition Statement (Maybe Statement)
|
| IfStatement Condition Statement (Maybe Statement)
|
||||||
{-| AssignmentStatement VariableAccess Expression
|
| AssignmentStatement VariableAccess Expression
|
||||||
| WhileStatement Condition Statement -}
|
-- | WhileStatement Condition Statement
|
||||||
| CompoundStatement [Statement]
|
| CompoundStatement [Statement]
|
||||||
| CallStatement Identifier [Expression]
|
| CallStatement Identifier [Expression]
|
||||||
deriving Eq
|
deriving Eq
|
||||||
@ -84,9 +84,9 @@ instance Show Statement
|
|||||||
, show if'
|
, show if'
|
||||||
, maybe "" ((<> " else ") . show) else'
|
, maybe "" ((<> " else ") . show) else'
|
||||||
]
|
]
|
||||||
{-show (AssignmentStatement lhs rhs) =
|
show (AssignmentStatement lhs rhs) =
|
||||||
concat [show lhs, " := ", show rhs, ";"]
|
concat [show lhs, " := ", show rhs, ";"]
|
||||||
show (WhileStatement expression statement) =
|
{-show (WhileStatement expression statement) =
|
||||||
concat ["while (", show expression, ") ", show statement, ";"]-}
|
concat ["while (", show expression, ") ", show statement, ";"]-}
|
||||||
show (CompoundStatement statements) =
|
show (CompoundStatement statements) =
|
||||||
concat ["{\n", unlines (show <$> statements), " }"]
|
concat ["{\n", unlines (show <$> statements), " }"]
|
||||||
@ -163,7 +163,7 @@ data Expression
|
|||||||
| NegationExpression Expression
|
| NegationExpression Expression
|
||||||
| ProductExpression Expression Expression
|
| ProductExpression Expression Expression
|
||||||
| DivisionExpression Expression Expression
|
| DivisionExpression Expression Expression
|
||||||
-- | VariableExpression VariableAccess
|
| VariableExpression VariableAccess
|
||||||
deriving Eq
|
deriving Eq
|
||||||
|
|
||||||
instance Show Expression
|
instance Show Expression
|
||||||
@ -174,19 +174,19 @@ instance Show Expression
|
|||||||
show (NegationExpression negation) = '-' : show negation
|
show (NegationExpression negation) = '-' : show negation
|
||||||
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
|
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
|
||||||
show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs]
|
show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs]
|
||||||
-- show (VariableExpression variable) = show variable
|
show (VariableExpression variable) = show variable
|
||||||
{-
|
|
||||||
data VariableAccess
|
newtype VariableAccess
|
||||||
= VariableAccess Identifier
|
= VariableAccess Identifier
|
||||||
| ArrayAccess VariableAccess Expression
|
-- | ArrayAccess VariableAccess Expression
|
||||||
deriving Eq
|
deriving Eq
|
||||||
|
|
||||||
instance Show VariableAccess
|
instance Show VariableAccess
|
||||||
where
|
where
|
||||||
show (VariableAccess variableName) = show variableName
|
show (VariableAccess variableName) = show variableName
|
||||||
show (ArrayAccess arrayAccess elementIndex) =
|
{- show (ArrayAccess arrayAccess elementIndex) =
|
||||||
concat [show arrayAccess, "[", show elementIndex, "]"]
|
concat [show arrayAccess, "[", show elementIndex, "]"] -}
|
||||||
-}
|
|
||||||
data Condition
|
data Condition
|
||||||
= EqualCondition Expression Expression
|
= EqualCondition Expression Expression
|
||||||
| NonEqualCondition Expression Expression
|
| NonEqualCondition Expression Expression
|
||||||
|
@ -158,9 +158,9 @@ expression globalTable (AST.ProductExpression lhs rhs)
|
|||||||
expression globalTable (AST.DivisionExpression lhs rhs)
|
expression globalTable (AST.DivisionExpression lhs rhs)
|
||||||
= expression globalTable lhs
|
= expression globalTable lhs
|
||||||
>> expression globalTable rhs
|
>> expression globalTable rhs
|
||||||
{- expression globalTable (AST.VariableExpression variableExpression) =
|
expression globalTable (AST.VariableExpression variableExpression) =
|
||||||
variableAccess globalTable variableExpression
|
variableAccess globalTable variableExpression
|
||||||
-}
|
|
||||||
statement :: SymbolTable -> AST.Statement -> NameAnalysis ()
|
statement :: SymbolTable -> AST.Statement -> NameAnalysis ()
|
||||||
statement _ AST.EmptyStatement = pure ()
|
statement _ AST.EmptyStatement = pure ()
|
||||||
statement globalTable (AST.CallStatement name arguments)
|
statement globalTable (AST.CallStatement name arguments)
|
||||||
@ -172,9 +172,9 @@ statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement)
|
|||||||
= condition globalTable ifCondition
|
= condition globalTable ifCondition
|
||||||
>> statement globalTable ifStatement
|
>> statement globalTable ifStatement
|
||||||
>> maybe (pure ()) (statement globalTable) elseStatement
|
>> maybe (pure ()) (statement globalTable) elseStatement
|
||||||
-- statement globalTable (AST.AssignmentStatement lvalue rvalue)
|
statement globalTable (AST.AssignmentStatement lvalue rvalue)
|
||||||
-- = variableAccess globalTable lvalue
|
= variableAccess globalTable lvalue
|
||||||
-- >> expression globalTable rvalue
|
>> expression globalTable rvalue
|
||||||
--statement globalTable (AST.WhileStatement whileCondition loop)
|
--statement globalTable (AST.WhileStatement whileCondition loop)
|
||||||
-- = condition globalTable whileCondition
|
-- = condition globalTable whileCondition
|
||||||
-- >> statement globalTable loop
|
-- >> statement globalTable loop
|
||||||
@ -198,13 +198,13 @@ condition globalTable (AST.LessOrEqualCondition lhs rhs)
|
|||||||
condition globalTable (AST.GreaterOrEqualCondition lhs rhs)
|
condition globalTable (AST.GreaterOrEqualCondition lhs rhs)
|
||||||
= expression globalTable lhs
|
= expression globalTable lhs
|
||||||
>> expression globalTable rhs
|
>> expression globalTable rhs
|
||||||
{-
|
|
||||||
variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
|
variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
|
||||||
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
|
|
||||||
= variableAccess globalTable arrayExpression
|
|
||||||
>> expression globalTable indexExpression
|
|
||||||
variableAccess globalTable (AST.VariableAccess identifier) =
|
variableAccess globalTable (AST.VariableAccess identifier) =
|
||||||
checkSymbol globalTable 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 -> SymbolTable -> NameAnalysis SymbolTable
|
||||||
enter identifier info table
|
enter identifier info table
|
||||||
@ -216,9 +216,4 @@ identifierAlreadyDefinedError = NameAnalysis
|
|||||||
. lift
|
. lift
|
||||||
. throwE
|
. throwE
|
||||||
. IdentifierAlreadyDefinedError
|
. IdentifierAlreadyDefinedError
|
||||||
|
|
||||||
variableDeclaration :: AST.VariableDeclaration -> NameAnalysis (Identifier, Info)
|
|
||||||
variableDeclaration (AST.VariableDeclaration identifier typeExpression)
|
|
||||||
= (identifier,) . VariableInfo False
|
|
||||||
<$> dataType typeExpression
|
|
||||||
-}
|
-}
|
||||||
|
@ -16,7 +16,7 @@ import Language.Elna.Frontend.AST
|
|||||||
, Statement(..)
|
, Statement(..)
|
||||||
, TypeExpression(..)
|
, TypeExpression(..)
|
||||||
, VariableDeclaration(..)
|
, VariableDeclaration(..)
|
||||||
--, VariableAccess(..)
|
, VariableAccess(..)
|
||||||
, Condition(..)
|
, Condition(..)
|
||||||
, Expression(..)
|
, Expression(..)
|
||||||
, Literal(..)
|
, Literal(..)
|
||||||
@ -64,7 +64,7 @@ termP :: Parser Expression
|
|||||||
termP = choice
|
termP = choice
|
||||||
[ parensP expressionP
|
[ parensP expressionP
|
||||||
, LiteralExpression <$> literalP
|
, LiteralExpression <$> literalP
|
||||||
-- , VariableExpression <$> variableAccessP
|
, VariableExpression <$> variableAccessP
|
||||||
]
|
]
|
||||||
|
|
||||||
operatorTable :: [[Operator Parser Expression]]
|
operatorTable :: [[Operator Parser Expression]]
|
||||||
@ -91,13 +91,13 @@ operatorTable =
|
|||||||
|
|
||||||
expressionP :: Parser Expression
|
expressionP :: Parser Expression
|
||||||
expressionP = makeExprParser termP operatorTable
|
expressionP = makeExprParser termP operatorTable
|
||||||
{-
|
|
||||||
variableAccessP :: Parser VariableAccess
|
variableAccessP :: Parser VariableAccess
|
||||||
variableAccessP = do
|
variableAccessP = VariableAccess <$> identifierP {- do
|
||||||
identifier <- identifierP
|
identifier <- identifierP
|
||||||
indices <- many $ bracketsP expressionP
|
indices <- many $ bracketsP expressionP
|
||||||
pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices
|
pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices -}
|
||||||
-}
|
|
||||||
conditionP :: Parser Condition
|
conditionP :: Parser Condition
|
||||||
conditionP = do
|
conditionP = do
|
||||||
lhs <- expressionP
|
lhs <- expressionP
|
||||||
@ -187,8 +187,8 @@ statementP
|
|||||||
= EmptyStatement <$ semicolonP
|
= EmptyStatement <$ semicolonP
|
||||||
<|> ifElseP
|
<|> ifElseP
|
||||||
<|> CompoundStatement <$> blockP (many statementP)
|
<|> CompoundStatement <$> blockP (many statementP)
|
||||||
{-<|> try assignmentP
|
<|> try assignmentP
|
||||||
<|> try whileP -}
|
-- <|> try whileP
|
||||||
<|> callP
|
<|> callP
|
||||||
<?> "statement"
|
<?> "statement"
|
||||||
where
|
where
|
||||||
@ -202,12 +202,12 @@ statementP
|
|||||||
<*> optional (symbol "else" *> statementP)
|
<*> optional (symbol "else" *> statementP)
|
||||||
{-whileP = WhileStatement
|
{-whileP = WhileStatement
|
||||||
<$> (symbol "while" *> parensP conditionP)
|
<$> (symbol "while" *> parensP conditionP)
|
||||||
<*> statementP
|
<*> statementP -}
|
||||||
assignmentP = AssignmentStatement
|
assignmentP = AssignmentStatement
|
||||||
<$> variableAccessP
|
<$> variableAccessP
|
||||||
<* symbol ":="
|
<* symbol ":="
|
||||||
<*> expressionP
|
<*> expressionP
|
||||||
<* semicolonP -}
|
<* semicolonP
|
||||||
|
|
||||||
variableDeclarationP :: Parser VariableDeclaration
|
variableDeclarationP :: Parser VariableDeclaration
|
||||||
variableDeclarationP = VariableDeclaration
|
variableDeclarationP = VariableDeclaration
|
||||||
|
@ -3,10 +3,11 @@ module Language.Elna.Frontend.TypeAnalysis
|
|||||||
, -- Error(..)
|
, -- Error(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Control.Applicative (Alternative(..))
|
||||||
import Control.Monad (unless)
|
import Control.Monad (unless)
|
||||||
import Control.Monad.Trans.Class (MonadTrans(..))
|
import Control.Monad.Trans.Class (MonadTrans(..))
|
||||||
import Control.Monad.Trans.Except (Except, runExcept, throwE)
|
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 Data.Foldable (traverse_)
|
||||||
import qualified Data.Vector as Vector
|
import qualified Data.Vector as Vector
|
||||||
import qualified Language.Elna.Frontend.AST as AST
|
import qualified Language.Elna.Frontend.AST as AST
|
||||||
@ -22,9 +23,6 @@ typeAnalysis globalTable = either Just (const Nothing)
|
|||||||
. runTypeAnalysis
|
. runTypeAnalysis
|
||||||
. program
|
. program
|
||||||
|
|
||||||
{-
|
|
||||||
import Control.Applicative (Alternative(..))
|
|
||||||
-}
|
|
||||||
data Error
|
data Error
|
||||||
= UnexpectedProcedureInfoError Info
|
= UnexpectedProcedureInfoError Info
|
||||||
| UndefinedSymbolError Identifier
|
| UndefinedSymbolError Identifier
|
||||||
@ -96,14 +94,14 @@ declaration (AST.TypeDefinition _ _) = pure ()
|
|||||||
statement :: SymbolTable -> AST.Statement -> TypeAnalysis ()
|
statement :: SymbolTable -> AST.Statement -> TypeAnalysis ()
|
||||||
statement globalTable = \case
|
statement globalTable = \case
|
||||||
AST.EmptyStatement -> pure ()
|
AST.EmptyStatement -> pure ()
|
||||||
{- AST.AssignmentStatement lhs rhs -> do
|
AST.AssignmentStatement lhs rhs -> do
|
||||||
lhsType <- variableAccess globalTable lhs
|
lhsType <- variableAccess globalTable lhs
|
||||||
rhsType <- expression globalTable rhs
|
rhsType <- expression globalTable rhs
|
||||||
unless (lhsType == intType)
|
unless (lhsType == intType)
|
||||||
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError lhsType
|
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError lhsType
|
||||||
unless (rhsType == intType)
|
unless (rhsType == intType)
|
||||||
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError rhsType
|
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError rhsType
|
||||||
AST.WhileStatement whileCondition whileStatement -> do
|
{- AST.WhileStatement whileCondition whileStatement -> do
|
||||||
conditionType <- condition globalTable whileCondition
|
conditionType <- condition globalTable whileCondition
|
||||||
unless (conditionType == booleanType)
|
unless (conditionType == booleanType)
|
||||||
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError conditionType
|
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError conditionType
|
||||||
@ -136,7 +134,7 @@ statement globalTable = \case
|
|||||||
when (isReferenceParameter && not (isLvalue argument))
|
when (isReferenceParameter && not (isLvalue argument))
|
||||||
$ TypeAnalysis $ lift $ throwE $ ExpectedLvalueError argument
|
$ TypeAnalysis $ lift $ throwE $ ExpectedLvalueError argument
|
||||||
isLvalue (AST.VariableExpression _) = True
|
isLvalue (AST.VariableExpression _) = True
|
||||||
isLvalue _ = False
|
isLvalue _ = False -}
|
||||||
|
|
||||||
variableAccess :: SymbolTable -> AST.VariableAccess -> TypeAnalysis Type
|
variableAccess :: SymbolTable -> AST.VariableAccess -> TypeAnalysis Type
|
||||||
variableAccess globalTable (AST.VariableAccess identifier) = do
|
variableAccess globalTable (AST.VariableAccess identifier) = do
|
||||||
@ -147,7 +145,7 @@ variableAccess globalTable (AST.VariableAccess identifier) = do
|
|||||||
$ UnexpectedVariableInfoError anotherInfo
|
$ UnexpectedVariableInfoError anotherInfo
|
||||||
Nothing -> TypeAnalysis $ lift $ throwE
|
Nothing -> TypeAnalysis $ lift $ throwE
|
||||||
$ UndefinedSymbolError identifier
|
$ UndefinedSymbolError identifier
|
||||||
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = do
|
{-variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = do
|
||||||
arrayType <- variableAccess globalTable arrayExpression
|
arrayType <- variableAccess globalTable arrayExpression
|
||||||
indexType <- expression globalTable indexExpression
|
indexType <- expression globalTable indexExpression
|
||||||
unless (indexType == intType)
|
unless (indexType == intType)
|
||||||
@ -159,8 +157,8 @@ variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = d
|
|||||||
-}
|
-}
|
||||||
expression :: SymbolTable -> AST.Expression -> TypeAnalysis Type
|
expression :: SymbolTable -> AST.Expression -> TypeAnalysis Type
|
||||||
expression globalTable = \case
|
expression globalTable = \case
|
||||||
{- AST.VariableExpression variableExpression -> do
|
AST.VariableExpression variableExpression ->
|
||||||
variableAccess globalTable variableExpression -}
|
variableAccess globalTable variableExpression
|
||||||
AST.LiteralExpression literal' -> literal literal'
|
AST.LiteralExpression literal' -> literal literal'
|
||||||
AST.NegationExpression negation -> do
|
AST.NegationExpression negation -> do
|
||||||
operandType <- expression globalTable negation
|
operandType <- expression globalTable negation
|
||||||
|
@ -15,13 +15,15 @@ import qualified Data.Text.Lazy as Text.Lazy
|
|||||||
import qualified Data.Vector as Vector
|
import qualified Data.Vector as Vector
|
||||||
import Data.Word (Word32)
|
import Data.Word (Word32)
|
||||||
import qualified Language.Elna.Frontend.AST as AST
|
import qualified Language.Elna.Frontend.AST as AST
|
||||||
|
import Language.Elna.Frontend.Types (Type(..))
|
||||||
import Language.Elna.Backend.Intermediate
|
import Language.Elna.Backend.Intermediate
|
||||||
( Label(..)
|
( Label(..)
|
||||||
, Operand(..)
|
, Operand(..)
|
||||||
, Quadruple(..)
|
, Quadruple(..)
|
||||||
, Variable(..)
|
, Variable(..)
|
||||||
)
|
)
|
||||||
import Language.Elna.Frontend.SymbolTable (SymbolTable)
|
import Language.Elna.Frontend.SymbolTable (Info(..), SymbolTable)
|
||||||
|
import qualified Language.Elna.Frontend.SymbolTable as SymbolTable
|
||||||
import GHC.Records (HasField(..))
|
import GHC.Records (HasField(..))
|
||||||
|
|
||||||
data Paste = Paste
|
data Paste = Paste
|
||||||
@ -98,20 +100,20 @@ statement localTable (AST.IfStatement ifCondition ifStatement elseStatement) = d
|
|||||||
<> Vector.snoc ifStatements (LabelQuadruple endLabel)
|
<> Vector.snoc ifStatements (LabelQuadruple endLabel)
|
||||||
Nothing -> Vector.fromList [jumpConstructor ifLabel, GoToQuadruple endLabel, LabelQuadruple ifLabel]
|
Nothing -> Vector.fromList [jumpConstructor ifLabel, GoToQuadruple endLabel, LabelQuadruple ifLabel]
|
||||||
<> Vector.snoc ifStatements (LabelQuadruple endLabel)
|
<> Vector.snoc ifStatements (LabelQuadruple endLabel)
|
||||||
{- statement localTable (AST.AssignmentStatement variableAccess' assignee) = do
|
statement localTable (AST.AssignmentStatement variableAccess' assignee) = do
|
||||||
(rhsOperand, rhsStatements) <- expression localTable assignee
|
(rhsOperand, rhsStatements) <- expression localTable assignee
|
||||||
let variableType' = variableType variableAccess' localTable
|
let variableType' = variableType variableAccess' localTable
|
||||||
accessResult <- variableAccess localTable variableAccess' Nothing variableType' mempty
|
accessResult <- variableAccess localTable variableAccess' Nothing variableType' mempty
|
||||||
pure $ rhsStatements <> case accessResult of
|
pure $ rhsStatements <> case accessResult of
|
||||||
(AST.Identifier identifier, Just accumulatedIndex, accumulatedStatements) ->
|
{-(AST.Identifier identifier, Just accumulatedIndex, accumulatedStatements) ->
|
||||||
Vector.snoc accumulatedStatements
|
Vector.snoc accumulatedStatements
|
||||||
$ ArrayAssignQuadruple rhsOperand accumulatedIndex
|
$ ArrayAssignQuadruple rhsOperand accumulatedIndex
|
||||||
$ Variable identifier
|
$ LocalVariable identifier -}
|
||||||
(AST.Identifier identifier, Nothing, accumulatedStatements) ->
|
(AST.Identifier identifier, Nothing, accumulatedStatements) ->
|
||||||
Vector.snoc accumulatedStatements
|
Vector.snoc accumulatedStatements
|
||||||
$ AssignQuadruple rhsOperand
|
$ AssignQuadruple rhsOperand
|
||||||
$ Variable identifier
|
$ LocalVariable 0
|
||||||
statement localTable (AST.WhileStatement whileCondition whileStatement) = do
|
{- statement localTable (AST.WhileStatement whileCondition whileStatement) = do
|
||||||
(conditionStatements, jumpConstructor) <- condition localTable whileCondition
|
(conditionStatements, jumpConstructor) <- condition localTable whileCondition
|
||||||
startLabel <- createLabel
|
startLabel <- createLabel
|
||||||
endLabel <- createLabel
|
endLabel <- createLabel
|
||||||
@ -189,20 +191,17 @@ condition localTable (AST.GreaterOrEqualCondition lhs rhs) = do
|
|||||||
( lhsStatements <> rhsStatements
|
( lhsStatements <> rhsStatements
|
||||||
, GreaterOrEqualQuadruple lhsOperand rhsOperand
|
, GreaterOrEqualQuadruple lhsOperand rhsOperand
|
||||||
)
|
)
|
||||||
{-
|
|
||||||
import Language.Elna.Types (Type(..))
|
|
||||||
import qualified Language.Elna.SymbolTable as SymbolTable
|
|
||||||
|
|
||||||
variableAccess
|
variableAccess
|
||||||
:: SymbolTable
|
:: SymbolTable
|
||||||
-> AST.VariableAccess
|
-> AST.VariableAccess
|
||||||
-> Maybe Operand
|
-> Maybe (Operand Variable)
|
||||||
-> Type
|
-> Type
|
||||||
-> Vector Quadruple
|
-> Vector (Quadruple Variable)
|
||||||
-> Glue (AST.Identifier, Maybe Operand, Vector Quadruple)
|
-> Glue (AST.Identifier, Maybe (Operand Variable), Vector (Quadruple Variable))
|
||||||
variableAccess _ (AST.VariableAccess identifier) accumulatedIndex _ accumulatedStatements =
|
variableAccess _ (AST.VariableAccess identifier) accumulatedIndex _ accumulatedStatements =
|
||||||
pure (identifier, accumulatedIndex, accumulatedStatements)
|
pure (identifier, accumulatedIndex, accumulatedStatements)
|
||||||
variableAccess localTable (AST.ArrayAccess access1 index1) Nothing (ArrayType _ baseType) _ = do
|
{- variableAccess localTable (AST.ArrayAccess access1 index1) Nothing (ArrayType _ baseType) _ = do
|
||||||
(indexPlace, statements) <- expression localTable index1
|
(indexPlace, statements) <- expression localTable index1
|
||||||
variableAccess localTable access1 (Just indexPlace) baseType statements
|
variableAccess localTable access1 (Just indexPlace) baseType statements
|
||||||
variableAccess localTable (AST.ArrayAccess arrayAccess' arrayIndex) (Just baseIndex) (ArrayType arraySize baseType) statements = do
|
variableAccess localTable (AST.ArrayAccess arrayAccess' arrayIndex) (Just baseIndex) (ArrayType arraySize baseType) statements = do
|
||||||
@ -216,14 +215,14 @@ variableAccess localTable (AST.ArrayAccess arrayAccess' arrayIndex) (Just baseIn
|
|||||||
in variableAccess localTable arrayAccess' (Just resultOperand) baseType
|
in variableAccess localTable arrayAccess' (Just resultOperand) baseType
|
||||||
$ statements <> indexCalculation <> statements'
|
$ statements <> indexCalculation <> statements'
|
||||||
variableAccess _ _ _ _ _ = error "Array access operator doesn't match the type."
|
variableAccess _ _ _ _ _ = error "Array access operator doesn't match the type."
|
||||||
|
-}
|
||||||
variableType :: AST.VariableAccess -> SymbolTable -> Type
|
variableType :: AST.VariableAccess -> SymbolTable -> Type
|
||||||
variableType (AST.VariableAccess identifier) symbolTable
|
variableType (AST.VariableAccess identifier) symbolTable
|
||||||
| Just (TypeInfo type') <- SymbolTable.lookup identifier symbolTable = type'
|
| Just (TypeInfo type') <- SymbolTable.lookup identifier symbolTable = type'
|
||||||
| otherwise = error "Undefined type."
|
| otherwise = error "Undefined type."
|
||||||
variableType (AST.ArrayAccess arrayAccess' _) symbolTable =
|
{-variableType (AST.ArrayAccess arrayAccess' _) symbolTable =
|
||||||
variableType arrayAccess' symbolTable
|
variableType arrayAccess' symbolTable -}
|
||||||
-}
|
|
||||||
expression :: SymbolTable -> AST.Expression -> Glue (Operand Variable, Vector (Quadruple Variable))
|
expression :: SymbolTable -> AST.Expression -> Glue (Operand Variable, Vector (Quadruple Variable))
|
||||||
expression localTable = \case
|
expression localTable = \case
|
||||||
(AST.LiteralExpression literal') -> pure (literal literal', mempty)
|
(AST.LiteralExpression literal') -> pure (literal literal', mempty)
|
||||||
@ -242,8 +241,9 @@ expression localTable = \case
|
|||||||
binaryExpression ProductQuadruple lhs rhs
|
binaryExpression ProductQuadruple lhs rhs
|
||||||
(AST.DivisionExpression lhs rhs) ->
|
(AST.DivisionExpression lhs rhs) ->
|
||||||
binaryExpression DivisionQuadruple lhs rhs
|
binaryExpression DivisionQuadruple lhs rhs
|
||||||
{- (AST.VariableExpression variableExpression) -> do
|
(AST.VariableExpression variableExpression) -> do
|
||||||
let variableType' = variableType variableExpression localTable
|
pure (VariableOperand (LocalVariable 0), mempty)
|
||||||
|
{- let variableType' = variableType variableExpression localTable
|
||||||
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
|
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
|
||||||
case variableAccess' of
|
case variableAccess' of
|
||||||
(AST.Identifier identifier, Nothing, statements) ->
|
(AST.Identifier identifier, Nothing, statements) ->
|
||||||
|
@ -427,11 +427,11 @@ quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel)
|
|||||||
then pure $ Vector.singleton $ unconditionalJal goToLabel
|
then pure $ Vector.singleton $ unconditionalJal goToLabel
|
||||||
else pure Vector.empty
|
else pure Vector.empty
|
||||||
| VariableOperand variableOperand1 <- operand1
|
| VariableOperand variableOperand1 <- operand1
|
||||||
, VariableOperand variableOperand2 <- operand2 = do
|
, VariableOperand variableOperand2 <- operand2 =
|
||||||
let Store operandRegister1 = variableOperand1
|
let Store operandRegister1 = variableOperand1
|
||||||
Store operandRegister2 = variableOperand2
|
Store operandRegister2 = variableOperand2
|
||||||
Label goToLabel' = goToLabel
|
Label goToLabel' = goToLabel
|
||||||
pure $ Vector.singleton
|
in pure $ Vector.singleton
|
||||||
$ Instruction
|
$ Instruction
|
||||||
$ RiscV.RelocatableInstruction RiscV.Branch
|
$ RiscV.RelocatableInstruction RiscV.Branch
|
||||||
$ RiscV.RBranch goToLabel' RiscV.BGE operandRegister1 operandRegister2
|
$ RiscV.RBranch goToLabel' RiscV.BGE operandRegister1 operandRegister2
|
||||||
@ -453,6 +453,15 @@ quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel)
|
|||||||
$ Instruction
|
$ Instruction
|
||||||
$ RiscV.RelocatableInstruction RiscV.Branch
|
$ RiscV.RelocatableInstruction RiscV.Branch
|
||||||
$ RiscV.RBranch goToLabel' RiscV.BGE immediateRegister operandRegister2
|
$ RiscV.RBranch goToLabel' RiscV.BGE immediateRegister operandRegister2
|
||||||
|
quadruple (AssignQuadruple operand1 (Store register))
|
||||||
|
| IntOperand immediateOperand1 <- operand1 = pure
|
||||||
|
$ lui immediateOperand1 register
|
||||||
|
| VariableOperand variableOperand1 <- operand1 =
|
||||||
|
let Store operandRegister1 = variableOperand1
|
||||||
|
in pure $ Vector.singleton
|
||||||
|
$ Instruction
|
||||||
|
$ RiscV.BaseInstruction RiscV.OpImm
|
||||||
|
$ RiscV.I register RiscV.ADDI operandRegister1 0
|
||||||
|
|
||||||
unconditionalJal :: Label -> Statement
|
unconditionalJal :: Label -> Statement
|
||||||
unconditionalJal (Label goToLabel) = Instruction
|
unconditionalJal (Label goToLabel) = Instruction
|
||||||
|
1
tests/expectations/define_variable.txt
Normal file
1
tests/expectations/define_variable.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
58
|
6
tests/vm/define_variable.elna
Normal file
6
tests/vm/define_variable.elna
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
proc main() {
|
||||||
|
var i: int;
|
||||||
|
i := 58;
|
||||||
|
|
||||||
|
printi(i);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user