Implement if statements with equality
This commit is contained in:
parent
87f183baad
commit
0850f0a8d6
1
TODO
1
TODO
@ -14,7 +14,6 @@
|
|||||||
- Sort the symbols so that local symbols come first. Some table header had a
|
- Sort the symbols so that local symbols come first. Some table header had a
|
||||||
number specifiying the index of the first non-local symbol. Adjust that number.
|
number specifiying the index of the first non-local symbol. Adjust that number.
|
||||||
|
|
||||||
|
|
||||||
# Name analysis
|
# Name analysis
|
||||||
|
|
||||||
- Format error messages.
|
- Format error messages.
|
||||||
|
@ -146,6 +146,7 @@ data RelocationType
|
|||||||
| RLower12S Text Funct3 XRegister XRegister
|
| RLower12S Text Funct3 XRegister XRegister
|
||||||
| RHigher20 XRegister Text -- Type U.
|
| RHigher20 XRegister Text -- Type U.
|
||||||
| RBranch Text Funct3 XRegister XRegister -- Type B.
|
| RBranch Text Funct3 XRegister XRegister -- Type B.
|
||||||
|
| RJal XRegister Text -- Type J.
|
||||||
deriving Eq
|
deriving Eq
|
||||||
|
|
||||||
data Instruction
|
data Instruction
|
||||||
@ -304,6 +305,7 @@ relocationType (RLower12I rd funct3' rs1 _) = type' $ I rd funct3' rs1 0
|
|||||||
relocationType (RLower12S _ funct3' rs1 rs2) = type' $ S 0 funct3' rs1 rs2
|
relocationType (RLower12S _ funct3' rs1 rs2) = type' $ S 0 funct3' rs1 rs2
|
||||||
relocationType (RHigher20 rd _) = type' $ U rd 0
|
relocationType (RHigher20 rd _) = type' $ U rd 0
|
||||||
relocationType (RBranch _ funct3' rs1 rs2) = type' $ B 0 funct3' rs1 rs2
|
relocationType (RBranch _ funct3' rs1 rs2) = type' $ B 0 funct3' rs1 rs2
|
||||||
|
relocationType (RJal rd _) = type' $ J rd 0
|
||||||
|
|
||||||
instruction :: Instruction -> ByteString.Builder.Builder
|
instruction :: Instruction -> ByteString.Builder.Builder
|
||||||
instruction = \case
|
instruction = \case
|
||||||
|
@ -50,6 +50,10 @@ allocate MachineConfiguration{..} = fmap function
|
|||||||
= DivisionQuadruple (operand operand1) (operand operand2)
|
= DivisionQuadruple (operand operand1) (operand operand2)
|
||||||
$ Store
|
$ Store
|
||||||
$ temporaryRegisters !! fromIntegral index
|
$ temporaryRegisters !! fromIntegral index
|
||||||
|
quadruple (LabelQuadruple label) = LabelQuadruple label
|
||||||
|
quadruple (GoToQuadruple label) = GoToQuadruple label
|
||||||
|
quadruple (EqualQuadruple operand1 operand2 goToLabel) =
|
||||||
|
EqualQuadruple (operand operand1) (operand operand2) goToLabel
|
||||||
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))
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
module Language.Elna.Backend.Intermediate
|
module Language.Elna.Backend.Intermediate
|
||||||
( Operand(..)
|
( Operand(..)
|
||||||
, Quadruple(..)
|
, Quadruple(..)
|
||||||
{- , Label(..) -}
|
, Label(..)
|
||||||
, Variable(..)
|
, Variable(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Int (Int32)
|
import Data.Int (Int32)
|
||||||
import Data.Word (Word32)
|
import Data.Word (Word32)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as Text
|
||||||
|
|
||||||
|
newtype Label = Label { unLabel :: Text }
|
||||||
|
deriving Eq
|
||||||
|
|
||||||
|
instance Show Label
|
||||||
|
where
|
||||||
|
show (Label label) = '.' : Text.unpack label
|
||||||
|
|
||||||
newtype Variable = TempVariable Word32 -- | Variable Text
|
newtype Variable = TempVariable Word32 -- | Variable Text
|
||||||
deriving Eq
|
deriving Eq
|
||||||
@ -32,15 +40,15 @@ data Quadruple v
|
|||||||
| NegationQuadruple (Operand v) v
|
| NegationQuadruple (Operand v) 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 Variable
|
||||||
| ArrayQuadruple Variable Operand Variable
|
| ArrayQuadruple Variable Operand Variable
|
||||||
| ArrayAssignQuadruple Operand Operand Variable
|
| ArrayAssignQuadruple Operand Operand Variable
|
||||||
| EqualQuadruple Operand Operand Label
|
|
||||||
| NonEqualQuadruple Operand Operand Label
|
| NonEqualQuadruple Operand Operand Label
|
||||||
| LessQuadruple Operand Operand Label
|
| LessQuadruple Operand Operand Label
|
||||||
| GreaterQuadruple Operand Operand Label
|
| GreaterQuadruple Operand Operand Label
|
||||||
| LessOrEqualQuadruple Operand Operand Label
|
| LessOrEqualQuadruple Operand Operand Label
|
||||||
| GreaterOrEqualQuadruple Operand Operand Label
|
| GreaterOrEqualQuadruple Operand Operand Label -}
|
||||||
| LabelQuadruple Label -}
|
| EqualQuadruple (Operand v) (Operand v) Label
|
||||||
|
| LabelQuadruple Label
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
@ -6,8 +6,8 @@ module Language.Elna.Frontend.AST
|
|||||||
, Statement(..)
|
, Statement(..)
|
||||||
, TypeExpression(..)
|
, TypeExpression(..)
|
||||||
, VariableDeclaration(..)
|
, VariableDeclaration(..)
|
||||||
{-, VariableAccess(..)
|
--, VariableAccess(..)
|
||||||
, Condition(..)-}
|
, Condition(..)
|
||||||
, Expression(..)
|
, Expression(..)
|
||||||
, Literal(..)
|
, Literal(..)
|
||||||
) where
|
) where
|
||||||
@ -67,8 +67,8 @@ instance Show TypeExpression
|
|||||||
|
|
||||||
data Statement
|
data Statement
|
||||||
= EmptyStatement
|
= EmptyStatement
|
||||||
{-| AssignmentStatement VariableAccess Expression
|
|
||||||
| IfStatement Condition Statement (Maybe Statement)
|
| IfStatement Condition Statement (Maybe Statement)
|
||||||
|
{-| AssignmentStatement VariableAccess Expression
|
||||||
| WhileStatement Condition Statement -}
|
| WhileStatement Condition Statement -}
|
||||||
| CompoundStatement [Statement]
|
| CompoundStatement [Statement]
|
||||||
| CallStatement Identifier [Expression]
|
| CallStatement Identifier [Expression]
|
||||||
@ -77,13 +77,13 @@ data Statement
|
|||||||
instance Show Statement
|
instance Show Statement
|
||||||
where
|
where
|
||||||
show EmptyStatement = ";"
|
show EmptyStatement = ";"
|
||||||
{-show (AssignmentStatement lhs rhs) =
|
|
||||||
concat [show lhs, " := ", show rhs, ";"]
|
|
||||||
show (IfStatement condition if' else') = concat
|
show (IfStatement condition if' else') = concat
|
||||||
[ "if (", show condition, ") "
|
[ "if (", show condition, ") "
|
||||||
, show if'
|
, show if'
|
||||||
, maybe "" ((<> " else ") . show) else'
|
, maybe "" ((<> " else ") . show) else'
|
||||||
]
|
]
|
||||||
|
{-show (AssignmentStatement lhs 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) =
|
||||||
@ -143,22 +143,21 @@ instance Show VariableAccess
|
|||||||
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
|
||||||
| LessCondition Expression Expression
|
-- | LessCondition Expression Expression
|
||||||
| GreaterCondition Expression Expression
|
-- | GreaterCondition Expression Expression
|
||||||
| LessOrEqualCondition Expression Expression
|
-- | LessOrEqualCondition Expression Expression
|
||||||
| GreaterOrEqualCondition Expression Expression
|
-- | GreaterOrEqualCondition Expression Expression
|
||||||
deriving Eq
|
deriving Eq
|
||||||
|
|
||||||
instance Show Condition
|
instance Show Condition
|
||||||
where
|
where
|
||||||
show (EqualCondition lhs rhs) = concat [show lhs, " = ", show rhs]
|
show (EqualCondition lhs rhs) = concat [show lhs, " = ", show rhs]
|
||||||
show (NonEqualCondition lhs rhs) = concat [show lhs, " # ", show rhs]
|
-- show (NonEqualCondition lhs rhs) = concat [show lhs, " # ", show rhs]
|
||||||
show (LessCondition lhs rhs) = concat [show lhs, " < ", show rhs]
|
-- show (LessCondition lhs rhs) = concat [show lhs, " < ", show rhs]
|
||||||
show (GreaterCondition lhs rhs) = concat [show lhs, " > ", show rhs]
|
-- show (GreaterCondition lhs rhs) = concat [show lhs, " > ", show rhs]
|
||||||
show (LessOrEqualCondition lhs rhs) = concat [show lhs, " <= ", show rhs]
|
-- show (LessOrEqualCondition lhs rhs) = concat [show lhs, " <= ", show rhs]
|
||||||
show (GreaterOrEqualCondition lhs rhs) = concat [show lhs, " >= ", show rhs]
|
-- show (GreaterOrEqualCondition lhs rhs) = concat [show lhs, " >= ", show rhs]
|
||||||
-}
|
|
||||||
|
@ -160,17 +160,37 @@ statement globalTable (AST.CallStatement name arguments)
|
|||||||
>> traverse_ (expression globalTable) arguments
|
>> traverse_ (expression globalTable) arguments
|
||||||
statement globalTable (AST.CompoundStatement statements) =
|
statement globalTable (AST.CompoundStatement statements) =
|
||||||
traverse_ (statement globalTable) statements
|
traverse_ (statement globalTable) statements
|
||||||
{- statement globalTable (AST.AssignmentStatement lvalue rvalue)
|
|
||||||
= variableAccess globalTable lvalue
|
|
||||||
>> expression globalTable rvalue
|
|
||||||
statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement)
|
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.WhileStatement whileCondition loop)
|
-- statement globalTable (AST.AssignmentStatement lvalue rvalue)
|
||||||
= condition globalTable whileCondition
|
-- = variableAccess globalTable lvalue
|
||||||
>> statement globalTable loop
|
-- >> expression globalTable rvalue
|
||||||
|
--statement globalTable (AST.WhileStatement whileCondition loop)
|
||||||
|
-- = condition globalTable whileCondition
|
||||||
|
-- >> statement globalTable loop
|
||||||
|
|
||||||
|
condition :: SymbolTable -> AST.Condition -> NameAnalysis ()
|
||||||
|
condition globalTable (AST.EqualCondition lhs rhs)
|
||||||
|
= expression globalTable lhs
|
||||||
|
>> expression globalTable rhs
|
||||||
|
--condition globalTable (AST.NonEqualCondition lhs rhs)
|
||||||
|
-- = expression globalTable lhs
|
||||||
|
-- >> expression globalTable rhs
|
||||||
|
--condition globalTable (AST.LessCondition lhs rhs)
|
||||||
|
-- = expression globalTable lhs
|
||||||
|
-- >> expression globalTable rhs
|
||||||
|
--condition globalTable (AST.GreaterCondition lhs rhs)
|
||||||
|
-- = expression globalTable lhs
|
||||||
|
-- >> expression globalTable rhs
|
||||||
|
--condition globalTable (AST.LessOrEqualCondition lhs rhs)
|
||||||
|
-- = expression globalTable lhs
|
||||||
|
-- >> expression globalTable rhs
|
||||||
|
--condition globalTable (AST.GreaterOrEqualCondition lhs rhs)
|
||||||
|
-- = expression globalTable lhs
|
||||||
|
-- >> expression globalTable rhs
|
||||||
|
{-
|
||||||
variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
|
variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
|
||||||
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
|
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
|
||||||
= variableAccess globalTable arrayExpression
|
= variableAccess globalTable arrayExpression
|
||||||
@ -178,26 +198,6 @@ variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
|
|||||||
variableAccess globalTable (AST.VariableAccess identifier) =
|
variableAccess globalTable (AST.VariableAccess identifier) =
|
||||||
checkSymbol globalTable identifier
|
checkSymbol globalTable identifier
|
||||||
|
|
||||||
condition :: SymbolTable -> AST.Condition -> NameAnalysis ()
|
|
||||||
condition globalTable (AST.EqualCondition lhs rhs)
|
|
||||||
= expression globalTable lhs
|
|
||||||
>> expression globalTable rhs
|
|
||||||
condition globalTable (AST.NonEqualCondition lhs rhs)
|
|
||||||
= expression globalTable lhs
|
|
||||||
>> expression globalTable rhs
|
|
||||||
condition globalTable (AST.LessCondition lhs rhs)
|
|
||||||
= expression globalTable lhs
|
|
||||||
>> expression globalTable rhs
|
|
||||||
condition globalTable (AST.GreaterCondition lhs rhs)
|
|
||||||
= expression globalTable lhs
|
|
||||||
>> expression globalTable rhs
|
|
||||||
condition globalTable (AST.LessOrEqualCondition lhs rhs)
|
|
||||||
= expression globalTable lhs
|
|
||||||
>> expression globalTable rhs
|
|
||||||
condition globalTable (AST.GreaterOrEqualCondition lhs rhs)
|
|
||||||
= expression globalTable lhs
|
|
||||||
>> expression globalTable rhs
|
|
||||||
|
|
||||||
enter :: Identifier -> Info -> SymbolTable -> NameAnalysis SymbolTable
|
enter :: Identifier -> Info -> SymbolTable -> NameAnalysis SymbolTable
|
||||||
enter identifier info table
|
enter identifier info table
|
||||||
= maybe (identifierAlreadyDefinedError identifier) pure
|
= maybe (identifierAlreadyDefinedError identifier) pure
|
||||||
|
@ -16,8 +16,8 @@ import Language.Elna.Frontend.AST
|
|||||||
, Statement(..)
|
, Statement(..)
|
||||||
, TypeExpression(..)
|
, TypeExpression(..)
|
||||||
, VariableDeclaration(..)
|
, VariableDeclaration(..)
|
||||||
{-, VariableAccess(..)
|
--, VariableAccess(..)
|
||||||
, Condition(..)-}
|
, Condition(..)
|
||||||
, Expression(..)
|
, Expression(..)
|
||||||
, Literal(..)
|
, Literal(..)
|
||||||
)
|
)
|
||||||
@ -97,7 +97,7 @@ variableAccessP = 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
|
||||||
@ -105,14 +105,14 @@ conditionP = do
|
|||||||
conditionCons lhs <$> expressionP
|
conditionCons lhs <$> expressionP
|
||||||
where
|
where
|
||||||
comparisonOperator =
|
comparisonOperator =
|
||||||
[ symbol "<" >> pure LessCondition
|
--, symbol "<" >> pure LessCondition
|
||||||
, symbol "<=" >> pure LessOrEqualCondition
|
--, symbol "<=" >> pure LessOrEqualCondition
|
||||||
, symbol ">" >> pure GreaterCondition
|
--, symbol ">" >> pure GreaterCondition
|
||||||
, symbol ">=" >> pure GreaterOrEqualCondition
|
--, symbol ">=" >> pure GreaterOrEqualCondition
|
||||||
, symbol "=" >> pure EqualCondition
|
[ symbol "=" >> pure EqualCondition
|
||||||
, symbol "#" >> pure NonEqualCondition
|
--, symbol "#" >> pure NonEqualCondition
|
||||||
]
|
]
|
||||||
-}
|
|
||||||
symbol :: Text -> Parser Text
|
symbol :: Text -> Parser Text
|
||||||
symbol = Lexer.symbol space
|
symbol = Lexer.symbol space
|
||||||
|
|
||||||
@ -182,22 +182,22 @@ procedureDeclarationP = procedureCons
|
|||||||
statementP :: Parser Statement
|
statementP :: Parser Statement
|
||||||
statementP
|
statementP
|
||||||
= EmptyStatement <$ semicolonP
|
= EmptyStatement <$ semicolonP
|
||||||
|
<|> ifElseP
|
||||||
{-<|> CompoundStatement <$> blockP (many statementP)
|
{-<|> CompoundStatement <$> blockP (many statementP)
|
||||||
<|> try assignmentP
|
<|> try assignmentP
|
||||||
<|> try ifElseP
|
|
||||||
<|> try whileP -}
|
<|> try whileP -}
|
||||||
<|> try callP
|
<|> callP
|
||||||
<?> "statement"
|
<?> "statement"
|
||||||
where
|
where
|
||||||
callP = CallStatement
|
callP = CallStatement
|
||||||
<$> identifierP
|
<$> identifierP
|
||||||
<*> parensP (sepBy expressionP commaP)
|
<*> parensP (sepBy expressionP commaP)
|
||||||
<* semicolonP
|
<* semicolonP
|
||||||
{-ifElseP = IfStatement
|
ifElseP = IfStatement
|
||||||
<$> (symbol "if" *> parensP conditionP)
|
<$> (symbol "if" *> parensP conditionP)
|
||||||
<*> statementP
|
<*> 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
|
||||||
|
@ -9,15 +9,24 @@ import Data.HashMap.Strict (HashMap)
|
|||||||
import qualified Data.HashMap.Strict as HashMap
|
import qualified Data.HashMap.Strict as HashMap
|
||||||
import Data.Maybe (catMaybes)
|
import Data.Maybe (catMaybes)
|
||||||
import Data.Vector (Vector)
|
import Data.Vector (Vector)
|
||||||
|
import qualified Data.Text.Lazy.Builder.Int as Text.Builder
|
||||||
|
import qualified Data.Text.Lazy.Builder as Text.Builder
|
||||||
|
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.Backend.Intermediate (Operand(..), Quadruple(..), Variable(..))
|
import Language.Elna.Backend.Intermediate
|
||||||
|
( Label(..)
|
||||||
|
, Operand(..)
|
||||||
|
, Quadruple(..)
|
||||||
|
, Variable(..)
|
||||||
|
)
|
||||||
import Language.Elna.Frontend.SymbolTable (SymbolTable)
|
import Language.Elna.Frontend.SymbolTable (SymbolTable)
|
||||||
import GHC.Records (HasField(..))
|
import GHC.Records (HasField(..))
|
||||||
|
|
||||||
newtype Paste = Paste
|
data Paste = Paste
|
||||||
{ temporaryCounter :: Word32
|
{ temporaryCounter :: Word32
|
||||||
|
, labelCounter :: Word32
|
||||||
}
|
}
|
||||||
|
|
||||||
newtype Glue a = Glue
|
newtype Glue a = Glue
|
||||||
@ -39,7 +48,7 @@ instance Monad Glue
|
|||||||
glue :: SymbolTable -> AST.Program -> HashMap AST.Identifier (Vector (Quadruple Variable))
|
glue :: SymbolTable -> AST.Program -> HashMap AST.Identifier (Vector (Quadruple Variable))
|
||||||
glue globalTable
|
glue globalTable
|
||||||
= fst
|
= fst
|
||||||
. flip runState Paste{ temporaryCounter = 0 }
|
. flip runState Paste{ temporaryCounter = 0, labelCounter = 0 }
|
||||||
. runGlue
|
. runGlue
|
||||||
. program globalTable
|
. program globalTable
|
||||||
|
|
||||||
@ -77,6 +86,18 @@ statement localTable (AST.CallStatement (AST.Identifier callName) arguments) = d
|
|||||||
$ Vector.length argumentStatements
|
$ Vector.length argumentStatements
|
||||||
statement localTable (AST.CompoundStatement statements) =
|
statement localTable (AST.CompoundStatement statements) =
|
||||||
fold <$> traverse (statement localTable) statements
|
fold <$> traverse (statement localTable) statements
|
||||||
|
statement localTable (AST.IfStatement ifCondition ifStatement elseStatement) = do
|
||||||
|
(conditionStatements, jumpConstructor) <- condition localTable ifCondition
|
||||||
|
ifLabel <- createLabel
|
||||||
|
endLabel <- createLabel
|
||||||
|
ifStatements <- statement localTable ifStatement
|
||||||
|
possibleElseStatements <- traverse (statement localTable) elseStatement
|
||||||
|
pure $ conditionStatements <> case possibleElseStatements of
|
||||||
|
Just elseStatements -> Vector.cons (jumpConstructor ifLabel) elseStatements
|
||||||
|
<> Vector.fromList [GoToQuadruple endLabel, LabelQuadruple ifLabel]
|
||||||
|
<> Vector.snoc ifStatements (LabelQuadruple endLabel)
|
||||||
|
Nothing -> Vector.fromList [jumpConstructor ifLabel, GoToQuadruple endLabel, LabelQuadruple ifLabel]
|
||||||
|
<> 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
|
||||||
@ -90,18 +111,6 @@ statement localTable (AST.CompoundStatement statements) =
|
|||||||
Vector.snoc accumulatedStatements
|
Vector.snoc accumulatedStatements
|
||||||
$ AssignQuadruple rhsOperand
|
$ AssignQuadruple rhsOperand
|
||||||
$ Variable identifier
|
$ Variable identifier
|
||||||
statement localTable (AST.IfStatement ifCondition ifStatement elseStatement) = do
|
|
||||||
(conditionStatements, jumpConstructor) <- condition localTable ifCondition
|
|
||||||
ifLabel <- createLabel
|
|
||||||
endLabel <- createLabel
|
|
||||||
ifStatements <- statement localTable ifStatement
|
|
||||||
possibleElseStatements <- traverse (statement localTable) elseStatement
|
|
||||||
pure $ conditionStatements <> case possibleElseStatements of
|
|
||||||
Just elseStatements -> Vector.cons (jumpConstructor ifLabel) elseStatements
|
|
||||||
<> Vector.fromList [GoToQuadruple endLabel, LabelQuadruple ifLabel]
|
|
||||||
<> Vector.snoc ifStatements (LabelQuadruple endLabel)
|
|
||||||
Nothing -> Vector.fromList [jumpConstructor ifLabel, GoToQuadruple endLabel, LabelQuadruple ifLabel]
|
|
||||||
<> Vector.snoc ifStatements (LabelQuadruple endLabel)
|
|
||||||
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
|
||||||
@ -124,21 +133,23 @@ createTemporary = do
|
|||||||
{ temporaryCounter = getField @"temporaryCounter" generator + 1
|
{ temporaryCounter = getField @"temporaryCounter" generator + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
{-
|
createLabel :: Glue Label
|
||||||
import Language.Elna.Types (Type(..))
|
createLabel = do
|
||||||
import qualified Language.Elna.SymbolTable as SymbolTable
|
currentCounter <- Glue $ gets $ getField @"labelCounter"
|
||||||
|
Glue $ modify' modifier
|
||||||
newtype Label = Label Text
|
pure $ Label
|
||||||
deriving Eq
|
$ Text.Lazy.toStrict
|
||||||
|
$ Text.Builder.toLazyText
|
||||||
instance Show Label
|
$ "L" <> Text.Builder.decimal currentCounter
|
||||||
where
|
where
|
||||||
show (Label label) = '.' : Text.unpack label
|
modifier generator = generator
|
||||||
|
{ labelCounter = getField @"labelCounter" generator + 1
|
||||||
|
}
|
||||||
|
|
||||||
condition
|
condition
|
||||||
:: SymbolTable
|
:: SymbolTable
|
||||||
-> AST.Condition
|
-> AST.Condition
|
||||||
-> Glue (Vector Quadruple, Label -> Quadruple)
|
-> Glue (Vector (Quadruple Variable), Label -> Quadruple Variable)
|
||||||
condition localTable (AST.EqualCondition lhs rhs) = do
|
condition localTable (AST.EqualCondition lhs rhs) = do
|
||||||
(lhsOperand, lhsStatements) <- expression localTable lhs
|
(lhsOperand, lhsStatements) <- expression localTable lhs
|
||||||
(rhsOperand, rhsStatements) <- expression localTable rhs
|
(rhsOperand, rhsStatements) <- expression localTable rhs
|
||||||
@ -146,7 +157,7 @@ condition localTable (AST.EqualCondition lhs rhs) = do
|
|||||||
( lhsStatements <> rhsStatements
|
( lhsStatements <> rhsStatements
|
||||||
, EqualQuadruple lhsOperand rhsOperand
|
, EqualQuadruple lhsOperand rhsOperand
|
||||||
)
|
)
|
||||||
condition localTable (AST.NonEqualCondition lhs rhs) = do
|
{- condition localTable (AST.NonEqualCondition lhs rhs) = do
|
||||||
(lhsOperand, lhsStatements) <- expression localTable lhs
|
(lhsOperand, lhsStatements) <- expression localTable lhs
|
||||||
(rhsOperand, rhsStatements) <- expression localTable rhs
|
(rhsOperand, rhsStatements) <- expression localTable rhs
|
||||||
pure
|
pure
|
||||||
@ -178,6 +189,9 @@ 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
|
||||||
|
@ -13,7 +13,7 @@ import Data.Vector (Vector)
|
|||||||
import qualified Data.Vector as Vector
|
import qualified Data.Vector as Vector
|
||||||
import qualified Language.Elna.Architecture.RiscV as RiscV
|
import qualified Language.Elna.Architecture.RiscV as RiscV
|
||||||
import Language.Elna.Backend.Allocator (MachineConfiguration(..), Store(..))
|
import Language.Elna.Backend.Allocator (MachineConfiguration(..), Store(..))
|
||||||
import Language.Elna.Backend.Intermediate (Operand(..), Quadruple(..))
|
import Language.Elna.Backend.Intermediate (Label(..), Operand(..), Quadruple(..))
|
||||||
import Language.Elna.Location (Identifier(..))
|
import Language.Elna.Location (Identifier(..))
|
||||||
import Data.Bits (Bits(..))
|
import Data.Bits (Bits(..))
|
||||||
import Data.Foldable (Foldable(..), foldlM)
|
import Data.Foldable (Foldable(..), foldlM)
|
||||||
@ -45,6 +45,10 @@ riscVConfiguration = MachineConfiguration
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- | Reserved register used for calculations to save an immediate temporary.
|
||||||
|
immediateRegister :: RiscV.XRegister
|
||||||
|
immediateRegister = RiscV.A7
|
||||||
|
|
||||||
type RiscVStore = Store RiscV.XRegister
|
type RiscVStore = Store RiscV.XRegister
|
||||||
type RiscVQuadruple = Quadruple RiscVStore
|
type RiscVQuadruple = Quadruple RiscVStore
|
||||||
type RiscVOperand = Operand RiscVStore
|
type RiscVOperand = Operand RiscVStore
|
||||||
@ -243,6 +247,43 @@ quadruple (DivisionQuadruple operand1 operand2 (Store register))
|
|||||||
$ RiscV.BaseInstruction RiscV.Op
|
$ RiscV.BaseInstruction RiscV.Op
|
||||||
$ RiscV.R register RiscV.DIV register operandRegister2
|
$ RiscV.R register RiscV.DIV register operandRegister2
|
||||||
$ RiscV.Funct7 0b0000001
|
$ RiscV.Funct7 0b0000001
|
||||||
|
quadruple (LabelQuadruple (Label label)) = pure $ Vector.singleton $ JumpLabel label mempty
|
||||||
|
quadruple (GoToQuadruple label) = pure $ Vector.singleton $ unconditionalJal label
|
||||||
|
quadruple (EqualQuadruple operand1 operand2 goToLabel)
|
||||||
|
| IntOperand immediateOperand1 <- operand1
|
||||||
|
, IntOperand immediateOperand2 <- operand2 =
|
||||||
|
if immediateOperand1 == immediateOperand2
|
||||||
|
then pure $ Vector.singleton $ unconditionalJal goToLabel
|
||||||
|
else pure Vector.empty
|
||||||
|
| VariableOperand variableOperand1 <- operand1
|
||||||
|
, VariableOperand variableOperand2 <- operand2 = do
|
||||||
|
let Store operandRegister1 = variableOperand1
|
||||||
|
Store operandRegister2 = variableOperand2
|
||||||
|
branchLabel <- createLabel
|
||||||
|
pure $ Vector.singleton
|
||||||
|
$ Instruction
|
||||||
|
$ RiscV.RelocatableInstruction RiscV.Branch
|
||||||
|
$ RiscV.RBranch branchLabel RiscV.BEQ operandRegister1 operandRegister2
|
||||||
|
| VariableOperand variableOperand1 <- operand1
|
||||||
|
, IntOperand immediateOperand2 <- operand2 =
|
||||||
|
compareImmediateRegister variableOperand1 immediateOperand2
|
||||||
|
| IntOperand immediateOperand1 <- operand1
|
||||||
|
, VariableOperand variableOperand2 <- operand2 =
|
||||||
|
compareImmediateRegister variableOperand2 immediateOperand1
|
||||||
|
where
|
||||||
|
compareImmediateRegister variableOperand immediateOperand =
|
||||||
|
let statements = lui immediateOperand immediateRegister
|
||||||
|
Store operandRegister = variableOperand
|
||||||
|
Label goToLabel' = goToLabel
|
||||||
|
in pure $ Vector.snoc statements
|
||||||
|
$ Instruction
|
||||||
|
$ RiscV.RelocatableInstruction RiscV.Branch
|
||||||
|
$ RiscV.RBranch goToLabel' RiscV.BEQ operandRegister immediateRegister
|
||||||
|
|
||||||
|
unconditionalJal :: Label -> Statement
|
||||||
|
unconditionalJal (Label goToLabel) = Instruction
|
||||||
|
$ RiscV.RelocatableInstruction RiscV.Jal
|
||||||
|
$ RiscV.RJal RiscV.Zero goToLabel
|
||||||
|
|
||||||
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
|
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
|
||||||
loadImmediateOrRegister (IntOperand intValue) targetRegister =
|
loadImmediateOrRegister (IntOperand intValue) targetRegister =
|
||||||
|
@ -236,8 +236,8 @@ riscv32Elf code objectHandle = text
|
|||||||
, st_info = stInfo STB_GLOBAL STT_FUNC
|
, st_info = stInfo STB_GLOBAL STT_FUNC
|
||||||
}
|
}
|
||||||
result =
|
result =
|
||||||
( encoded <> encoded'
|
( encoded'
|
||||||
, relocations <> relocations'
|
, relocations'
|
||||||
, ElfHeaderResult (names <> Text.encodeUtf8 labelName <> "\0") (Vector.snoc symbols newEntry)
|
, ElfHeaderResult (names <> Text.encodeUtf8 labelName <> "\0") (Vector.snoc symbols newEntry)
|
||||||
, definitions'
|
, definitions'
|
||||||
)
|
)
|
||||||
@ -260,6 +260,9 @@ riscv32Elf code objectHandle = text
|
|||||||
| RiscV.RBranch symbolName _ _ _ <- instructionType
|
| RiscV.RBranch symbolName _ _ _ <- instructionType
|
||||||
-> Just -- R_RISCV_BRANCH
|
-> Just -- R_RISCV_BRANCH
|
||||||
$ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 16
|
$ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 16
|
||||||
|
| RiscV.RJal _ symbolName <- instructionType
|
||||||
|
-> Just -- R_RISCV_JAL
|
||||||
|
$ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 17
|
||||||
RiscV.CallInstruction symbolName
|
RiscV.CallInstruction symbolName
|
||||||
-> Just -- R_RISCV_CALL_PLT
|
-> Just -- R_RISCV_CALL_PLT
|
||||||
$ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 19
|
$ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 19
|
||||||
|
1
tests/expectations/printi_if.txt
Normal file
1
tests/expectations/printi_if.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
3
|
4
tests/vm/printi_if.elna
Normal file
4
tests/vm/printi_if.elna
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
proc main() {
|
||||||
|
if (1 = 1)
|
||||||
|
printi(3);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user