From 0850f0a8d66af028e32a79063cdad328b70db909 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 11 Oct 2024 16:14:01 +0200 Subject: [PATCH] Implement if statements with equality --- TODO | 1 - lib/Language/Elna/Architecture/RiscV.hs | 2 + lib/Language/Elna/Backend/Allocator.hs | 4 ++ lib/Language/Elna/Backend/Intermediate.hs | 20 +++++-- lib/Language/Elna/Frontend/AST.hs | 33 ++++++----- lib/Language/Elna/Frontend/NameAnalysis.hs | 52 ++++++++--------- lib/Language/Elna/Frontend/Parser.hs | 28 ++++----- lib/Language/Elna/Glue.hs | 66 +++++++++++++--------- lib/Language/Elna/RiscV/CodeGenerator.hs | 43 +++++++++++++- lib/Language/Elna/RiscV/ElfWriter.hs | 7 ++- tests/expectations/printi_if.txt | 1 + tests/vm/printi_if.elna | 4 ++ 12 files changed, 168 insertions(+), 93 deletions(-) create mode 100644 tests/expectations/printi_if.txt create mode 100644 tests/vm/printi_if.elna diff --git a/TODO b/TODO index 2f138f8..40d6de1 100644 --- a/TODO +++ b/TODO @@ -14,7 +14,6 @@ - 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. - # Name analysis - Format error messages. diff --git a/lib/Language/Elna/Architecture/RiscV.hs b/lib/Language/Elna/Architecture/RiscV.hs index 03895a3..6619160 100644 --- a/lib/Language/Elna/Architecture/RiscV.hs +++ b/lib/Language/Elna/Architecture/RiscV.hs @@ -146,6 +146,7 @@ data RelocationType | RLower12S Text Funct3 XRegister XRegister | RHigher20 XRegister Text -- Type U. | RBranch Text Funct3 XRegister XRegister -- Type B. + | RJal XRegister Text -- Type J. deriving Eq 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 (RHigher20 rd _) = type' $ U rd 0 relocationType (RBranch _ funct3' rs1 rs2) = type' $ B 0 funct3' rs1 rs2 +relocationType (RJal rd _) = type' $ J rd 0 instruction :: Instruction -> ByteString.Builder.Builder instruction = \case diff --git a/lib/Language/Elna/Backend/Allocator.hs b/lib/Language/Elna/Backend/Allocator.hs index 701beb8..bdbccab 100644 --- a/lib/Language/Elna/Backend/Allocator.hs +++ b/lib/Language/Elna/Backend/Allocator.hs @@ -50,6 +50,10 @@ allocate MachineConfiguration{..} = fmap function = DivisionQuadruple (operand operand1) (operand operand2) $ Store $ 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 (IntOperand x) = IntOperand x operand (VariableOperand (TempVariable index)) diff --git a/lib/Language/Elna/Backend/Intermediate.hs b/lib/Language/Elna/Backend/Intermediate.hs index 380fba7..6d3a1af 100644 --- a/lib/Language/Elna/Backend/Intermediate.hs +++ b/lib/Language/Elna/Backend/Intermediate.hs @@ -1,13 +1,21 @@ module Language.Elna.Backend.Intermediate ( Operand(..) , Quadruple(..) - {- , Label(..) -} + , Label(..) , Variable(..) ) where import Data.Int (Int32) import Data.Word (Word32) 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 deriving Eq @@ -32,15 +40,15 @@ data Quadruple v | NegationQuadruple (Operand v) v | ProductQuadruple (Operand v) (Operand v) v | DivisionQuadruple (Operand v) (Operand v) v - {-| GoToQuadruple Label - | AssignQuadruple Operand Variable + | GoToQuadruple Label + {-| AssignQuadruple Operand Variable | ArrayQuadruple Variable Operand Variable | ArrayAssignQuadruple Operand Operand Variable - | EqualQuadruple Operand Operand Label | NonEqualQuadruple Operand Operand Label | LessQuadruple Operand Operand Label | GreaterQuadruple Operand Operand Label | LessOrEqualQuadruple Operand Operand Label - | GreaterOrEqualQuadruple Operand Operand Label - | LabelQuadruple Label -} + | GreaterOrEqualQuadruple Operand Operand Label -} + | EqualQuadruple (Operand v) (Operand v) Label + | LabelQuadruple Label deriving (Eq, Show) diff --git a/lib/Language/Elna/Frontend/AST.hs b/lib/Language/Elna/Frontend/AST.hs index b9ed539..68ac581 100644 --- a/lib/Language/Elna/Frontend/AST.hs +++ b/lib/Language/Elna/Frontend/AST.hs @@ -6,8 +6,8 @@ module Language.Elna.Frontend.AST , Statement(..) , TypeExpression(..) , VariableDeclaration(..) - {-, VariableAccess(..) - , Condition(..)-} + --, VariableAccess(..) + , Condition(..) , Expression(..) , Literal(..) ) where @@ -67,8 +67,8 @@ instance Show TypeExpression data Statement = EmptyStatement - {-| AssignmentStatement VariableAccess Expression | IfStatement Condition Statement (Maybe Statement) + {-| AssignmentStatement VariableAccess Expression | WhileStatement Condition Statement -} | CompoundStatement [Statement] | CallStatement Identifier [Expression] @@ -77,13 +77,13 @@ data Statement instance Show Statement where show EmptyStatement = ";" - {-show (AssignmentStatement lhs rhs) = - concat [show lhs, " := ", show rhs, ";"] show (IfStatement condition if' else') = concat [ "if (", show condition, ") " , show if' , maybe "" ((<> " else ") . show) else' ] + {-show (AssignmentStatement lhs rhs) = + concat [show lhs, " := ", show rhs, ";"] show (WhileStatement expression statement) = concat ["while (", show expression, ") ", show statement, ";"]-} show (CompoundStatement statements) = @@ -143,22 +143,21 @@ instance Show VariableAccess show (VariableAccess variableName) = show variableName show (ArrayAccess arrayAccess elementIndex) = concat [show arrayAccess, "[", show elementIndex, "]"] - +-} data Condition = EqualCondition Expression Expression - | NonEqualCondition Expression Expression - | LessCondition Expression Expression - | GreaterCondition Expression Expression - | LessOrEqualCondition Expression Expression - | GreaterOrEqualCondition Expression Expression + -- | NonEqualCondition Expression Expression + -- | LessCondition Expression Expression + -- | GreaterCondition Expression Expression + -- | LessOrEqualCondition Expression Expression + -- | GreaterOrEqualCondition Expression Expression deriving Eq instance Show Condition where show (EqualCondition 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 (GreaterCondition 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 (NonEqualCondition 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 (LessOrEqualCondition lhs rhs) = concat [show lhs, " <= ", show rhs] + -- show (GreaterOrEqualCondition lhs rhs) = concat [show lhs, " >= ", show rhs] diff --git a/lib/Language/Elna/Frontend/NameAnalysis.hs b/lib/Language/Elna/Frontend/NameAnalysis.hs index 18ae6dd..12e51f8 100644 --- a/lib/Language/Elna/Frontend/NameAnalysis.hs +++ b/lib/Language/Elna/Frontend/NameAnalysis.hs @@ -160,17 +160,37 @@ statement globalTable (AST.CallStatement name arguments) >> traverse_ (expression globalTable) arguments statement globalTable (AST.CompoundStatement statements) = traverse_ (statement globalTable) statements -{- statement globalTable (AST.AssignmentStatement lvalue rvalue) - = variableAccess globalTable lvalue - >> expression globalTable rvalue statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement) = condition globalTable ifCondition >> statement globalTable ifStatement >> maybe (pure ()) (statement globalTable) elseStatement -statement globalTable (AST.WhileStatement whileCondition loop) - = condition globalTable whileCondition - >> statement globalTable loop +-- statement globalTable (AST.AssignmentStatement lvalue rvalue) +-- = variableAccess globalTable lvalue +-- >> 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 globalTable (AST.ArrayAccess arrayExpression indexExpression) = variableAccess globalTable arrayExpression @@ -178,26 +198,6 @@ variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) variableAccess globalTable (AST.VariableAccess 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 table = maybe (identifierAlreadyDefinedError identifier) pure diff --git a/lib/Language/Elna/Frontend/Parser.hs b/lib/Language/Elna/Frontend/Parser.hs index 9d6bb60..9dd3206 100644 --- a/lib/Language/Elna/Frontend/Parser.hs +++ b/lib/Language/Elna/Frontend/Parser.hs @@ -16,8 +16,8 @@ import Language.Elna.Frontend.AST , Statement(..) , TypeExpression(..) , VariableDeclaration(..) - {-, VariableAccess(..) - , Condition(..)-} + --, VariableAccess(..) + , Condition(..) , Expression(..) , Literal(..) ) @@ -97,7 +97,7 @@ variableAccessP = do identifier <- identifierP indices <- many $ bracketsP expressionP pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices - +-} conditionP :: Parser Condition conditionP = do lhs <- expressionP @@ -105,14 +105,14 @@ conditionP = do conditionCons lhs <$> expressionP where comparisonOperator = - [ symbol "<" >> pure LessCondition - , symbol "<=" >> pure LessOrEqualCondition - , symbol ">" >> pure GreaterCondition - , symbol ">=" >> pure GreaterOrEqualCondition - , symbol "=" >> pure EqualCondition - , symbol "#" >> pure NonEqualCondition + --, symbol "<" >> pure LessCondition + --, symbol "<=" >> pure LessOrEqualCondition + --, symbol ">" >> pure GreaterCondition + --, symbol ">=" >> pure GreaterOrEqualCondition + [ symbol "=" >> pure EqualCondition + --, symbol "#" >> pure NonEqualCondition ] --} + symbol :: Text -> Parser Text symbol = Lexer.symbol space @@ -182,22 +182,22 @@ procedureDeclarationP = procedureCons statementP :: Parser Statement statementP = EmptyStatement <$ semicolonP + <|> ifElseP {-<|> CompoundStatement <$> blockP (many statementP) <|> try assignmentP - <|> try ifElseP <|> try whileP -} - <|> try callP + <|> callP "statement" where callP = CallStatement <$> identifierP <*> parensP (sepBy expressionP commaP) <* semicolonP - {-ifElseP = IfStatement + ifElseP = IfStatement <$> (symbol "if" *> parensP conditionP) <*> statementP <*> optional (symbol "else" *> statementP) - whileP = WhileStatement + {-whileP = WhileStatement <$> (symbol "while" *> parensP conditionP) <*> statementP assignmentP = AssignmentStatement diff --git a/lib/Language/Elna/Glue.hs b/lib/Language/Elna/Glue.hs index 9fc8a1c..6b883d7 100644 --- a/lib/Language/Elna/Glue.hs +++ b/lib/Language/Elna/Glue.hs @@ -9,15 +9,24 @@ import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap import Data.Maybe (catMaybes) 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 Data.Word (Word32) 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 GHC.Records (HasField(..)) -newtype Paste = Paste +data Paste = Paste { temporaryCounter :: Word32 + , labelCounter :: Word32 } newtype Glue a = Glue @@ -39,7 +48,7 @@ instance Monad Glue glue :: SymbolTable -> AST.Program -> HashMap AST.Identifier (Vector (Quadruple Variable)) glue globalTable = fst - . flip runState Paste{ temporaryCounter = 0 } + . flip runState Paste{ temporaryCounter = 0, labelCounter = 0 } . runGlue . program globalTable @@ -77,6 +86,18 @@ statement localTable (AST.CallStatement (AST.Identifier callName) arguments) = d $ Vector.length argumentStatements statement localTable (AST.CompoundStatement 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 (rhsOperand, rhsStatements) <- expression localTable assignee let variableType' = variableType variableAccess' localTable @@ -90,18 +111,6 @@ statement localTable (AST.CompoundStatement statements) = Vector.snoc accumulatedStatements $ AssignQuadruple rhsOperand $ 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 (conditionStatements, jumpConstructor) <- condition localTable whileCondition startLabel <- createLabel @@ -124,21 +133,23 @@ createTemporary = do { temporaryCounter = getField @"temporaryCounter" generator + 1 } -{- -import Language.Elna.Types (Type(..)) -import qualified Language.Elna.SymbolTable as SymbolTable - -newtype Label = Label Text - deriving Eq - -instance Show Label +createLabel :: Glue Label +createLabel = do + currentCounter <- Glue $ gets $ getField @"labelCounter" + Glue $ modify' modifier + pure $ Label + $ Text.Lazy.toStrict + $ Text.Builder.toLazyText + $ "L" <> Text.Builder.decimal currentCounter where - show (Label label) = '.' : Text.unpack label + modifier generator = generator + { labelCounter = getField @"labelCounter" generator + 1 + } condition :: SymbolTable -> AST.Condition - -> Glue (Vector Quadruple, Label -> Quadruple) + -> Glue (Vector (Quadruple Variable), Label -> Quadruple Variable) condition localTable (AST.EqualCondition lhs rhs) = do (lhsOperand, lhsStatements) <- expression localTable lhs (rhsOperand, rhsStatements) <- expression localTable rhs @@ -146,7 +157,7 @@ condition localTable (AST.EqualCondition lhs rhs) = do ( lhsStatements <> rhsStatements , EqualQuadruple lhsOperand rhsOperand ) -condition localTable (AST.NonEqualCondition lhs rhs) = do +{- condition localTable (AST.NonEqualCondition lhs rhs) = do (lhsOperand, lhsStatements) <- expression localTable lhs (rhsOperand, rhsStatements) <- expression localTable rhs pure @@ -178,6 +189,9 @@ condition localTable (AST.GreaterOrEqualCondition lhs rhs) = do ( lhsStatements <> rhsStatements , GreaterOrEqualQuadruple lhsOperand rhsOperand ) +-}{- +import Language.Elna.Types (Type(..)) +import qualified Language.Elna.SymbolTable as SymbolTable variableAccess :: SymbolTable diff --git a/lib/Language/Elna/RiscV/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs index e3fac72..659e0e6 100644 --- a/lib/Language/Elna/RiscV/CodeGenerator.hs +++ b/lib/Language/Elna/RiscV/CodeGenerator.hs @@ -13,7 +13,7 @@ import Data.Vector (Vector) import qualified Data.Vector as Vector import qualified Language.Elna.Architecture.RiscV as RiscV 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 Data.Bits (Bits(..)) 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 RiscVQuadruple = Quadruple RiscVStore type RiscVOperand = Operand RiscVStore @@ -243,6 +247,43 @@ quadruple (DivisionQuadruple operand1 operand2 (Store register)) $ RiscV.BaseInstruction RiscV.Op $ RiscV.R register RiscV.DIV register operandRegister2 $ 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 (IntOperand intValue) targetRegister = diff --git a/lib/Language/Elna/RiscV/ElfWriter.hs b/lib/Language/Elna/RiscV/ElfWriter.hs index d3b0e94..52a92ea 100644 --- a/lib/Language/Elna/RiscV/ElfWriter.hs +++ b/lib/Language/Elna/RiscV/ElfWriter.hs @@ -236,8 +236,8 @@ riscv32Elf code objectHandle = text , st_info = stInfo STB_GLOBAL STT_FUNC } result = - ( encoded <> encoded' - , relocations <> relocations' + ( encoded' + , relocations' , ElfHeaderResult (names <> Text.encodeUtf8 labelName <> "\0") (Vector.snoc symbols newEntry) , definitions' ) @@ -260,6 +260,9 @@ riscv32Elf code objectHandle = text | RiscV.RBranch symbolName _ _ _ <- instructionType -> Just -- R_RISCV_BRANCH $ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 16 + | RiscV.RJal _ symbolName <- instructionType + -> Just -- R_RISCV_JAL + $ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 17 RiscV.CallInstruction symbolName -> Just -- R_RISCV_CALL_PLT $ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 19 diff --git a/tests/expectations/printi_if.txt b/tests/expectations/printi_if.txt new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/tests/expectations/printi_if.txt @@ -0,0 +1 @@ +3 diff --git a/tests/vm/printi_if.elna b/tests/vm/printi_if.elna new file mode 100644 index 0000000..a3d859b --- /dev/null +++ b/tests/vm/printi_if.elna @@ -0,0 +1,4 @@ +proc main() { + if (1 = 1) + printi(3); +}