Generate the code for IfStatement

This commit is contained in:
Eugen Wissner 2024-08-17 14:16:16 +02:00
parent d405072dbf
commit 6a54b66421
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
2 changed files with 58 additions and 4 deletions

5
TODO
View File

@ -1 +1,4 @@
# Register allocation # Intermediate code generation
Execute the generation in a state monad and generate unique labels and
temporary variable names.

View File

@ -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