Implement comparison operators

This commit is contained in:
Eugen Wissner 2024-10-13 12:59:47 +02:00
parent 0850f0a8d6
commit 582040e5d3
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
19 changed files with 261 additions and 43 deletions

View File

@ -54,6 +54,16 @@ allocate MachineConfiguration{..} = fmap function
quadruple (GoToQuadruple label) = GoToQuadruple label quadruple (GoToQuadruple label) = GoToQuadruple label
quadruple (EqualQuadruple operand1 operand2 goToLabel) = quadruple (EqualQuadruple operand1 operand2 goToLabel) =
EqualQuadruple (operand operand1) (operand operand2) goToLabel EqualQuadruple (operand operand1) (operand operand2) goToLabel
quadruple (NonEqualQuadruple operand1 operand2 goToLabel) =
NonEqualQuadruple (operand operand1) (operand operand2) goToLabel
quadruple (LessQuadruple operand1 operand2 goToLabel) =
LessQuadruple (operand operand1) (operand operand2) goToLabel
quadruple (GreaterQuadruple operand1 operand2 goToLabel) =
GreaterQuadruple (operand operand1) (operand operand2) goToLabel
quadruple (LessOrEqualQuadruple operand1 operand2 goToLabel) =
LessOrEqualQuadruple (operand operand1) (operand operand2) goToLabel
quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel) =
GreaterOrEqualQuadruple (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))

View File

@ -43,12 +43,12 @@ data Quadruple 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 -}
| NonEqualQuadruple Operand Operand Label | LessOrEqualQuadruple (Operand v) (Operand v) Label
| LessQuadruple Operand Operand Label | GreaterOrEqualQuadruple (Operand v) (Operand v) Label
| GreaterQuadruple Operand Operand Label | GreaterQuadruple (Operand v) (Operand v) Label
| LessOrEqualQuadruple Operand Operand Label | LessQuadruple (Operand v) (Operand v) Label
| GreaterOrEqualQuadruple Operand Operand Label -} | NonEqualQuadruple (Operand v) (Operand v) Label
| EqualQuadruple (Operand v) (Operand v) Label | EqualQuadruple (Operand v) (Operand v) Label
| LabelQuadruple Label | LabelQuadruple Label
deriving (Eq, Show) deriving (Eq, Show)

View File

@ -146,18 +146,18 @@ instance Show VariableAccess
-} -}
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]

View File

@ -175,21 +175,21 @@ condition :: SymbolTable -> AST.Condition -> NameAnalysis ()
condition globalTable (AST.EqualCondition lhs rhs) condition globalTable (AST.EqualCondition lhs rhs)
= expression globalTable lhs = expression globalTable lhs
>> expression globalTable rhs >> expression globalTable rhs
--condition globalTable (AST.NonEqualCondition lhs rhs) condition globalTable (AST.NonEqualCondition lhs rhs)
-- = expression globalTable lhs = expression globalTable lhs
-- >> expression globalTable rhs >> expression globalTable rhs
--condition globalTable (AST.LessCondition lhs rhs) condition globalTable (AST.LessCondition lhs rhs)
-- = expression globalTable lhs = expression globalTable lhs
-- >> expression globalTable rhs >> expression globalTable rhs
--condition globalTable (AST.GreaterCondition lhs rhs) condition globalTable (AST.GreaterCondition lhs rhs)
-- = expression globalTable lhs = expression globalTable lhs
-- >> expression globalTable rhs >> expression globalTable rhs
--condition globalTable (AST.LessOrEqualCondition lhs rhs) condition globalTable (AST.LessOrEqualCondition lhs rhs)
-- = expression globalTable lhs = expression globalTable lhs
-- >> expression globalTable rhs >> expression globalTable 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 (AST.ArrayAccess arrayExpression indexExpression)

View File

@ -105,12 +105,12 @@ conditionP = do
conditionCons lhs <$> expressionP conditionCons lhs <$> expressionP
where where
comparisonOperator = comparisonOperator =
--, symbol "<" >> pure LessCondition [ symbol "<=" >> pure LessOrEqualCondition
--, symbol "<=" >> pure LessOrEqualCondition , symbol "<" >> pure LessCondition
--, symbol ">" >> pure GreaterCondition , symbol ">=" >> pure GreaterOrEqualCondition
--, symbol ">=" >> pure GreaterOrEqualCondition , symbol ">" >> pure GreaterCondition
[ symbol "=" >> pure EqualCondition , symbol "=" >> pure EqualCondition
--, symbol "#" >> pure NonEqualCondition , symbol "#" >> pure NonEqualCondition
] ]
symbol :: Text -> Parser Text symbol :: Text -> Parser Text
@ -183,8 +183,8 @@ statementP :: Parser Statement
statementP 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"

View File

