Add printc and exit builtin functions
This commit is contained in:
		
							
								
								
									
										9
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								TODO
									
									
									
									
									
								
							@@ -15,16 +15,15 @@
 | 
			
		||||
- Format error messages.
 | 
			
		||||
- Return non-zero error code on errors.
 | 
			
		||||
 | 
			
		||||
# Built-in
 | 
			
		||||
 | 
			
		||||
- Implement printc (with int argument).
 | 
			
		||||
- Implement exit() as standalone function.
 | 
			
		||||
 | 
			
		||||
# Register allocation
 | 
			
		||||
 | 
			
		||||
- Temporary variables always use the same register, t0. Allocate registers for
 | 
			
		||||
  temporaries.
 | 
			
		||||
 | 
			
		||||
# Prarsing and abstract syntax tree
 | 
			
		||||
 | 
			
		||||
- Parse signed hexadecimal numbers.
 | 
			
		||||
 | 
			
		||||
# Other
 | 
			
		||||
 | 
			
		||||
- Type analysis.
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,8 @@ allocate MachineConfiguration{..} = fmap function
 | 
			
		||||
        SubtractionQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
 | 
			
		||||
    quadruple (NegationQuadruple operand1 _) =
 | 
			
		||||
        NegationQuadruple (operand operand1) (Store temporaryRegister)
 | 
			
		||||
    quadruple (ProductQuadruple operand1 operand2 _) =
 | 
			
		||||
        ProductQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
 | 
			
		||||
    operand :: Operand Variable -> Operand (Store r)
 | 
			
		||||
    operand (IntOperand x) = IntOperand x
 | 
			
		||||
    operand (VariableOperand _) = VariableOperand (Store temporaryRegister)
 | 
			
		||||
 
 | 
			
		||||
@@ -30,11 +30,11 @@ data Quadruple v
 | 
			
		||||
    | AddQuadruple (Operand v) (Operand v) v
 | 
			
		||||
    | SubtractionQuadruple (Operand v) (Operand v) v
 | 
			
		||||
    | NegationQuadruple (Operand v) v
 | 
			
		||||
    | ProductQuadruple (Operand v) (Operand v) v
 | 
			
		||||
    {-| GoToQuadruple Label
 | 
			
		||||
    | AssignQuadruple Operand Variable
 | 
			
		||||
    | ArrayQuadruple Variable Operand Variable
 | 
			
		||||
    | ArrayAssignQuadruple Operand Operand Variable
 | 
			
		||||
    | ProductQuadruple Operand Operand Variable
 | 
			
		||||
    | DivisionQuadruple Operand Operand Variable
 | 
			
		||||
    | EqualQuadruple Operand Operand Label
 | 
			
		||||
    | NonEqualQuadruple Operand Operand Label
 | 
			
		||||
 
 | 
			
		||||
@@ -12,10 +12,12 @@ module Language.Elna.Frontend.AST
 | 
			
		||||
    , Literal(..)
 | 
			
		||||
    ) where
 | 
			
		||||
 | 
			
		||||
import Data.Char (chr)
 | 
			
		||||
import Data.Int (Int32)
 | 
			
		||||
import Data.List (intercalate)
 | 
			
		||||
import Data.Word ({-Word16, -}Word32)
 | 
			
		||||
import Data.Word (Word8, Word32)
 | 
			
		||||
import Language.Elna.Location (Identifier(..), showArrayType)
 | 
			
		||||
import Numeric (showHex)
 | 
			
		||||
 | 
			
		||||
newtype Program = Program [Declaration]
 | 
			
		||||
    deriving Eq
 | 
			
		||||
@@ -67,8 +69,8 @@ data Statement
 | 
			
		||||
    = EmptyStatement
 | 
			
		||||
    {-| AssignmentStatement VariableAccess Expression
 | 
			
		||||
    | IfStatement Condition Statement (Maybe Statement)
 | 
			
		||||
    | WhileStatement Condition Statement
 | 
			
		||||
    | CompoundStatement [Statement]-}
 | 
			
		||||
    | WhileStatement Condition Statement -}
 | 
			
		||||
    | CompoundStatement [Statement]
 | 
			
		||||
    | CallStatement Identifier [Expression]
 | 
			
		||||
    deriving Eq
 | 
			
		||||
 | 
			
		||||
