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
TODO
lib/Language/Elna

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.SymbolTable (SymbolTable, Info(..))
import qualified Language.Elna.SymbolTable as SymbolTable
import Data.Maybe (fromMaybe)
data Operand
= VariableOperand Variable
@ -34,7 +35,7 @@ data Quadruple
| GoToQuadruple Label
| AssignQuadruple Operand Variable
| ArrayQuadruple Variable Operand Variable
| ArrayAssignQuadruple Operand Word32 Variable
| ArrayAssignQuadruple Operand Operand Variable
| AddQuadruple Operand Operand Variable
| SubtractionQuadruple Operand Operand Variable
| ProductQuadruple Operand Operand Variable
@ -66,8 +67,58 @@ intermediate globalTable (AST.Program declarations) =
statement :: SymbolTable -> AST.Statement -> Vector Quadruple
statement _ AST.EmptyStatement = mempty
statement globalTable (AST.CompoundStatement statements) =
foldMap (statement globalTable) statements
statement localTable (AST.AssignmentStatement variableAccess' assignee) =
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
:: SymbolTable