Generate the code for IfStatement
This commit is contained in:
parent
d405072dbf
commit
6a54b66421
5
TODO
5
TODO
@ -1 +1,4 @@
|
|||||||
# Register allocation
|
# Intermediate code generation
|
||||||
|
|
||||||
|
Execute the generation in a state monad and generate unique labels and
|
||||||
|
temporary variable names.
|
||||||
|
@ -17,6 +17,7 @@ import qualified Language.Elna.AST as AST
|
|||||||
import Language.Elna.Types (Type(..))
|
import Language.Elna.Types (Type(..))
|
||||||
import Language.Elna.SymbolTable (SymbolTable, Info(..))
|
import Language.Elna.SymbolTable (SymbolTable, Info(..))
|
||||||
import qualified Language.Elna.SymbolTable as SymbolTable
|
import qualified Language.Elna.SymbolTable as SymbolTable
|
||||||
|
import Data.Maybe (fromMaybe)
|
||||||
|
|
||||||
data Operand
|
data Operand
|
||||||
= VariableOperand Variable
|
= VariableOperand Variable
|
||||||
@ -34,7 +35,7 @@ data Quadruple
|
|||||||
| GoToQuadruple Label
|
| GoToQuadruple Label
|
||||||
| AssignQuadruple Operand Variable
|
| AssignQuadruple Operand Variable
|
||||||
| ArrayQuadruple Variable Operand Variable
|
| ArrayQuadruple Variable Operand Variable
|
||||||
| ArrayAssignQuadruple Operand Word32 Variable
|
| ArrayAssignQuadruple Operand Operand Variable
|
||||||
| AddQuadruple Operand Operand Variable
|
| AddQuadruple Operand Operand Variable
|
||||||
| SubtractionQuadruple Operand Operand Variable
|
| SubtractionQuadruple Operand Operand Variable
|
||||||
| ProductQuadruple Operand Operand Variable
|
| ProductQuadruple Operand Operand Variable
|
||||||
@ -66,8 +67,58 @@ intermediate globalTable (AST.Program declarations) =
|
|||||||
|
|
||||||
statement :: SymbolTable -> AST.Statement -> Vector Quadruple
|
statement :: SymbolTable -> AST.Statement -> Vector Quadruple
|
||||||
statement _ AST.EmptyStatement = mempty
|
statement _ AST.EmptyStatement = mempty
|
||||||
statement globalTable (AST.CompoundStatement statements) =
|
statement localTable (AST.AssignmentStatement variableAccess' assignee) =
|
||||||
foldMap (statement globalTable) statements
|
let (rhsOperand, rhsStatements) = expression localTable assignee
|
||||||
|
variableType' = variableType variableAccess' localTable
|
||||||
|
lhsStatements = case variableAccess localTable variableAccess' Nothing variableType' mempty of
|
||||||
|
(AST.Identifier identifier, Just accumulatedIndex, accumulatedStatements) ->
|
||||||
|
Vector.snoc accumulatedStatements
|
||||||
|
$ ArrayAssignQuadruple rhsOperand accumulatedIndex
|
||||||
|
$ Variable identifier
|
||||||
|
(AST.Identifier identifier, Nothing, accumulatedStatements) ->
|
||||||
|
Vector.snoc accumulatedStatements
|
||||||
|
$ AssignQuadruple rhsOperand
|
||||||
|
$ Variable identifier
|
||||||
|
in rhsStatements <> lhsStatements
|
||||||
|
statement localTable (AST.IfStatement ifCondition ifStatement elseStatement) =
|
||||||
|
let (conditionStatements, jumpConstructor) = condition localTable ifCondition
|
||||||
|
ifStatements = statement localTable ifStatement
|
||||||
|
ifLabel = Label "L1"
|
||||||
|
endLabel = Label "L2"
|
||||||
|
in conditionStatements <> case statement localTable <$> elseStatement 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.CompoundStatement statements) =
|
||||||
|
foldMap (statement localTable) statements
|
||||||
|
|
||||||
|
condition :: SymbolTable -> AST.Condition -> (Vector Quadruple, Label -> Quadruple)
|
||||||
|
condition localTable (AST.EqualCondition lhs rhs) =
|
||||||
|
let (lhsOperand, lhsStatements) = expression localTable lhs
|
||||||
|
(rhsOperand, rhsStatements) = expression localTable rhs
|
||||||
|
in (lhsStatements <> rhsStatements, EqualQuadruple lhsOperand rhsOperand)
|
||||||
|
condition localTable (AST.NonEqualCondition lhs rhs) =
|
||||||
|
let (lhsOperand, lhsStatements) = expression localTable lhs
|
||||||
|
(rhsOperand, rhsStatements) = expression localTable rhs
|
||||||
|
in (lhsStatements <> rhsStatements, NonEqualQuadruple lhsOperand rhsOperand)
|
||||||
|
condition localTable (AST.LessCondition lhs rhs) =
|
||||||
|
let (lhsOperand, lhsStatements) = expression localTable lhs
|
||||||
|
(rhsOperand, rhsStatements) = expression localTable rhs
|
||||||
|
in (lhsStatements <> rhsStatements, LessQuadruple lhsOperand rhsOperand)
|
||||||
|
condition localTable (AST.GreaterCondition lhs rhs) =
|
||||||
|
let (lhsOperand, lhsStatements) = expression localTable lhs
|
||||||
|
(rhsOperand, rhsStatements) = expression localTable rhs
|
||||||
|
in (lhsStatements <> rhsStatements, GreaterQuadruple lhsOperand rhsOperand)
|
||||||
|
condition localTable (AST.LessOrEqualCondition lhs rhs) =
|
||||||
|
let (lhsOperand, lhsStatements) = expression localTable lhs
|
||||||
|
(rhsOperand, rhsStatements) = expression localTable rhs
|
||||||
|
in (lhsStatements <> rhsStatements, LessOrEqualQuadruple lhsOperand rhsOperand)
|
||||||
|
condition localTable (AST.GreaterOrEqualCondition lhs rhs) =
|
||||||
|
let (lhsOperand, lhsStatements) = expression localTable lhs
|
||||||
|
(rhsOperand, rhsStatements) = expression localTable rhs
|
||||||
|
in (lhsStatements <> rhsStatements, GreaterOrEqualQuadruple lhsOperand rhsOperand)
|
||||||
|
|
||||||
variableAccess
|
variableAccess
|
||||||
:: SymbolTable
|
:: SymbolTable
|
||||||
|
Loading…
Reference in New Issue
Block a user