@@ -83,9 +85,9 @@ instance Show Statement
 | 
			
		||||
        , maybe "" ((<> " else ") . show) else'
 | 
			
		||||
        ]
 | 
			
		||||
    show (WhileStatement expression statement) =
 | 
			
		||||
        concat ["while (", show expression, ") ", show statement, ";"]
 | 
			
		||||
        concat ["while (", show expression, ") ", show statement, ";"]-}
 | 
			
		||||
    show (CompoundStatement statements) =
 | 
			
		||||
        concat ["{\n", unlines (show <$> statements), " }"]-}
 | 
			
		||||
        concat ["{\n", unlines (show <$> statements), " }"]
 | 
			
		||||
    show (CallStatement name parameters) = show name <> "("
 | 
			
		||||
        <> intercalate ", " (show <$> parameters) <> ")"
 | 
			
		||||
 | 
			
		||||
@@ -93,22 +95,18 @@ data VariableDeclaration =
 | 
			
		||||
    VariableDeclaration Identifier TypeExpression
 | 
			
		||||
    deriving Eq
 | 
			
		||||
 | 
			
		||||
newtype Literal
 | 
			
		||||
data Literal
 | 
			
		||||
    = IntegerLiteral Int32
 | 
			
		||||
    {- | HexadecimalLiteral Int32
 | 
			
		||||
    | CharacterLiteral Word16
 | 
			
		||||
    | BooleanLiteral Bool -}
 | 
			
		||||
    | HexadecimalLiteral Int32
 | 
			
		||||
    | CharacterLiteral Word8
 | 
			
		||||
    deriving Eq
 | 
			
		||||
 | 
			
		||||
instance Show Literal
 | 
			
		||||
  where
 | 
			
		||||
    show (IntegerLiteral integer) = show integer
 | 
			
		||||
    {- show (HexadecimalLiteral integer) = '0' : 'x' : showHex integer ""
 | 
			
		||||
    show (HexadecimalLiteral integer) = '0' : 'x' : showHex integer ""
 | 
			
		||||
    show (CharacterLiteral character) =
 | 
			
		||||
        '\'' : chr (fromEnum character) : ['\'']
 | 
			
		||||
    show (BooleanLiteral boolean)
 | 
			
		||||
        | boolean = "true"
 | 
			
		||||
        | otherwise = "false" -}
 | 
			
		||||
 | 
			
		||||
instance Show VariableDeclaration
 | 
			
		||||
  where
 | 
			
		||||
