Implement addition and subtraction
This commit is contained in:
parent
ed144309fa
commit
c2c923276f
8
TODO
8
TODO
@ -17,6 +17,12 @@
|
|||||||
|
|
||||||
# Built-in
|
# Built-in
|
||||||
|
|
||||||
Printi should print a sign for negative numbers.
|
- Implement printc (with int argument).
|
||||||
|
- Implement exit() as standalone function.
|
||||||
|
|
||||||
|
# Register allocation
|
||||||
|
|
||||||
|
- Temporary variables always use the same register, t0. Allocate registers for
|
||||||
|
temporaries.
|
||||||
|
|
||||||
# Type analysis
|
# Type analysis
|
||||||
|
@ -115,12 +115,12 @@ instance Show VariableDeclaration
|
|||||||
show (VariableDeclaration identifier typeExpression) =
|
show (VariableDeclaration identifier typeExpression) =
|
||||||
concat ["var ", show identifier, ": " <> show typeExpression, ";"]
|
concat ["var ", show identifier, ": " <> show typeExpression, ";"]
|
||||||
|
|
||||||
newtype Expression
|
data Expression
|
||||||
= LiteralExpression Literal
|
= LiteralExpression Literal
|
||||||
{- | VariableExpression VariableAccess
|
|
||||||
| NegationExpression Expression
|
|
||||||
| SumExpression Expression Expression
|
| SumExpression Expression Expression
|
||||||
| SubtractionExpression Expression Expression
|
| SubtractionExpression Expression Expression
|
||||||
|
{- | VariableExpression VariableAccess
|
||||||
|
| NegationExpression Expression
|
||||||
| ProductExpression Expression Expression
|
| ProductExpression Expression Expression
|
||||||
| DivisionExpression Expression Expression -}
|
| DivisionExpression Expression Expression -}
|
||||||
deriving Eq
|
deriving Eq
|
||||||
@ -128,10 +128,10 @@ newtype Expression
|
|||||||
instance Show Expression
|
instance Show Expression
|
||||||
where
|
where
|
||||||
show (LiteralExpression literal) = show literal
|
show (LiteralExpression literal) = show literal
|
||||||
{- show (VariableExpression variable) = show variable
|
|
||||||
show (NegationExpression negation) = '-' : show negation
|
|
||||||
show (SumExpression lhs rhs) = concat [show lhs, " + ", show rhs]
|
show (SumExpression lhs rhs) = concat [show lhs, " + ", show rhs]
|
||||||
show (SubtractionExpression lhs rhs) = concat [show lhs, " - ", show rhs]
|
show (SubtractionExpression lhs rhs) = concat [show lhs, " - ", show rhs]
|
||||||
|
{- show (VariableExpression variable) = show variable
|
||||||
|
show (NegationExpression negation) = '-' : show negation
|
||||||
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
|
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
|
||||||
show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs] -}
|
show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs] -}
|
||||||
{-
|
{-
|
||||||
|
@ -6,11 +6,12 @@ module Language.Elna.CodeGenerator
|
|||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import Data.HashMap.Strict (HashMap)
|
import Data.HashMap.Strict (HashMap)
|
||||||
import qualified Data.HashMap.Strict as HashMap
|
import qualified Data.HashMap.Strict as HashMap
|
||||||
|
import Data.Int (Int32)
|
||||||
import Data.Vector (Vector)
|
import Data.Vector (Vector)
|
||||||
import qualified Data.Vector as Vector
|
import qualified Data.Vector as Vector
|
||||||
import qualified Data.Text.Encoding as Text.Encoding
|
import qualified Data.Text.Encoding as Text.Encoding
|
||||||
import Language.Elna.Location (Identifier(..))
|
import Language.Elna.Location (Identifier(..))
|
||||||
import Language.Elna.Intermediate (Operand(..), Quadruple(..))
|
import Language.Elna.Intermediate (Operand(..), Quadruple(..), Variable(..))
|
||||||
import qualified Language.Elna.Architecture.RiscV as RiscV
|
import qualified Language.Elna.Architecture.RiscV as RiscV
|
||||||
import Language.Elna.SymbolTable (SymbolTable)
|
import Language.Elna.SymbolTable (SymbolTable)
|
||||||
import Data.Bits (Bits(..))
|
import Data.Bits (Bits(..))
|
||||||
@ -40,27 +41,12 @@ quadruple StartQuadruple = Vector.fromList
|
|||||||
, Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 4 RiscV.SW RiscV.SP RiscV.RA)
|
, Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 4 RiscV.SW RiscV.SP RiscV.RA)
|
||||||
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.S0 RiscV.ADDI RiscV.SP 4)
|
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.S0 RiscV.ADDI RiscV.SP 4)
|
||||||
]
|
]
|
||||||
quadruple (ParameterQuadruple (IntOperand intValue))
|
quadruple (ParameterQuadruple operand1) =
|
||||||
= mappend go
|
let (operandRegister, statements) = loadImmediateOrRegister operand1 RiscV.A0
|
||||||
$ Vector.fromList
|
in mappend statements $ Vector.fromList
|
||||||
[ Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP (negate 4))
|
[ Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP (negate 4))
|
||||||
, Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 0 RiscV.SW RiscV.SP RiscV.A0)
|
, Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 0 RiscV.SW RiscV.SP operandRegister)
|
||||||
]
|
]
|
||||||
where
|
|
||||||
hi = intValue `shiftR` 12
|
|
||||||
lo = intValue
|
|
||||||
go
|
|
||||||
| intValue >= -2048
|
|
||||||
, intValue <= 2047 = Vector.singleton
|
|
||||||
$ Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.A0 RiscV.ADDI RiscV.A0 $ fromIntegral lo)
|
|
||||||
| intValue .&. 0x800 /= 0 = Vector.fromList
|
|
||||||
[ Instruction (RiscV.BaseInstruction RiscV.Lui $ RiscV.U RiscV.A0 $ fromIntegral $ succ hi)
|
|
||||||
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.A0 RiscV.ADDI RiscV.A0 $ fromIntegral lo)
|
|
||||||
]
|
|
||||||
| otherwise = Vector.fromList
|
|
||||||
[ Instruction (RiscV.BaseInstruction RiscV.Lui $ RiscV.U RiscV.A0 $ fromIntegral hi)
|
|
||||||
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.A0 RiscV.ADDI RiscV.A0 $ fromIntegral lo)
|
|
||||||
]
|
|
||||||
quadruple (CallQuadruple callName numberOfArguments) = Vector.fromList
|
quadruple (CallQuadruple callName numberOfArguments) = Vector.fromList
|
||||||
[ Instruction (RiscV.CallInstruction callName)
|
[ Instruction (RiscV.CallInstruction callName)
|
||||||
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP (numberOfArguments * 4))
|
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP (numberOfArguments * 4))
|
||||||
@ -71,3 +57,39 @@ quadruple StopQuadruple = Vector.fromList
|
|||||||
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP 4)
|
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP 4)
|
||||||
, Instruction (RiscV.BaseInstruction RiscV.Jalr $ RiscV.I RiscV.RA RiscV.JALR RiscV.Zero 0)
|
, Instruction (RiscV.BaseInstruction RiscV.Jalr $ RiscV.I RiscV.RA RiscV.JALR RiscV.Zero 0)
|
||||||
]
|
]
|
||||||
|
quadruple (AddQuadruple operand1 operand2 (TempVariable _)) =
|
||||||
|
let (operandRegister1, statements1) = loadImmediateOrRegister operand1 RiscV.A0
|
||||||
|
(operandRegister2, statements2) = loadImmediateOrRegister operand2 RiscV.A1
|
||||||
|
in Vector.snoc (statements1 <> statements2)
|
||||||
|
$ Instruction
|
||||||
|
$ RiscV.BaseInstruction RiscV.Op
|
||||||
|
$ RiscV.R RiscV.T0 RiscV.ADD operandRegister1 operandRegister2 (RiscV.Funct7 0b0000000)
|
||||||
|
quadruple (SubtractionQuadruple operand1 operand2 (TempVariable _)) =
|
||||||
|
let (operandRegister1, statements1) = loadImmediateOrRegister operand1 RiscV.A0
|
||||||
|
(operandRegister2, statements2) = loadImmediateOrRegister operand2 RiscV.A1
|
||||||
|
in Vector.snoc (statements1 <> statements2)
|
||||||
|
$ Instruction
|
||||||
|
$ RiscV.BaseInstruction RiscV.Op
|
||||||
|
$ RiscV.R RiscV.T0 RiscV.SUB operandRegister1 operandRegister2 (RiscV.Funct7 0b0100000)
|
||||||
|
|
||||||
|
loadImmediateOrRegister :: Operand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
|
||||||
|
loadImmediateOrRegister (IntOperand intValue) targetRegister =
|
||||||
|
(targetRegister, lui intValue targetRegister)
|
||||||
|
loadImmediateOrRegister (VariableOperand _) _ = (RiscV.T0, Vector.empty)
|
||||||
|
|
||||||
|
lui :: Int32 -> RiscV.XRegister -> Vector Statement
|
||||||
|
lui intValue targetRegister
|
||||||
|
| intValue >= -2048
|
||||||
|
, intValue <= 2047 = Vector.singleton
|
||||||
|
$ Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I targetRegister RiscV.ADDI RiscV.Zero lo)
|
||||||
|
| intValue .&. 0x800 /= 0 = Vector.fromList
|
||||||
|
[ Instruction (RiscV.BaseInstruction RiscV.Lui $ RiscV.U targetRegister $ fromIntegral $ succ hi)
|
||||||
|
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I targetRegister RiscV.ADDI targetRegister lo)
|
||||||
|
]
|
||||||
|
| otherwise = Vector.fromList
|
||||||
|
[ Instruction (RiscV.BaseInstruction RiscV.Lui $ RiscV.U targetRegister $ fromIntegral hi)
|
||||||
|
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I targetRegister RiscV.ADDI targetRegister lo)
|
||||||
|
]
|
||||||
|
where
|
||||||
|
hi = intValue `shiftR` 12
|
||||||
|
lo = fromIntegral intValue
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
module Language.Elna.Intermediate
|
module Language.Elna.Intermediate
|
||||||
( Operand(..)
|
( Operand(..)
|
||||||
, Quadruple(..)
|
, Quadruple(..)
|
||||||
{- , Label(..)
|
{- , Label(..) -}
|
||||||
, Variable(..) -}
|
, Variable(..)
|
||||||
, intermediate
|
, intermediate
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -17,12 +17,20 @@ import Data.Text (Text)
|
|||||||
import qualified Language.Elna.AST as AST
|
import qualified Language.Elna.AST as AST
|
||||||
import Language.Elna.SymbolTable (SymbolTable{-, Info(..) -})
|
import Language.Elna.SymbolTable (SymbolTable{-, Info(..) -})
|
||||||
import Data.Foldable (Foldable(..))
|
import Data.Foldable (Foldable(..))
|
||||||
import Control.Monad.Trans.State (State, runState)
|
import Control.Monad.Trans.State (State, get, modify', runState)
|
||||||
import Data.Maybe (catMaybes)
|
import Data.Maybe (catMaybes)
|
||||||
|
|
||||||
newtype Operand
|
newtype Variable = TempVariable Word32 -- | Variable Text
|
||||||
|
deriving Eq
|
||||||
|
|
||||||
|
instance Show Variable
|
||||||
|
where
|
||||||
|
-- show (Variable variable) = '$' : Text.unpack variable
|
||||||
|
show (TempVariable variable) = '$' : show variable
|
||||||
|
|
||||||
|
data Operand
|
||||||
= IntOperand Int32
|
= IntOperand Int32
|
||||||
-- | VariableOperand Variable
|
| VariableOperand Variable
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
data Quadruple
|
data Quadruple
|
||||||
@ -30,12 +38,12 @@ data Quadruple
|
|||||||
| StopQuadruple
|
| StopQuadruple
|
||||||
| ParameterQuadruple Operand
|
| ParameterQuadruple Operand
|
||||||
| CallQuadruple Text Word32
|
| CallQuadruple Text Word32
|
||||||
|
| AddQuadruple Operand Operand Variable
|
||||||
|
| SubtractionQuadruple Operand Operand Variable
|
||||||
{-| 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
|
||||||
| AddQuadruple Operand Operand Variable
|
|
||||||
| SubtractionQuadruple Operand Operand Variable
|
|
||||||
| ProductQuadruple Operand Operand Variable
|
| ProductQuadruple Operand Operand Variable
|
||||||
| DivisionQuadruple Operand Operand Variable
|
| DivisionQuadruple Operand Operand Variable
|
||||||
| NegationQuadruple Operand Variable
|
| NegationQuadruple Operand Variable
|
||||||
@ -142,6 +150,12 @@ statement localTable (AST.WhileStatement whileCondition whileStatement) = do
|
|||||||
statement localTable (AST.CompoundStatement statements) =
|
statement localTable (AST.CompoundStatement statements) =
|
||||||
fold <$> traverse (statement localTable) statements -}
|
fold <$> traverse (statement localTable) statements -}
|
||||||
|
|
||||||
|
createTemporary :: Intermediate Variable
|
||||||
|
createTemporary = do
|
||||||
|
currentCounter <- Intermediate get
|
||||||
|
Intermediate $ modify' (+ 1)
|
||||||
|
pure $ TempVariable currentCounter
|
||||||
|
|
||||||
{-
|
{-
|
||||||
import Language.Elna.Types (Type(..))
|
import Language.Elna.Types (Type(..))
|
||||||
import qualified Language.Elna.SymbolTable as SymbolTable
|
import qualified Language.Elna.SymbolTable as SymbolTable
|
||||||
@ -171,16 +185,6 @@ createLabel = do
|
|||||||
{ labelCounter = getField @"labelCounter" generator + 1
|
{ labelCounter = getField @"labelCounter" generator + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
createTemporary :: Intermediate Variable
|
|
||||||
createTemporary = do
|
|
||||||
currentCounter <- Intermediate $ gets temporaryCounter
|
|
||||||
Intermediate $ modify' modifier
|
|
||||||
pure $ TempVariable currentCounter
|
|
||||||
where
|
|
||||||
modifier generator = generator
|
|
||||||
{ temporaryCounter = getField @"temporaryCounter" generator + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
condition
|
condition
|
||||||
:: SymbolTable
|
:: SymbolTable
|
||||||
-> AST.Condition
|
-> AST.Condition
|
||||||
@ -257,8 +261,11 @@ variableType (AST.ArrayAccess arrayAccess' _) symbolTable =
|
|||||||
variableType arrayAccess' symbolTable
|
variableType arrayAccess' symbolTable
|
||||||
-}
|
-}
|
||||||
expression :: SymbolTable -> AST.Expression -> Intermediate (Operand, Vector Quadruple)
|
expression :: SymbolTable -> AST.Expression -> Intermediate (Operand, Vector Quadruple)
|
||||||
expression _localTable = \case
|
expression localTable = \case
|
||||||
(AST.LiteralExpression literal') -> pure (literal literal', mempty)
|
(AST.LiteralExpression literal') -> pure (literal literal', mempty)
|
||||||
|
(AST.SumExpression lhs rhs) -> binaryExpression AddQuadruple lhs rhs
|
||||||
|
(AST.SubtractionExpression lhs rhs) ->
|
||||||
|
binaryExpression SubtractionQuadruple lhs rhs
|
||||||
{- (AST.VariableExpression variableExpression) -> do
|
{- (AST.VariableExpression variableExpression) -> do
|
||||||
let variableType' = variableType variableExpression localTable
|
let variableType' = variableType variableExpression localTable
|
||||||
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
|
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
|
||||||
@ -280,13 +287,10 @@ expression _localTable = \case
|
|||||||
( VariableOperand tempVariable
|
( VariableOperand tempVariable
|
||||||
, Vector.snoc statements negationQuadruple
|
, Vector.snoc statements negationQuadruple
|
||||||
)
|
)
|
||||||
(AST.SumExpression lhs rhs) -> binaryExpression AddQuadruple lhs rhs
|
|
||||||
(AST.SubtractionExpression lhs rhs) ->
|
|
||||||
binaryExpression SubtractionQuadruple lhs rhs
|
|
||||||
(AST.ProductExpression lhs rhs) ->
|
(AST.ProductExpression lhs rhs) ->
|
||||||
binaryExpression ProductQuadruple lhs rhs
|
binaryExpression ProductQuadruple lhs rhs
|
||||||
(AST.DivisionExpression lhs rhs) ->
|
(AST.DivisionExpression lhs rhs) ->
|
||||||
binaryExpression DivisionQuadruple lhs rhs
|
binaryExpression DivisionQuadruple lhs rhs -}
|
||||||
where
|
where
|
||||||
binaryExpression f lhs rhs = do
|
binaryExpression f lhs rhs = do
|
||||||
(lhsOperand, lhsStatements) <- expression localTable lhs
|
(lhsOperand, lhsStatements) <- expression localTable lhs
|
||||||
@ -298,14 +302,6 @@ expression _localTable = \case
|
|||||||
, Vector.snoc (lhsStatements <> rhsStatements) newQuadruple
|
, Vector.snoc (lhsStatements <> rhsStatements) newQuadruple
|
||||||
)
|
)
|
||||||
|
|
||||||
data Variable = Variable Text | TempVariable Int32
|
|
||||||
deriving Eq
|
|
||||||
|
|
||||||
instance Show Variable
|
|
||||||
where
|
|
||||||
show (Variable variable) = '$' : Text.unpack variable
|
|
||||||
show (TempVariable variable) = '$' : show variable
|
|
||||||
-}
|
|
||||||
literal :: AST.Literal -> Operand
|
literal :: AST.Literal -> Operand
|
||||||
literal (AST.IntegerLiteral integer) = IntOperand integer
|
literal (AST.IntegerLiteral integer) = IntOperand integer
|
||||||
{-literal (AST.HexadecimalLiteral integer) = IntOperand integer
|
{-literal (AST.HexadecimalLiteral integer) = IntOperand integer
|
||||||
|
@ -136,16 +136,16 @@ checkSymbol globalTable identifier
|
|||||||
|
|
||||||
expression :: SymbolTable -> AST.Expression -> NameAnalysis ()
|
expression :: SymbolTable -> AST.Expression -> NameAnalysis ()
|
||||||
expression _ (AST.LiteralExpression _) = pure ()
|
expression _ (AST.LiteralExpression _) = pure ()
|
||||||
{- expression globalTable (AST.VariableExpression variableExpression) =
|
|
||||||
variableAccess globalTable variableExpression
|
|
||||||
expression globalTable (AST.NegationExpression negation) =
|
|
||||||
expression globalTable negation
|
|
||||||
expression globalTable (AST.SumExpression lhs rhs)
|
expression globalTable (AST.SumExpression lhs rhs)
|
||||||
= expression globalTable lhs
|
= expression globalTable lhs
|
||||||
>> expression globalTable rhs
|
>> expression globalTable rhs
|
||||||
expression globalTable (AST.SubtractionExpression lhs rhs)
|
expression globalTable (AST.SubtractionExpression lhs rhs)
|
||||||
= expression globalTable lhs
|
= expression globalTable lhs
|
||||||
>> expression globalTable rhs
|
>> expression globalTable rhs
|
||||||
|
{- expression globalTable (AST.VariableExpression variableExpression) =
|
||||||
|
variableAccess globalTable variableExpression
|
||||||
|
expression globalTable (AST.NegationExpression negation) =
|
||||||
|
expression globalTable negation
|
||||||
expression globalTable (AST.ProductExpression lhs rhs)
|
expression globalTable (AST.ProductExpression lhs rhs)
|
||||||
= expression globalTable lhs
|
= expression globalTable lhs
|
||||||
>> expression globalTable rhs
|
>> expression globalTable rhs
|
||||||
|
@ -4,7 +4,7 @@ module Language.Elna.Parser
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad (void)
|
import Control.Monad (void)
|
||||||
import Control.Monad.Combinators.Expr ({-Operator(..), -} makeExprParser)
|
import Control.Monad.Combinators.Expr (Operator(..), makeExprParser)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as Text
|
import qualified Data.Text as Text
|
||||||
import Data.Void (Void)
|
import Data.Void (Void)
|
||||||
@ -69,6 +69,31 @@ termP = choice
|
|||||||
, LiteralExpression <$> literalP
|
, LiteralExpression <$> literalP
|
||||||
-- , VariableExpression <$> variableAccessP
|
-- , VariableExpression <$> variableAccessP
|
||||||
]
|
]
|
||||||
|
|
||||||
|
operatorTable :: [[Operator Parser Expression]]
|
||||||
|
operatorTable =
|
||||||
|
[{- unaryOperator
|
||||||
|
, factorOperator
|
||||||
|
,-} termOperator
|
||||||
|
]
|
||||||
|
where
|
||||||
|
{- unaryOperator =
|
||||||
|
[ prefix "-" NegationExpression
|
||||||
|
, prefix "+" id
|
||||||
|
]
|
||||||
|
factorOperator =
|
||||||
|
[ binary "*" ProductExpression
|
||||||
|
, binary "/" DivisionExpression
|
||||||
|
] -}
|
||||||
|
termOperator =
|
||||||
|
[ binary "+" SumExpression
|
||||||
|
, binary "-" SubtractionExpression
|
||||||
|
]
|
||||||
|
-- prefix name f = Prefix (f <$ symbol name)
|
||||||
|
binary name f = InfixL (f <$ symbol name)
|
||||||
|
|
||||||
|
expressionP :: Parser Expression
|
||||||
|
expressionP = makeExprParser termP operatorTable
|
||||||
{-
|
{-
|
||||||
variableAccessP :: Parser VariableAccess
|
variableAccessP :: Parser VariableAccess
|
||||||
variableAccessP = do
|
variableAccessP = do
|
||||||
@ -76,31 +101,6 @@ variableAccessP = do
|
|||||||
indices <- many $ bracketsP expressionP
|
indices <- many $ bracketsP expressionP
|
||||||
pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices
|
pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices
|
||||||
|
|
||||||
operatorTable :: [[Operator Parser Expression]]
|
|
||||||
operatorTable =
|
|
||||||
[ unaryOperator
|
|
||||||
, factorOperator
|
|
||||||
, termOperator
|
|
||||||
]
|
|
||||||
where
|
|
||||||
unaryOperator =
|
|
||||||
[ prefix "-" NegationExpression
|
|
||||||
, prefix "+" id
|
|
||||||
]
|
|
||||||
factorOperator =
|
|
||||||
[ binary "*" ProductExpression
|
|
||||||
, binary "/" DivisionExpression
|
|
||||||
]
|
|
||||||
termOperator =
|
|
||||||
[ binary "+" SumExpression
|
|
||||||
, binary "-" SubtractionExpression
|
|
||||||
]
|
|
||||||
prefix name f = Prefix (f <$ symbol name)
|
|
||||||
binary name f = InfixL (f <$ symbol name)
|
|
||||||
-}
|
|
||||||
expressionP :: Parser Expression
|
|
||||||
expressionP = makeExprParser termP [] -- operatorTable
|
|
||||||
{-
|
|
||||||
conditionP :: Parser Condition
|
conditionP :: Parser Condition
|
||||||
conditionP = do
|
conditionP = do
|
||||||
lhs <- expressionP
|
lhs <- expressionP
|
||||||
@ -204,8 +204,8 @@ statementP
|
|||||||
<$> variableAccessP
|
<$> variableAccessP
|
||||||
<* symbol ":="
|
<* symbol ":="
|
||||||
<*> expressionP
|
<*> expressionP
|
||||||
<* semicolonP
|
<* semicolonP -}
|
||||||
-}
|
|
||||||
variableDeclarationP :: Parser VariableDeclaration
|
variableDeclarationP :: Parser VariableDeclaration
|
||||||
variableDeclarationP = VariableDeclaration
|
variableDeclarationP = VariableDeclaration
|
||||||
<$> (symbol "var" *> identifierP)
|
<$> (symbol "var" *> identifierP)
|
||||||
|
1
tests/expectations/print_subtraction.txt
Normal file
1
tests/expectations/print_subtraction.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
-8
|
1
tests/expectations/print_sum.txt
Normal file
1
tests/expectations/print_sum.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
18
|
3
tests/vm/print_subtraction.elna
Normal file
3
tests/vm/print_subtraction.elna
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
proc main() {
|
||||||
|
printi(5 - 13);
|
||||||
|
}
|
3
tests/vm/print_sum.elna
Normal file
3
tests/vm/print_sum.elna
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
proc main() {
|
||||||
|
printi(5 + 13);
|
||||||
|
}
|
@ -18,10 +18,16 @@ printi:
|
|||||||
# t1 - Constant 10.
|
# t1 - Constant 10.
|
||||||
# a1 - Local buffer.
|
# a1 - Local buffer.
|
||||||
# t2 - Current character.
|
# t2 - Current character.
|
||||||
|
# t3 - Whether the number is negative.
|
||||||
lw t0, 0(s0)
|
lw t0, 0(s0)
|
||||||
addi t1, zero, 10
|
addi t1, zero, 10
|
||||||
addi a1, s0, -2
|
addi a1, s0, -2
|
||||||
|
|
||||||
|
addi t3, zero, 0
|
||||||
|
bge t0, zero, .digit10
|
||||||
|
addi t3, zero, 1
|
||||||
|
sub t0, zero, t0
|
||||||
|
|
||||||
.digit10:
|
.digit10:
|
||||||
rem t2, t0, t1
|
rem t2, t0, t1
|
||||||
addi t2, t2, '0'
|
addi t2, t2, '0'
|
||||||
@ -30,8 +36,12 @@ printi:
|
|||||||
addi a1, a1, -1
|
addi a1, a1, -1
|
||||||
bne zero, t0, .digit10
|
bne zero, t0, .digit10
|
||||||
|
|
||||||
ecall
|
beq zero, t3, .write_call
|
||||||
|
addi t2, zero, '-'
|
||||||
|
sb t2, 0(a1)
|
||||||
|
addi a1, a1, -1
|
||||||
|
|
||||||
|
.write_call:
|
||||||
addi a0, zero, 1
|
addi a0, zero, 1
|
||||||
addi a1, a1, 1
|
addi a1, a1, 1
|
||||||
sub a2, s0, a1
|
sub a2, s0, a1
|
||||||
|
Loading…
Reference in New Issue
Block a user