@ -157,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
@ -189,7 +189,7 @@ condition localTable (AST.GreaterOrEqualCondition lhs rhs) = do
( lhsStatements <> rhsStatements ( lhsStatements <> rhsStatements
, GreaterOrEqualQuadruple lhsOperand rhsOperand , GreaterOrEqualQuadruple lhsOperand rhsOperand
) )
-}{- {-
import Language.Elna.Types (Type(..)) import Language.Elna.Types (Type(..))
import qualified Language.Elna.SymbolTable as SymbolTable import qualified Language.Elna.SymbolTable as SymbolTable

View File

@ -259,11 +259,11 @@ quadruple (EqualQuadruple operand1 operand2 goToLabel)
, VariableOperand variableOperand2 <- operand2 = do , VariableOperand variableOperand2 <- operand2 = do
let Store operandRegister1 = variableOperand1 let Store operandRegister1 = variableOperand1
Store operandRegister2 = variableOperand2 Store operandRegister2 = variableOperand2
branchLabel <- createLabel Label goToLabel' = goToLabel
pure $ Vector.singleton pure $ Vector.singleton
$ Instruction $ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch $ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch branchLabel RiscV.BEQ operandRegister1 operandRegister2 $ RiscV.RBranch goToLabel' RiscV.BEQ operandRegister1 operandRegister2
| VariableOperand variableOperand1 <- operand1 | VariableOperand variableOperand1 <- operand1
, IntOperand immediateOperand2 <- operand2 = , IntOperand immediateOperand2 <- operand2 =
compareImmediateRegister variableOperand1 immediateOperand2 compareImmediateRegister variableOperand1 immediateOperand2
@ -279,6 +279,168 @@ quadruple (EqualQuadruple operand1 operand2 goToLabel)
$ Instruction $ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch $ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BEQ operandRegister immediateRegister $ RiscV.RBranch goToLabel' RiscV.BEQ operandRegister immediateRegister
quadruple (NonEqualQuadruple 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
Label goToLabel' = goToLabel
pure $ Vector.singleton
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BNE 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.BNE operandRegister immediateRegister
quadruple (LessQuadruple 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
Label goToLabel' = goToLabel
pure $ Vector.singleton
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BLT operandRegister1 operandRegister2
| VariableOperand variableOperand1 <- operand1
, IntOperand immediateOperand2 <- operand2 =
let statements2 = lui immediateOperand2 immediateRegister
Store operandRegister1 = variableOperand1
Label goToLabel' = goToLabel
in pure $ Vector.snoc statements2
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BLT operandRegister1 immediateRegister
| IntOperand immediateOperand1 <- operand1
, VariableOperand variableOperand2 <- operand2 =
let statements1 = lui immediateOperand1 immediateRegister
Store operandRegister2 = variableOperand2
Label goToLabel' = goToLabel
in pure $ Vector.snoc statements1
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BLT immediateRegister operandRegister2
quadruple (GreaterQuadruple 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
Label goToLabel' = goToLabel
pure $ Vector.singleton
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BLT operandRegister2 operandRegister1
| VariableOperand variableOperand1 <- operand1
, IntOperand immediateOperand2 <- operand2 =
let statements2 = lui immediateOperand2 immediateRegister
Store operandRegister1 = variableOperand1
Label goToLabel' = goToLabel
in pure $ Vector.snoc statements2
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BLT immediateRegister operandRegister1
| IntOperand immediateOperand1 <- operand1
, VariableOperand variableOperand2 <- operand2 =
let statements1 = lui immediateOperand1 immediateRegister
Store operandRegister2 = variableOperand2
Label goToLabel' = goToLabel
in pure $ Vector.snoc statements1
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BLT operandRegister2 immediateRegister
quadruple (LessOrEqualQuadruple 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
Label goToLabel' = goToLabel
pure $ Vector.singleton
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BGE operandRegister2 operandRegister1
| VariableOperand variableOperand1 <- operand1
, IntOperand immediateOperand2 <- operand2 =
let statements2 = lui immediateOperand2 immediateRegister
Store operandRegister1 = variableOperand1
Label goToLabel' = goToLabel
in pure $ Vector.snoc statements2
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BGE immediateRegister operandRegister1
| IntOperand immediateOperand1 <- operand1
, VariableOperand variableOperand2 <- operand2 =
let statements1 = lui immediateOperand1 immediateRegister
Store operandRegister2 = variableOperand2
Label goToLabel' = goToLabel
in pure $ Vector.snoc statements1
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BGE operandRegister2 immediateRegister
quadruple (GreaterOrEqualQuadruple 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
Label goToLabel' = goToLabel
pure $ Vector.singleton
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BGE operandRegister1 operandRegister2
| VariableOperand variableOperand1 <- operand1
, IntOperand immediateOperand2 <- operand2 =
let statements2 = lui immediateOperand2 immediateRegister
Store operandRegister1 = variableOperand1
Label goToLabel' = goToLabel
in pure $ Vector.snoc statements2
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BGE operandRegister1 immediateRegister
| IntOperand immediateOperand1 <- operand1
, VariableOperand variableOperand2 <- operand2 =
let statements1 = lui immediateOperand1 immediateRegister
Store operandRegister2 = variableOperand2
Label goToLabel' = goToLabel
in pure $ Vector.snoc statements1
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BGE immediateRegister operandRegister2
unconditionalJal :: Label -> Statement unconditionalJal :: Label -> Statement
unconditionalJal (Label goToLabel) = Instruction unconditionalJal (Label goToLabel) = Instruction

View File

@ -0,0 +1 @@
5

View File

@ -0,0 +1 @@
5

View File

@ -0,0 +1 @@
3

View File

@ -0,0 +1 @@
3

View File

@ -0,0 +1 @@
3

View File

@ -0,0 +1,2 @@
3
7

View File

@ -0,0 +1,6 @@
proc main() {
if ((1 + 1) > 2)
printi(3);
else
printi(5);
}

View File

@ -0,0 +1,6 @@
proc main() {
if ((1 + 1) >= (2 + 3))
printi(3);
else
printi(5);
}

View File

@ -0,0 +1,6 @@
proc main() {
if (1 < 2)
printi(3);
else
printi(5);
}

View File

@ -0,0 +1,6 @@
proc main() {
if (2 <= (2 + 1))
printi(3);
else
printi(5);
}

View File

@ -0,0 +1,6 @@
proc main() {
if (1 # 2)
printi(3);
else
printi(5);
}

View File

@ -0,0 +1,9 @@
proc main() {
if (1 # 2) {
printi(3);
printi(7);
} else {
printi(5);
printi(9);
}
}