@@ -120,8 +118,8 @@ data Expression
 | 
			
		||||
    | SumExpression Expression Expression
 | 
			
		||||
    | SubtractionExpression Expression Expression
 | 
			
		||||
    | NegationExpression Expression
 | 
			
		||||
{-    | VariableExpression VariableAccess
 | 
			
		||||
    | ProductExpression Expression Expression
 | 
			
		||||
{-    | VariableExpression VariableAccess
 | 
			
		||||
    | DivisionExpression Expression Expression -}
 | 
			
		||||
    deriving Eq
 | 
			
		||||
 | 
			
		||||
@@ -131,13 +129,10 @@ instance Show Expression
 | 
			
		||||
    show (SumExpression lhs rhs) = concat [show lhs, " + ", show rhs]
 | 
			
		||||
    show (SubtractionExpression lhs rhs) = concat [show lhs, " - ", show rhs]
 | 
			
		||||
    show (NegationExpression negation) = '-' : show negation
 | 
			
		||||
    {- show (VariableExpression variable) = show variable
 | 
			
		||||
    show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
 | 
			
		||||
    {- show (VariableExpression variable) = show variable
 | 
			
		||||
    show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs] -}
 | 
			
		||||
{-
 | 
			
		||||
import Data.Char (chr)
 | 
			
		||||
import Numeric (showHex)
 | 
			
		||||
 | 
			
		||||
data VariableAccess
 | 
			
		||||
    = VariableAccess Identifier
 | 
			
		||||
    | ArrayAccess VariableAccess Expression
 | 
			
		||||
 
 | 
			
		||||
@@ -144,11 +144,11 @@ expression globalTable (AST.SubtractionExpression lhs rhs)
 | 
			
		||||
    >> expression globalTable rhs
 | 
			
		||||
expression globalTable (AST.NegationExpression negation) =
 | 
			
		||||
    expression globalTable negation
 | 
			
		||||
{- expression globalTable (AST.VariableExpression variableExpression) =
 | 
			
		||||
    variableAccess globalTable variableExpression
 | 
			
		||||
expression globalTable (AST.ProductExpression lhs rhs)
 | 
			
		||||
    = expression globalTable lhs
 | 
			
		||||
    >> expression globalTable rhs
 | 
			
		||||
{- expression globalTable (AST.VariableExpression variableExpression) =
 | 
			
		||||
    variableAccess globalTable variableExpression
 | 
			
		||||
expression globalTable (AST.DivisionExpression lhs rhs)
 | 
			
		||||
    = expression globalTable lhs
 | 
			
		||||
    >> expression globalTable rhs
 | 
			
		||||
@@ -158,6 +158,8 @@ statement _ AST.EmptyStatement = pure ()
 | 
			
		||||
statement globalTable (AST.CallStatement name arguments)
 | 
			
		||||
    = checkSymbol globalTable name
 | 
			
		||||
    >> 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
 | 
			
		||||
@@ -168,8 +170,6 @@ statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement)
 | 
			
		||||
statement globalTable (AST.WhileStatement whileCondition loop)
 | 
			
		||||
    = condition globalTable whileCondition
 | 
			
		||||
    >> statement globalTable loop
 | 
			
		||||
statement globalTable (AST.CompoundStatement statements) =
 | 
			
		||||
    traverse_ (statement globalTable) statements
 | 
			
		||||
 | 
			
		||||
variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
 | 
			
		||||
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
 | 
			
		||||
 
 | 
			
		||||
@@ -34,27 +34,24 @@ import Text.Megaparsec
 | 
			
		||||
import qualified Text.Megaparsec.Char.Lexer as Lexer
 | 
			
		||||
import Text.Megaparsec.Char
 | 
			
		||||
    ( alphaNumChar
 | 
			
		||||
--    , char
 | 
			
		||||
    , char
 | 
			
		||||
    , letterChar
 | 
			
		||||
    , space1
 | 
			
		||||
--    , string
 | 
			
		||||
    , string
 | 
			
		||||
    )
 | 
			
		||||
import Control.Applicative (Alternative(..))
 | 
			
		||||
import Data.Maybe (isJust)
 | 
			
		||||
-- import Data.Functor (($>))
 | 
			
		||||
 | 
			
		||||
type Parser = Parsec Void Text
 | 
			
		||||
 | 
			
		||||
literalP :: Parser Literal
 | 
			
		||||
literalP
 | 
			
		||||
    = {- HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal)
 | 
			
		||||
    <|> -} IntegerLiteral <$> Lexer.signed space integerP
 | 
			
		||||
    {- <|> CharacterLiteral <$> lexeme charP
 | 
			
		||||
    <|> BooleanLiteral <$> (symbol "true" $> True)
 | 
			
		||||
    <|> BooleanLiteral <$> (symbol "false" $> False)
 | 
			
		||||
    = HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal)
 | 
			
		||||
    <|> IntegerLiteral <$> Lexer.signed space integerP
 | 
			
		||||
    <|> CharacterLiteral <$> lexeme charP
 | 
			
		||||
  where
 | 
			
		||||
    charP = fromIntegral . fromEnum
 | 
			
		||||
        <$> between (char '\'') (char '\'') Lexer.charLiteral -}
 | 
			
		||||
        <$> between (char '\'') (char '\'') Lexer.charLiteral
 | 
			
		||||
{-
 | 
			
		||||
typeDefinitionP :: Parser Declaration
 | 
			
		||||
typeDefinitionP = TypeDefinition
 | 
			
		||||
@@ -73,7 +70,7 @@ termP = choice
 | 
			
		||||
operatorTable :: [[Operator Parser Expression]]
 | 
			
		||||
operatorTable =
 | 
			
		||||
    [ unaryOperator
 | 
			
		||||
    -- , factorOperator
 | 
			
		||||
    , factorOperator
 | 
			
		||||
    , termOperator
 | 
			
		||||
    ]
 | 
			
		||||
  where
 | 
			
		||||
@@ -81,10 +78,10 @@ operatorTable =
 | 
			
		||||
        [ prefix "-" NegationExpression
 | 
			
		||||
        , prefix "+" id
 | 
			
		||||
        ]
 | 
			
		||||
    {- factorOperator =
 | 
			
		||||
    factorOperator =
 | 
			
		||||
        [ binary "*" ProductExpression
 | 
			
		||||
        , binary "/" DivisionExpression
 | 
			
		||||
        ] -}
 | 
			
		||||
        -- , binary "/" DivisionExpression
 | 
			
		||||
        ]
 | 
			
		||||
    termOperator =
 | 
			
		||||
        [ binary "+" SumExpression
 | 
			
		||||
        , binary "-" SubtractionExpression
 | 
			
		||||
 
 | 
			
		||||
@@ -40,9 +40,22 @@ scope parent (SymbolTable _ mappings) = SymbolTable (Just parent) mappings
 | 
			
		||||
 | 
			
		||||
builtInSymbolTable :: SymbolTable
 | 
			
		||||
builtInSymbolTable = SymbolTable Nothing $ HashMap.fromList
 | 
			
		||||
    [ ("printi", ProcedureInfo empty Vector.empty)
 | 
			
		||||
    [ ("printi", ProcedureInfo empty (Vector.singleton printiX))
 | 
			
		||||
    , ("printc", ProcedureInfo empty (Vector.singleton printcI))
 | 
			
		||||
    , ("exit", ProcedureInfo empty Vector.empty)
 | 
			
		||||
    , ("int", TypeInfo intType)
 | 
			
		||||
    ]
 | 
			
		||||
  where
 | 
			
		||||
    printiX = ParameterInfo
 | 
			
		||||
        { name = "x"
 | 
			
		||||
        , type' = intType
 | 
			
		||||
        , isReferenceParameter = False
 | 
			
		||||
        }
 | 
			
		||||
    printcI = ParameterInfo
 | 
			
		||||
        { name = "i"
 | 
			
		||||
        , type' = intType
 | 
			
		||||
        , isReferenceParameter = False
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
toMap :: SymbolTable  -> HashMap Identifier Info
 | 
			
		||||
toMap (SymbolTable _ map') = map'
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,8 @@ statement localTable (AST.CallStatement (AST.Identifier callName) arguments) = d
 | 
			
		||||
        $ CallQuadruple callName
 | 
			
		||||
        $ fromIntegral
 | 
			
		||||
        $ Vector.length argumentStatements
 | 
			
		||||
statement localTable (AST.CompoundStatement statements) =
 | 
			
		||||
    fold <$> traverse (statement localTable) statements
 | 
			
		||||
{- statement localTable (AST.AssignmentStatement variableAccess' assignee) = do
 | 
			
		||||
    (rhsOperand, rhsStatements) <- expression localTable assignee
 | 
			
		||||
    let variableType' = variableType variableAccess' localTable
 | 
			
		||||
@@ -105,9 +107,7 @@ statement localTable (AST.WhileStatement whileCondition whileStatement) = do
 | 
			
		||||
        <> conditionStatements
 | 
			
		||||
        <> Vector.fromList [jumpConstructor startLabel, GoToQuadruple endLabel, LabelQuadruple startLabel]
 | 
			
		||||
        <> whileStatements
 | 
			
		||||
        <> Vector.fromList [GoToQuadruple conditionLabel, LabelQuadruple endLabel]
 | 
			
		||||
statement localTable (AST.CompoundStatement statements) =
 | 
			
		||||
    fold <$> traverse (statement localTable) statements -}
 | 
			
		||||
        <> Vector.fromList [GoToQuadruple conditionLabel, LabelQuadruple endLabel] -}
 | 
			
		||||
 | 
			
		||||
createTemporary :: Glue Variable
 | 
			
		||||
createTemporary = do
 | 
			
		||||
@@ -233,6 +233,8 @@ expression localTable = \case
 | 
			
		||||
            ( VariableOperand tempVariable
 | 
			
		||||
            , Vector.snoc statements negationQuadruple
 | 
			
		||||
            )
 | 
			
		||||
    (AST.ProductExpression lhs rhs) ->
 | 
			
		||||
        binaryExpression ProductQuadruple lhs rhs
 | 
			
		||||
{-    (AST.VariableExpression variableExpression) -> do
 | 
			
		||||
        let variableType' = variableType variableExpression localTable
 | 
			
		||||
        variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
 | 
			
		||||
@@ -246,8 +248,6 @@ expression localTable = \case
 | 
			
		||||
                    ( VariableOperand arrayAddress
 | 
			
		||||
                    , Vector.snoc statements arrayStatement
 | 
			
		||||
                    )
 | 
			
		||||
    (AST.ProductExpression lhs rhs) ->
 | 
			
		||||
        binaryExpression ProductQuadruple lhs rhs
 | 
			
		||||
    (AST.DivisionExpression lhs rhs) ->
 | 
			
		||||
        binaryExpression DivisionQuadruple lhs rhs -}
 | 
			
		||||
  where
 | 
			
		||||
@@ -263,8 +263,5 @@ expression localTable = \case
 | 
			
		||||
 | 
			
		||||
literal :: AST.Literal -> Operand Variable
 | 
			
		||||
literal (AST.IntegerLiteral integer) = IntOperand integer
 | 
			
		||||
{-literal (AST.HexadecimalLiteral integer) = IntOperand integer
 | 
			
		||||
literal (AST.HexadecimalLiteral integer) = IntOperand integer
 | 
			
		||||
literal (AST.CharacterLiteral character) = IntOperand $ fromIntegral character
 | 
			
		||||
literal (AST.BooleanLiteral boolean)
 | 
			
		||||
    | boolean = IntOperand 1
 | 
			
		||||
    | otherwise = IntOperand 0 -}
 | 
			
		||||
 
 | 
			
		||||
@@ -132,6 +132,32 @@ quadruple (NegationQuadruple operand1 (Store register))
 | 
			
		||||
            $ RiscV.BaseInstruction RiscV.Op
 | 
			
		||||
            $ RiscV.R register RiscV.SUB RiscV.Zero operandRegister1
 | 
			
		||||
            $ RiscV.Funct7 0b0100000
 | 
			
		||||
quadruple (ProductQuadruple operand1 operand2 (Store register))
 | 
			
		||||
    | IntOperand immediateOperand1 <- operand1
 | 
			
		||||
    , IntOperand immediateOperand2 <- operand2 =
 | 
			
		||||
        lui (immediateOperand1 * immediateOperand2) register
 | 
			
		||||
    | VariableOperand variableOperand1 <- operand1
 | 
			
		||||
    , VariableOperand variableOperand2 <- operand2 =
 | 
			
		||||
        let Store operandRegister1 = variableOperand1
 | 
			
		||||
            Store operandRegister2 = variableOperand2
 | 
			
		||||
        in pure $ Instruction
 | 
			
		||||
            $ RiscV.BaseInstruction RiscV.Op
 | 
			
		||||
            $ RiscV.R register RiscV.MUL operandRegister1 operandRegister2 (RiscV.Funct7 0b0000001)
 | 
			
		||||
    | VariableOperand variableOperand1 <- operand1
 | 
			
		||||
    , IntOperand immediateOperand2 <- operand2 =
 | 
			
		||||
        multiplyImmediateRegister variableOperand1 immediateOperand2
 | 
			
		||||
    | IntOperand immediateOperand1 <- operand1
 | 
			
		||||
    , VariableOperand variableOperand2 <- operand2 =
 | 
			
		||||
        multiplyImmediateRegister variableOperand2 immediateOperand1
 | 
			
		||||
  where
 | 
			
		||||
    multiplyImmediateRegister variableOperand immediateOperand = 
 | 
			
		||||
        let statements = lui immediateOperand register
 | 
			
		||||
            Store operandRegister = variableOperand
 | 
			
		||||
        in Vector.snoc statements
 | 
			
		||||
            $ Instruction
 | 
			
		||||
            $ RiscV.BaseInstruction RiscV.Op
 | 
			
		||||
            $ RiscV.R register RiscV.MUL register operandRegister
 | 
			
		||||
            $ RiscV.Funct7 0b0000001
 | 
			
		||||
 | 
			
		||||
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
 | 
			
		||||
loadImmediateOrRegister (IntOperand intValue) targetRegister =
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/expectations/exit_between_statements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/expectations/exit_between_statements.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
c
 | 
			
		||||
							
								
								
									
										2
									
								
								tests/expectations/print_2_statements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tests/expectations/print_2_statements.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
13
 | 
			
		||||
2097150
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/expectations/print_char.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/expectations/print_char.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
x
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/expectations/print_product.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/expectations/print_product.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
1000
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/expectations/printi_hex.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/expectations/printi_hex.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
129
 | 
			
		||||
							
								
								
									
										5
									
								
								tests/vm/exit_between_statements.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/vm/exit_between_statements.elna
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
proc main() {
 | 
			
		||||
  printc('c');
 | 
			
		||||
  exit();
 | 
			
		||||
  printi(1234);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								tests/vm/print_2_statements.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								tests/vm/print_2_statements.elna
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
proc main() {
 | 
			
		||||
  printi(13);
 | 
			
		||||
  printi(2097150);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								tests/vm/print_char.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/vm/print_char.elna
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
proc main() {
 | 
			
		||||
  printc('x');
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								tests/vm/print_product.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/vm/print_product.elna
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
proc main() {
 | 
			
		||||
  printi(20 * 50);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								tests/vm/printi_hex.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/vm/printi_hex.elna
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
proc main() {
 | 
			
		||||
  printi(0x81);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,12 @@
 | 
			
		||||
.global printi
 | 
			
		||||
.type printi, @function
 | 
			
		||||
 | 
			
		||||
.global printc
 | 
			
		||||
.type printc, @function
 | 
			
		||||
 | 
			
		||||
.global exit
 | 
			
		||||
.type exit, @function
 | 
			
		||||
 | 
			
		||||
.global _start
 | 
			
		||||
.type _start, @function
 | 
			
		||||
 | 
			
		||||
@@ -53,8 +59,35 @@ printi:
 | 
			
		||||
    addi sp, sp, 16
 | 
			
		||||
    ret
 | 
			
		||||
 | 
			
		||||
_start:
 | 
			
		||||
    call main
 | 
			
		||||
printc:
 | 
			
		||||
    addi sp, sp, -12
 | 
			
		||||
    sw s0, 0(sp)
 | 
			
		||||
    sw ra, 4(sp)
 | 
			
		||||
    addi s0, sp, 12
 | 
			
		||||
 | 
			
		||||
    addi t1, zero, '\n'
 | 
			
		||||
    sb t1, -1(s0)
 | 
			
		||||
 | 
			
		||||
    lw t0, 0(s0)
 | 
			
		||||
    sb t0, -2(s0)
 | 
			
		||||
 | 
			
		||||
    addi a0, zero, 1
 | 
			
		||||
    addi a1, s0, -2
 | 
			
		||||
    addi a2, zero, 2
 | 
			
		||||
    addi a7, zero, 64
 | 
			
		||||
    ecall
 | 
			
		||||
 | 
			
		||||
    lw s0, 0(sp)
 | 
			
		||||
    lw ra, 4(sp)
 | 
			
		||||
    addi sp, sp, 12
 | 
			
		||||
    ret
 | 
			
		||||
 | 
			
		||||
exit:
 | 
			
		||||
    addi a0, zero, 0
 | 
			
		||||
    addi a7, zero, 93
 | 
			
		||||
    ecall
 | 
			
		||||
    # ret
 | 
			
		||||
 | 
			
		||||
_start:
 | 
			
		||||
    call main
 | 
			
		||||
    call exit
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user