Negate integral expressions
This commit is contained in:
parent
cafae5c830
commit
fdf56ce9d0
1
TODO
1
TODO
@ -28,4 +28,3 @@
|
||||
# Other
|
||||
|
||||
- Type analysis.
|
||||
- Move platform dependent code generation into a submodule.
|
||||
|
21
elna.cabal
21
elna.cabal
@ -35,20 +35,21 @@ common warnings
|
||||
library elna-internal
|
||||
import: warnings
|
||||
exposed-modules:
|
||||
Language.Elna.Allocator
|
||||
Language.Elna.Architecture.RiscV
|
||||
Language.Elna.AST
|
||||
Language.Elna.CodeGenerator
|
||||
Language.Elna.Backend.Allocator
|
||||
Language.Elna.Backend.Intermediate
|
||||
Language.Elna.CommandLine
|
||||
Language.Elna.PrinterWriter
|
||||
Language.Elna.Intermediate
|
||||
Language.Elna.Frontend.AST
|
||||
Language.Elna.Frontend.NameAnalysis
|
||||
Language.Elna.Frontend.Parser
|
||||
Language.Elna.Frontend.SymbolTable
|
||||
Language.Elna.Frontend.TypeAnalysis
|
||||
Language.Elna.Frontend.Types
|
||||
Language.Elna.Glue
|
||||
Language.Elna.Location
|
||||
Language.Elna.NameAnalysis
|
||||
Language.Elna.Object.Elf
|
||||
Language.Elna.Parser
|
||||
Language.Elna.SymbolTable
|
||||
Language.Elna.TypeAnalysis
|
||||
Language.Elna.Types
|
||||
Language.Elna.RiscV.CodeGenerator
|
||||
Language.Elna.RiscV.ElfWriter
|
||||
build-depends:
|
||||
exceptions ^>= 0.10,
|
||||
hashable ^>= 1.4.3,
|
||||
|
@ -1,4 +1,4 @@
|
||||
module Language.Elna.Allocator
|
||||
module Language.Elna.Backend.Allocator
|
||||
( MachineConfiguration(..)
|
||||
, Store(..)
|
||||
, allocate
|
||||
@ -6,7 +6,7 @@ module Language.Elna.Allocator
|
||||
|
||||
import Data.HashMap.Strict (HashMap)
|
||||
import Data.Vector (Vector)
|
||||
import Language.Elna.Intermediate (Operand(..), Quadruple(..), Variable(..))
|
||||
import Language.Elna.Backend.Intermediate (Operand(..), Quadruple(..), Variable(..))
|
||||
import Language.Elna.Location (Identifier(..))
|
||||
|
||||
newtype Store r = Store r
|
||||
@ -34,6 +34,8 @@ allocate MachineConfiguration{..} = fmap function
|
||||
AddQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
|
||||
quadruple (SubtractionQuadruple operand1 operand2 _) =
|
||||
SubtractionQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
|
||||
quadruple (NegationQuadruple operand1 _) =
|
||||
NegationQuadruple (operand operand1) (Store temporaryRegister)
|
||||
operand :: Operand Variable -> Operand (Store r)
|
||||
operand (IntOperand x) = IntOperand x
|
||||
operand (VariableOperand _) = VariableOperand (Store temporaryRegister)
|
46
lib/Language/Elna/Backend/Intermediate.hs
Normal file
46
lib/Language/Elna/Backend/Intermediate.hs
Normal file
@ -0,0 +1,46 @@
|
||||
module Language.Elna.Backend.Intermediate
|
||||
( Operand(..)
|
||||
, Quadruple(..)
|
||||
{- , Label(..) -}
|
||||
, Variable(..)
|
||||
) where
|
||||
|
||||
import Data.Int (Int32)
|
||||
import Data.Word (Word32)
|
||||
import Data.Text (Text)
|
||||
|
||||
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 v
|
||||
= IntOperand Int32
|
||||
| VariableOperand v
|
||||
deriving (Eq, Show)
|
||||
|
||||
data Quadruple v
|
||||
= StartQuadruple
|
||||
| StopQuadruple
|
||||
| ParameterQuadruple (Operand v)
|
||||
| CallQuadruple Text Word32
|
||||
| AddQuadruple (Operand v) (Operand v) v
|
||||
| SubtractionQuadruple (Operand v) (Operand v) v
|
||||
| NegationQuadruple (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
|
||||
| LessQuadruple Operand Operand Label
|
||||
| GreaterQuadruple Operand Operand Label
|
||||
| LessOrEqualQuadruple Operand Operand Label
|
||||
| GreaterOrEqualQuadruple Operand Operand Label
|
||||
| LabelQuadruple Label -}
|
||||
deriving (Eq, Show)
|
@ -1,4 +1,4 @@
|
||||
module Language.Elna.AST
|
||||
module Language.Elna.Frontend.AST
|
||||
( Declaration(..)
|
||||
, Identifier(..)
|
||||
, Parameter(..)
|
||||
@ -119,8 +119,8 @@ data Expression
|
||||
= LiteralExpression Literal
|
||||
| SumExpression Expression Expression
|
||||
| SubtractionExpression Expression Expression
|
||||
{- | VariableExpression VariableAccess
|
||||
| NegationExpression Expression
|
||||
{- | VariableExpression VariableAccess
|
||||
| ProductExpression Expression Expression
|
||||
| DivisionExpression Expression Expression -}
|
||||
deriving Eq
|
||||
@ -130,8 +130,8 @@ instance Show Expression
|
||||
show (LiteralExpression literal) = show literal
|
||||
show (SumExpression 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 (VariableExpression variable) = show variable
|
||||
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
|
||||
show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs] -}
|
||||
{-
|
@ -1,13 +1,13 @@
|
||||
module Language.Elna.NameAnalysis
|
||||
module Language.Elna.Frontend.NameAnalysis
|
||||
( nameAnalysis
|
||||
, Error(..)
|
||||
) where
|
||||
|
||||
import qualified Data.List.NonEmpty as NonEmpty
|
||||
import qualified Data.Vector as Vector
|
||||
import qualified Language.Elna.SymbolTable as SymbolTable
|
||||
import qualified Language.Elna.AST as AST
|
||||
import Language.Elna.SymbolTable
|
||||
import qualified Language.Elna.Frontend.AST as AST
|
||||
import qualified Language.Elna.Frontend.SymbolTable as SymbolTable
|
||||
import Language.Elna.Frontend.SymbolTable
|
||||
( SymbolTable
|
||||
, Info(..)
|
||||
, ParameterInfo(..)
|
||||
@ -15,7 +15,7 @@ import Language.Elna.SymbolTable
|
||||
import Control.Monad.Trans.Except (Except, runExcept, throwE)
|
||||
import Data.Functor ((<&>))
|
||||
import Language.Elna.Location (Identifier(..))
|
||||
import Language.Elna.Types (Type(..))
|
||||
import Language.Elna.Frontend.Types (Type(..))
|
||||
import Data.Foldable (traverse_)
|
||||
import Control.Monad (foldM, unless)
|
||||
|
||||
@ -142,10 +142,10 @@ expression globalTable (AST.SumExpression lhs rhs)
|
||||
expression globalTable (AST.SubtractionExpression lhs rhs)
|
||||
= expression globalTable lhs
|
||||
>> expression globalTable rhs
|
||||
{- expression globalTable (AST.VariableExpression variableExpression) =
|
||||
variableAccess globalTable variableExpression
|
||||
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
|
@ -1,4 +1,4 @@
|
||||
module Language.Elna.Parser
|
||||
module Language.Elna.Frontend.Parser
|
||||
( Parser
|
||||
, programP
|
||||
) where
|
||||
@ -8,7 +8,7 @@ import Control.Monad.Combinators.Expr (Operator(..), makeExprParser)
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as Text
|
||||
import Data.Void (Void)
|
||||
import Language.Elna.AST
|
||||
import Language.Elna.Frontend.AST
|
||||
( Declaration(..)
|
||||
, Identifier(..)
|
||||
, Parameter(..)
|
||||
@ -48,7 +48,7 @@ type Parser = Parsec Void Text
|
||||
literalP :: Parser Literal
|
||||
literalP
|
||||
= {- HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal)
|
||||
<|> -} IntegerLiteral <$> lexeme Lexer.decimal
|
||||
<|> -} IntegerLiteral <$> Lexer.signed space integerP
|
||||
{- <|> CharacterLiteral <$> lexeme charP
|
||||
<|> BooleanLiteral <$> (symbol "true" $> True)
|
||||
<|> BooleanLiteral <$> (symbol "false" $> False)
|
||||
@ -72,16 +72,16 @@ termP = choice
|
||||
|
||||
operatorTable :: [[Operator Parser Expression]]
|
||||
operatorTable =
|
||||
[{- unaryOperator
|
||||
, factorOperator
|
||||
,-} termOperator
|
||||
[ unaryOperator
|
||||
-- , factorOperator
|
||||
, termOperator
|
||||
]
|
||||
where
|
||||
{- unaryOperator =
|
||||
unaryOperator =
|
||||
[ prefix "-" NegationExpression
|
||||
, prefix "+" id
|
||||
]
|
||||
factorOperator =
|
||||
{- factorOperator =
|
||||
[ binary "*" ProductExpression
|
||||
, binary "/" DivisionExpression
|
||||
] -}
|
||||
@ -89,7 +89,7 @@ operatorTable =
|
||||
[ binary "+" SumExpression
|
||||
, binary "-" SubtractionExpression
|
||||
]
|
||||
-- prefix name f = Prefix (f <$ symbol name)
|
||||
prefix name f = Prefix (f <$ symbol name)
|
||||
binary name f = InfixL (f <$ symbol name)
|
||||
|
||||
expressionP :: Parser Expression
|
||||
@ -144,6 +144,9 @@ commaP = void $ symbol ","
|
||||
semicolonP :: Parser ()
|
||||
semicolonP = void $ symbol ";"
|
||||
|
||||
integerP :: Integral a => Parser a
|
||||
integerP = lexeme Lexer.decimal
|
||||
|
||||
identifierP :: Parser Identifier
|
||||
identifierP =
|
||||
let wordParser = (:) <$> letterChar <*> many alphaNumChar <?> "identifier"
|
||||
@ -166,7 +169,7 @@ typeExpressionP = arrayTypeExpression
|
||||
<?> "type expression"
|
||||
where
|
||||
arrayTypeExpression = ArrayType
|
||||
<$> (symbol "array" *> bracketsP (lexeme Lexer.decimal))
|
||||
<$> (symbol "array" *> bracketsP integerP)
|
||||
<*> (symbol "of" *> typeExpressionP)
|
||||
|
||||
procedureDeclarationP :: Parser Declaration
|
@ -1,4 +1,4 @@
|
||||
module Language.Elna.SymbolTable
|
||||
module Language.Elna.Frontend.SymbolTable
|
||||
( SymbolTable
|
||||
, Info(..)
|
||||
, ParameterInfo(..)
|
||||
@ -22,7 +22,7 @@ import Data.Maybe (isJust)
|
||||
import Data.Vector (Vector)
|
||||
import qualified Data.Vector as Vector
|
||||
import Language.Elna.Location (Identifier(..))
|
||||
import Language.Elna.Types (Type(..), intType)
|
||||
import Language.Elna.Frontend.Types (Type(..), intType)
|
||||
import Prelude hiding (lookup)
|
||||
|
||||
data SymbolTable = SymbolTable (Maybe SymbolTable) (HashMap Identifier Info)
|
@ -1,10 +1,10 @@
|
||||
module Language.Elna.TypeAnalysis
|
||||
module Language.Elna.Frontend.TypeAnalysis
|
||||
( typeAnalysis
|
||||
, -- Error(..)
|
||||
) where
|
||||
|
||||
import qualified Language.Elna.AST as AST
|
||||
import Language.Elna.SymbolTable ({-Info(..), ParameterInfo(..), -}SymbolTable)
|
||||
import qualified Language.Elna.Frontend.AST as AST
|
||||
import Language.Elna.Frontend.SymbolTable ({-Info(..), ParameterInfo(..), -}SymbolTable)
|
||||
|
||||
typeAnalysis :: SymbolTable -> AST.Program -> () -- Maybe Error
|
||||
typeAnalysis _globalTable = const () {- either Just (const Nothing)
|
@ -1,4 +1,4 @@
|
||||
module Language.Elna.Types
|
||||
module Language.Elna.Frontend.Types
|
||||
( Type(..)
|
||||
, addressByteSize
|
||||
, booleanType
|
@ -1,95 +1,54 @@
|
||||
module Language.Elna.Intermediate
|
||||
( Operand(..)
|
||||
, Quadruple(..)
|
||||
{- , Label(..) -}
|
||||
, Variable(..)
|
||||
, intermediate
|
||||
module Language.Elna.Glue
|
||||
( glue
|
||||
) where
|
||||
|
||||
import Control.Monad.Trans.State (State, get, modify', runState)
|
||||
import Data.Bifunctor (Bifunctor(..))
|
||||
import Data.Foldable (Foldable(..))
|
||||
import Data.HashMap.Strict (HashMap)
|
||||
import qualified Data.HashMap.Strict as HashMap
|
||||
import Data.Maybe (catMaybes)
|
||||
import Data.Vector (Vector)
|
||||
import qualified Data.Vector as Vector
|
||||
import Data.Int (Int32)
|
||||
import Data.Word (Word32)
|
||||
import Data.Text (Text)
|
||||
import qualified Language.Elna.AST as AST
|
||||
import Language.Elna.SymbolTable (SymbolTable{-, Info(..) -})
|
||||
import Data.Foldable (Foldable(..))
|
||||
import Control.Monad.Trans.State (State, get, modify', runState)
|
||||
import Data.Maybe (catMaybes)
|
||||
import qualified Language.Elna.Frontend.AST as AST
|
||||
import Language.Elna.Backend.Intermediate (Operand(..), Quadruple(..), Variable(..))
|
||||
import Language.Elna.Frontend.SymbolTable (SymbolTable{-, Info(..) -})
|
||||
|
||||
newtype Variable = TempVariable Word32 -- | Variable Text
|
||||
deriving Eq
|
||||
newtype Glue a = Glue
|
||||
{ runGlue :: State Word32 a }
|
||||
|
||||
instance Show Variable
|
||||
instance Functor Glue
|
||||
where
|
||||
-- show (Variable variable) = '$' : Text.unpack variable
|
||||
show (TempVariable variable) = '$' : show variable
|
||||
fmap f (Glue x) = Glue $ f <$> x
|
||||
|
||||
data Operand v
|
||||
= IntOperand Int32
|
||||
| VariableOperand v
|
||||
deriving (Eq, Show)
|
||||
|
||||
data Quadruple v
|
||||
= StartQuadruple
|
||||
| StopQuadruple
|
||||
| ParameterQuadruple (Operand v)
|
||||
| CallQuadruple Text Word32
|
||||
| AddQuadruple (Operand v) (Operand v) v
|
||||
| SubtractionQuadruple (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
|
||||
| NegationQuadruple 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 -}
|
||||
deriving (Eq, Show)
|
||||
|
||||
newtype Intermediate a = Intermediate
|
||||
{ runIntermediate :: State Word32 a }
|
||||
|
||||
instance Functor Intermediate
|
||||
instance Applicative Glue
|
||||
where
|
||||
fmap f (Intermediate x) = Intermediate $ f <$> x
|
||||
pure = Glue . pure
|
||||
(Glue f) <*> (Glue x) = Glue $ f <*> x
|
||||
|
||||
instance Applicative Intermediate
|
||||
instance Monad Glue
|
||||
where
|
||||
pure = Intermediate . pure
|
||||
(Intermediate f) <*> (Intermediate x) = Intermediate $ f <*> x
|
||||
(Glue x) >>= f = Glue $ x >>= (runGlue . f)
|
||||
|
||||
instance Monad Intermediate
|
||||
where
|
||||
(Intermediate x) >>= f = Intermediate $ x >>= (runIntermediate . f)
|
||||
|
||||
intermediate :: SymbolTable -> AST.Program -> HashMap AST.Identifier (Vector (Quadruple Variable))
|
||||
intermediate globalTable
|
||||
glue :: SymbolTable -> AST.Program -> HashMap AST.Identifier (Vector (Quadruple Variable))
|
||||
glue globalTable
|
||||
= fst
|
||||
. flip runState 0
|
||||
. runIntermediate
|
||||
. runGlue
|
||||
. program globalTable
|
||||
|
||||
program
|
||||
:: SymbolTable
|
||||
-> AST.Program
|
||||
-> Intermediate (HashMap AST.Identifier (Vector (Quadruple Variable)))
|
||||
-> Glue (HashMap AST.Identifier (Vector (Quadruple Variable)))
|
||||
program globalTable (AST.Program declarations) = HashMap.fromList . catMaybes
|
||||
<$> traverse (declaration globalTable) declarations
|
||||
|
||||
declaration
|
||||
:: SymbolTable
|
||||
-> AST.Declaration
|
||||
-> Intermediate (Maybe (AST.Identifier, Vector (Quadruple Variable)))
|
||||
-> Glue (Maybe (AST.Identifier, Vector (Quadruple Variable)))
|
||||
declaration globalTable (AST.ProcedureDeclaration procedureName _ _ statements)
|
||||
= Just
|
||||
. (procedureName,)
|
||||
@ -99,7 +58,7 @@ declaration globalTable (AST.ProcedureDeclaration procedureName _ _ statements)
|
||||
<$> traverse (statement globalTable) statements
|
||||
-- declaration (AST.TypeDefinition _ _) accumulator = pure accumulator
|
||||
|
||||
statement :: SymbolTable -> AST.Statement -> Intermediate (Vector (Quadruple Variable))
|
||||
statement :: SymbolTable -> AST.Statement -> Glue (Vector (Quadruple Variable))
|
||||
statement _ AST.EmptyStatement = pure mempty
|
||||
statement localTable (AST.CallStatement (AST.Identifier callName) arguments) = do
|
||||
visitedArguments <- traverse (expression localTable) arguments
|
||||
@ -150,10 +109,10 @@ statement localTable (AST.WhileStatement whileCondition whileStatement) = do
|
||||
statement localTable (AST.CompoundStatement statements) =
|
||||
fold <$> traverse (statement localTable) statements -}
|
||||
|
||||
createTemporary :: Intermediate Variable
|
||||
createTemporary :: Glue Variable
|
||||
createTemporary = do
|
||||
currentCounter <- Intermediate get
|
||||
Intermediate $ modify' (+ 1)
|
||||
currentCounter <- Glue get
|
||||
Glue $ modify' (+ 1)
|
||||
pure $ TempVariable currentCounter
|
||||
|
||||
{-
|
||||
@ -171,10 +130,10 @@ instance Show Label
|
||||
where
|
||||
show (Label label) = '.' : Text.unpack label
|
||||
|
||||
createLabel :: Intermediate Label
|
||||
createLabel :: Glue Label
|
||||
createLabel = do
|
||||
currentCounter <- Intermediate $ gets labelCounter
|
||||
Intermediate $ modify' modifier
|
||||
currentCounter <- Glue $ gets labelCounter
|
||||
Glue $ modify' modifier
|
||||
pure
|
||||
$ Label
|
||||
$ Text.Lazy.toStrict
|
||||
@ -188,7 +147,7 @@ createLabel = do
|
||||
condition
|
||||
:: SymbolTable
|
||||
-> AST.Condition
|
||||
-> Intermediate (Vector Quadruple, Label -> Quadruple)
|
||||
-> Glue (Vector Quadruple, Label -> Quadruple)
|
||||
condition localTable (AST.EqualCondition lhs rhs) = do
|
||||
(lhsOperand, lhsStatements) <- expression localTable lhs
|
||||
(rhsOperand, rhsStatements) <- expression localTable rhs
|
||||
@ -235,7 +194,7 @@ variableAccess
|
||||
-> Maybe Operand
|
||||
-> Type
|
||||
-> Vector Quadruple
|
||||
-> Intermediate (AST.Identifier, Maybe Operand, Vector Quadruple)
|
||||
-> Glue (AST.Identifier, Maybe Operand, Vector Quadruple)
|
||||
variableAccess _ (AST.VariableAccess identifier) accumulatedIndex _ accumulatedStatements =
|
||||
pure (identifier, accumulatedIndex, accumulatedStatements)
|
||||
variableAccess localTable (AST.ArrayAccess access1 index1) Nothing (ArrayType _ baseType) _ = do
|
||||
@ -260,12 +219,20 @@ variableType (AST.VariableAccess identifier) symbolTable
|
||||
variableType (AST.ArrayAccess arrayAccess' _) symbolTable =
|
||||
variableType arrayAccess' symbolTable
|
||||
-}
|
||||
expression :: SymbolTable -> AST.Expression -> Intermediate (Operand Variable, Vector (Quadruple Variable))
|
||||
expression :: SymbolTable -> AST.Expression -> Glue (Operand Variable, Vector (Quadruple Variable))
|
||||
expression localTable = \case
|
||||
(AST.LiteralExpression literal') -> pure (literal literal', mempty)
|
||||
(AST.SumExpression lhs rhs) -> binaryExpression AddQuadruple lhs rhs
|
||||
(AST.SubtractionExpression lhs rhs) ->
|
||||
binaryExpression SubtractionQuadruple lhs rhs
|
||||
(AST.NegationExpression negation) -> do
|
||||
(operand, statements) <- expression localTable negation
|
||||
tempVariable <- createTemporary
|
||||
let negationQuadruple = NegationQuadruple operand tempVariable
|
||||
pure
|
||||
( VariableOperand tempVariable
|
||||
, Vector.snoc statements negationQuadruple
|
||||
)
|
||||
{- (AST.VariableExpression variableExpression) -> do
|
||||
let variableType' = variableType variableExpression localTable
|
||||
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
|
||||
@ -279,14 +246,6 @@ expression localTable = \case
|
||||
( VariableOperand arrayAddress
|
||||
, Vector.snoc statements arrayStatement
|
||||
)
|
||||
(AST.NegationExpression negation) -> do
|
||||
(operand, statements) <- expression localTable negation
|
||||
tempVariable <- createTemporary
|
||||
let negationQuadruple = NegationQuadruple operand tempVariable
|
||||
pure
|
||||
( VariableOperand tempVariable
|
||||
, Vector.snoc statements negationQuadruple
|
||||
)
|
||||
(AST.ProductExpression lhs rhs) ->
|
||||
binaryExpression ProductQuadruple lhs rhs
|
||||
(AST.DivisionExpression lhs rhs) ->
|
@ -1,4 +1,4 @@
|
||||
module Language.Elna.CodeGenerator
|
||||
module Language.Elna.RiscV.CodeGenerator
|
||||
( Statement(..)
|
||||
, generateRiscV
|
||||
, riscVConfiguration
|
||||
@ -11,10 +11,10 @@ import Data.Int (Int32)
|
||||
import Data.Vector (Vector)
|
||||
import qualified Data.Vector as Vector
|
||||
import qualified Data.Text.Encoding as Text.Encoding
|
||||
import Language.Elna.Allocator (MachineConfiguration(..), Store(..))
|
||||
import Language.Elna.Location (Identifier(..))
|
||||
import Language.Elna.Intermediate (Operand(..), Quadruple(..))
|
||||
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.Location (Identifier(..))
|
||||
import Data.Bits (Bits(..))
|
||||
|
||||
data Directive
|
||||
@ -91,7 +91,8 @@ quadruple (AddQuadruple operand1 operand2 (Store register))
|
||||
in Vector.snoc statements
|
||||
$ Instruction
|
||||
$ RiscV.BaseInstruction RiscV.Op
|
||||
$ RiscV.R register RiscV.ADD register operandRegister (RiscV.Funct7 0b0000000)
|
||||
$ RiscV.R register RiscV.ADD register operandRegister
|
||||
$ RiscV.Funct7 0b0000000
|
||||
quadruple (SubtractionQuadruple operand1 operand2 (Store register))
|
||||
| IntOperand immediateOperand1 <- operand1
|
||||
, IntOperand immediateOperand2 <- operand2 =
|
||||
@ -102,7 +103,8 @@ quadruple (SubtractionQuadruple operand1 operand2 (Store register))
|
||||
Store operandRegister2 = variableOperand2
|
||||
in pure $ Instruction
|
||||
$ RiscV.BaseInstruction RiscV.Op
|
||||
$ RiscV.R register RiscV.SUB operandRegister1 operandRegister2 (RiscV.Funct7 0b0100000)
|
||||
$ RiscV.R register RiscV.SUB operandRegister1 operandRegister2
|
||||
$ RiscV.Funct7 0b0100000
|
||||
| IntOperand immediateOperand1 <- operand1
|
||||
, VariableOperand variableOperand2 <- operand2 =
|
||||
let statements1 = lui immediateOperand1 register
|
||||
@ -110,7 +112,8 @@ quadruple (SubtractionQuadruple operand1 operand2 (Store register))
|
||||
in Vector.snoc statements1
|
||||
$ Instruction
|
||||
$ RiscV.BaseInstruction RiscV.Op
|
||||
$ RiscV.R register RiscV.SUB register operandRegister2 (RiscV.Funct7 0b0100000)
|
||||
$ RiscV.R register RiscV.SUB register operandRegister2
|
||||
$ RiscV.Funct7 0b0100000
|
||||
| VariableOperand variableOperand1 <- operand1
|
||||
, IntOperand immediateOperand2 <- operand2 =
|
||||
let statements2 = lui (negate immediateOperand2) register
|
||||
@ -118,7 +121,17 @@ quadruple (SubtractionQuadruple operand1 operand2 (Store register))
|
||||
in Vector.snoc statements2
|
||||
$ Instruction
|
||||
$ RiscV.BaseInstruction RiscV.Op
|
||||
$ RiscV.R register RiscV.ADD register operandRegister1 (RiscV.Funct7 0b0000000)
|
||||
$ RiscV.R register RiscV.ADD register operandRegister1
|
||||
$ RiscV.Funct7 0b0000000
|
||||
quadruple (NegationQuadruple operand1 (Store register))
|
||||
| IntOperand immediateOperand1 <- operand1 = lui (negate immediateOperand1) register
|
||||
| VariableOperand variableOperand1 <- operand1 =
|
||||
let Store operandRegister1 = variableOperand1
|
||||
in Vector.singleton
|
||||
$ Instruction
|
||||
$ RiscV.BaseInstruction RiscV.Op
|
||||
$ RiscV.R register RiscV.SUB RiscV.Zero operandRegister1
|
||||
$ RiscV.Funct7 0b0100000
|
||||
|
||||
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
|
||||
loadImmediateOrRegister (IntOperand intValue) targetRegister =
|
@ -1,5 +1,5 @@
|
||||
-- | Writer assembler to an object file.
|
||||
module Language.Elna.PrinterWriter
|
||||
module Language.Elna.RiscV.ElfWriter
|
||||
( riscv32Elf
|
||||
) where
|
||||
|
||||
@ -44,7 +44,7 @@ import qualified Language.Elna.Architecture.RiscV as RiscV
|
||||
import qualified Data.Text.Encoding as Text.Encoding
|
||||
import Control.Monad.IO.Class (MonadIO(..))
|
||||
import Control.Monad.Trans.State (get)
|
||||
import Language.Elna.CodeGenerator (Statement(..))
|
||||
import Language.Elna.RiscV.CodeGenerator (Statement(..))
|
||||
import qualified Data.HashSet as HashSet
|
||||
import GHC.Records (HasField(..))
|
||||
|
16
src/Main.hs
16
src/Main.hs
@ -3,14 +3,14 @@ module Main
|
||||
) where
|
||||
|
||||
import Language.Elna.CommandLine (CommandLine(..), commandLine, execParser)
|
||||
import Language.Elna.PrinterWriter (riscv32Elf)
|
||||
import Language.Elna.Object.Elf (elfObject)
|
||||
import Language.Elna.Allocator (allocate)
|
||||
import Language.Elna.Parser (programP)
|
||||
import Language.Elna.NameAnalysis (nameAnalysis)
|
||||
import Language.Elna.TypeAnalysis (typeAnalysis)
|
||||
import Language.Elna.Intermediate (intermediate)
|
||||
import Language.Elna.CodeGenerator (generateRiscV, riscVConfiguration)
|
||||
import Language.Elna.Backend.Allocator (allocate)
|
||||
import Language.Elna.Glue (glue)
|
||||
import Language.Elna.Frontend.NameAnalysis (nameAnalysis)
|
||||
import Language.Elna.Frontend.Parser (programP)
|
||||
import Language.Elna.Frontend.TypeAnalysis (typeAnalysis)
|
||||
import Language.Elna.RiscV.CodeGenerator (generateRiscV, riscVConfiguration)
|
||||
import Language.Elna.RiscV.ElfWriter (riscv32Elf)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import System.FilePath (replaceExtension, takeFileName)
|
||||
import Text.Megaparsec (runParser, errorBundlePretty)
|
||||
@ -34,6 +34,6 @@ main = execParser commandLine >>= withCommandLine
|
||||
let _ = typeAnalysis symbolTable program
|
||||
instructions = generateRiscV
|
||||
$ allocate riscVConfiguration
|
||||
$ intermediate symbolTable program
|
||||
$ glue symbolTable program
|
||||
in elfObject output
|
||||
$ riscv32Elf instructions
|
||||
|
1
tests/expectations/parse_negative_numbers.txt
Normal file
1
tests/expectations/parse_negative_numbers.txt
Normal file
@ -0,0 +1 @@
|
||||
-8
|
1
tests/expectations/print_negate.txt
Normal file
1
tests/expectations/print_negate.txt
Normal file
@ -0,0 +1 @@
|
||||
-8
|
3
tests/vm/parse_negative_numbers.elna
Normal file
3
tests/vm/parse_negative_numbers.elna
Normal file
@ -0,0 +1,3 @@
|
||||
proc main() {
|
||||
printi(-8);
|
||||
}
|
3
tests/vm/print_negate.elna
Normal file
3
tests/vm/print_negate.elna
Normal file
@ -0,0 +1,3 @@
|
||||
proc main() {
|
||||
printi(-(8));
|
||||
}
|
Loading…
Reference in New Issue
Block a user