Negate integral expressions

This commit is contained in:
Eugen Wissner 2024-10-02 22:56:15 +02:00
parent cafae5c830
commit fdf56ce9d0
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
18 changed files with 169 additions and 138 deletions

1
TODO
View File

@ -28,4 +28,3 @@
# Other # Other
- Type analysis. - Type analysis.
- Move platform dependent code generation into a submodule.

View File

@ -35,20 +35,21 @@ common warnings
library elna-internal library elna-internal
import: warnings import: warnings
exposed-modules: exposed-modules:
Language.Elna.Allocator
Language.Elna.Architecture.RiscV Language.Elna.Architecture.RiscV
Language.Elna.AST Language.Elna.Backend.Allocator
Language.Elna.CodeGenerator Language.Elna.Backend.Intermediate
Language.Elna.CommandLine Language.Elna.CommandLine
Language.Elna.PrinterWriter Language.Elna.Frontend.AST
Language.Elna.Intermediate 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.Location
Language.Elna.NameAnalysis
Language.Elna.Object.Elf Language.Elna.Object.Elf
Language.Elna.Parser Language.Elna.RiscV.CodeGenerator
Language.Elna.SymbolTable Language.Elna.RiscV.ElfWriter
Language.Elna.TypeAnalysis
Language.Elna.Types
build-depends: build-depends:
exceptions ^>= 0.10, exceptions ^>= 0.10,
hashable ^>= 1.4.3, hashable ^>= 1.4.3,

View File

@ -1,4 +1,4 @@
module Language.Elna.Allocator module Language.Elna.Backend.Allocator
( MachineConfiguration(..) ( MachineConfiguration(..)
, Store(..) , Store(..)
, allocate , allocate
@ -6,7 +6,7 @@ module Language.Elna.Allocator
import Data.HashMap.Strict (HashMap) import Data.HashMap.Strict (HashMap)
import Data.Vector (Vector) import Data.Vector (Vector)
import Language.Elna.Intermediate (Operand(..), Quadruple(..), Variable(..)) import Language.Elna.Backend.Intermediate (Operand(..), Quadruple(..), Variable(..))
import Language.Elna.Location (Identifier(..)) import Language.Elna.Location (Identifier(..))
newtype Store r = Store r newtype Store r = Store r
@ -34,6 +34,8 @@ allocate MachineConfiguration{..} = fmap function
AddQuadruple (operand operand1) (operand operand2) (Store temporaryRegister) AddQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
quadruple (SubtractionQuadruple operand1 operand2 _) = quadruple (SubtractionQuadruple operand1 operand2 _) =
SubtractionQuadruple (operand operand1) (operand operand2) (Store temporaryRegister) SubtractionQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
quadruple (NegationQuadruple operand1 _) =
NegationQuadruple (operand operand1) (Store temporaryRegister)
operand :: Operand Variable -> Operand (Store r) operand :: Operand Variable -> Operand (Store r)
operand (IntOperand x) = IntOperand x operand (IntOperand x) = IntOperand x
operand (VariableOperand _) = VariableOperand (Store temporaryRegister) operand (VariableOperand _) = VariableOperand (Store temporaryRegister)

View 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)

View File

@ -1,4 +1,4 @@
module Language.Elna.AST module Language.Elna.Frontend.AST
( Declaration(..) ( Declaration(..)
, Identifier(..) , Identifier(..)
, Parameter(..) , Parameter(..)
@ -119,8 +119,8 @@ data Expression
= LiteralExpression Literal = LiteralExpression Literal
| SumExpression Expression Expression | SumExpression Expression Expression
| SubtractionExpression Expression Expression | SubtractionExpression Expression Expression
{- | VariableExpression VariableAccess
| NegationExpression Expression | NegationExpression Expression
{- | VariableExpression VariableAccess
| ProductExpression Expression Expression | ProductExpression Expression Expression
| DivisionExpression Expression Expression -} | DivisionExpression Expression Expression -}
deriving Eq deriving Eq
@ -130,8 +130,8 @@ instance Show Expression
show (LiteralExpression literal) = show literal show (LiteralExpression literal) = show literal
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 (NegationExpression negation) = '-' : show negation
{- show (VariableExpression variable) = show variable
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] -}
{- {-

View File

@ -1,13 +1,13 @@
module Language.Elna.NameAnalysis module Language.Elna.Frontend.NameAnalysis
( nameAnalysis ( nameAnalysis
, Error(..) , Error(..)
) where ) where
import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Vector as Vector import qualified Data.Vector as Vector
import qualified Language.Elna.SymbolTable as SymbolTable import qualified Language.Elna.Frontend.AST as AST
import qualified Language.Elna.AST as AST import qualified Language.Elna.Frontend.SymbolTable as SymbolTable
import Language.Elna.SymbolTable import Language.Elna.Frontend.SymbolTable
( SymbolTable ( SymbolTable
, Info(..) , Info(..)
, ParameterInfo(..) , ParameterInfo(..)
@ -15,7 +15,7 @@ import Language.Elna.SymbolTable
import Control.Monad.Trans.Except (Except, runExcept, throwE) import Control.Monad.Trans.Except (Except, runExcept, throwE)
import Data.Functor ((<&>)) import Data.Functor ((<&>))
import Language.Elna.Location (Identifier(..)) import Language.Elna.Location (Identifier(..))
import Language.Elna.Types (Type(..)) import Language.Elna.Frontend.Types (Type(..))
import Data.Foldable (traverse_) import Data.Foldable (traverse_)
import Control.Monad (foldM, unless) import Control.Monad (foldM, unless)
@ -142,10 +142,10 @@ expression globalTable (AST.SumExpression lhs 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 (AST.NegationExpression negation) =
expression globalTable negation expression globalTable negation
{- expression globalTable (AST.VariableExpression variableExpression) =
variableAccess globalTable variableExpression
expression globalTable (AST.ProductExpression lhs rhs) expression globalTable (AST.ProductExpression lhs rhs)
= expression globalTable lhs = expression globalTable lhs
>> expression globalTable rhs >> expression globalTable rhs

View File

@ -1,4 +1,4 @@
module Language.Elna.Parser module Language.Elna.Frontend.Parser
( Parser ( Parser
, programP , programP
) where ) where
@ -8,7 +8,7 @@ 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)
import Language.Elna.AST import Language.Elna.Frontend.AST
( Declaration(..) ( Declaration(..)
, Identifier(..) , Identifier(..)
, Parameter(..) , Parameter(..)
@ -48,7 +48,7 @@ type Parser = Parsec Void Text
literalP :: Parser Literal literalP :: Parser Literal
literalP literalP
= {- HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal) = {- HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal)
<|> -} IntegerLiteral <$> lexeme Lexer.decimal <|> -} IntegerLiteral <$> Lexer.signed space integerP
{- <|> CharacterLiteral <$> lexeme charP {- <|> CharacterLiteral <$> lexeme charP
<|> BooleanLiteral <$> (symbol "true" $> True) <|> BooleanLiteral <$> (symbol "true" $> True)
<|> BooleanLiteral <$> (symbol "false" $> False) <|> BooleanLiteral <$> (symbol "false" $> False)
@ -72,16 +72,16 @@ termP = choice
operatorTable :: [[Operator Parser Expression]] operatorTable :: [[Operator Parser Expression]]
operatorTable = operatorTable =
[{- unaryOperator [ unaryOperator
, factorOperator -- , factorOperator
,-} termOperator , termOperator
] ]
where where
{- unaryOperator = unaryOperator =
[ prefix "-" NegationExpression [ prefix "-" NegationExpression
, prefix "+" id , prefix "+" id
] ]
factorOperator = {- factorOperator =
[ binary "*" ProductExpression [ binary "*" ProductExpression
, binary "/" DivisionExpression , binary "/" DivisionExpression
] -} ] -}
@ -89,7 +89,7 @@ operatorTable =
[ binary "+" SumExpression [ binary "+" SumExpression
, binary "-" SubtractionExpression , binary "-" SubtractionExpression
] ]
-- prefix name f = Prefix (f <$ symbol name) prefix name f = Prefix (f <$ symbol name)
binary name f = InfixL (f <$ symbol name) binary name f = InfixL (f <$ symbol name)
expressionP :: Parser Expression expressionP :: Parser Expression
@ -144,6 +144,9 @@ commaP = void $ symbol ","
semicolonP :: Parser () semicolonP :: Parser ()
semicolonP = void $ symbol ";" semicolonP = void $ symbol ";"
integerP :: Integral a => Parser a
integerP = lexeme Lexer.decimal
identifierP :: Parser Identifier identifierP :: Parser Identifier
identifierP = identifierP =
let wordParser = (:) <$> letterChar <*> many alphaNumChar <?> "identifier" let wordParser = (:) <$> letterChar <*> many alphaNumChar <?> "identifier"
@ -166,7 +169,7 @@ typeExpressionP = arrayTypeExpression
<?> "type expression" <?> "type expression"
where where
arrayTypeExpression = ArrayType arrayTypeExpression = ArrayType
<$> (symbol "array" *> bracketsP (lexeme Lexer.decimal)) <$> (symbol "array" *> bracketsP integerP)
<*> (symbol "of" *> typeExpressionP) <*> (symbol "of" *> typeExpressionP)
procedureDeclarationP :: Parser Declaration procedureDeclarationP :: Parser Declaration

View File

@ -1,4 +1,4 @@
module Language.Elna.SymbolTable module Language.Elna.Frontend.SymbolTable
( SymbolTable ( SymbolTable
, Info(..) , Info(..)
, ParameterInfo(..) , ParameterInfo(..)
@ -22,7 +22,7 @@ import Data.Maybe (isJust)
import Data.Vector (Vector) import Data.Vector (Vector)
import qualified Data.Vector as Vector import qualified Data.Vector as Vector
import Language.Elna.Location (Identifier(..)) import Language.Elna.Location (Identifier(..))
import Language.Elna.Types (Type(..), intType) import Language.Elna.Frontend.Types (Type(..), intType)
import Prelude hiding (lookup) import Prelude hiding (lookup)
data SymbolTable = SymbolTable (Maybe SymbolTable) (HashMap Identifier Info) data SymbolTable = SymbolTable (Maybe SymbolTable) (HashMap Identifier Info)

View File

@ -1,10 +1,10 @@
module Language.Elna.TypeAnalysis module Language.Elna.Frontend.TypeAnalysis
( typeAnalysis ( typeAnalysis
, -- Error(..) , -- Error(..)
) where ) where
import qualified Language.Elna.AST as AST import qualified Language.Elna.Frontend.AST as AST
import Language.Elna.SymbolTable ({-Info(..), ParameterInfo(..), -}SymbolTable) import Language.Elna.Frontend.SymbolTable ({-Info(..), ParameterInfo(..), -}SymbolTable)
typeAnalysis :: SymbolTable -> AST.Program -> () -- Maybe Error typeAnalysis :: SymbolTable -> AST.Program -> () -- Maybe Error
typeAnalysis _globalTable = const () {- either Just (const Nothing) typeAnalysis _globalTable = const () {- either Just (const Nothing)

View File

@ -1,4 +1,4 @@
module Language.Elna.Types module Language.Elna.Frontend.Types
( Type(..) ( Type(..)
, addressByteSize , addressByteSize
, booleanType , booleanType

View File

@ -1,95 +1,54 @@
module Language.Elna.Intermediate module Language.Elna.Glue
( Operand(..) ( glue
, Quadruple(..)
{- , Label(..) -}
, Variable(..)
, intermediate
) where ) where
import Control.Monad.Trans.State (State, get, modify', runState)
import Data.Bifunctor (Bifunctor(..)) import Data.Bifunctor (Bifunctor(..))
import Data.Foldable (Foldable(..))
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.Maybe (catMaybes)
import Data.Vector (Vector) import Data.Vector (Vector)
import qualified Data.Vector as Vector import qualified Data.Vector as Vector
import Data.Int (Int32)
import Data.Word (Word32) import Data.Word (Word32)
import Data.Text (Text) import qualified Language.Elna.Frontend.AST as AST
import qualified Language.Elna.AST as AST import Language.Elna.Backend.Intermediate (Operand(..), Quadruple(..), Variable(..))
import Language.Elna.SymbolTable (SymbolTable{-, Info(..) -}) import Language.Elna.Frontend.SymbolTable (SymbolTable{-, Info(..) -})
import Data.Foldable (Foldable(..))
import Control.Monad.Trans.State (State, get, modify', runState)
import Data.Maybe (catMaybes)
newtype Variable = TempVariable Word32 -- | Variable Text newtype Glue a = Glue
deriving Eq { runGlue :: State Word32 a }
instance Show Variable instance Functor Glue
where where
-- show (Variable variable) = '$' : Text.unpack variable fmap f (Glue x) = Glue $ f <$> x
show (TempVariable variable) = '$' : show variable
data Operand v instance Applicative Glue
= 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
where 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 where
pure = Intermediate . pure (Glue x) >>= f = Glue $ x >>= (runGlue . f)
(Intermediate f) <*> (Intermediate x) = Intermediate $ f <*> x
instance Monad Intermediate glue :: SymbolTable -> AST.Program -> HashMap AST.Identifier (Vector (Quadruple Variable))
where glue globalTable
(Intermediate x) >>= f = Intermediate $ x >>= (runIntermediate . f)
intermediate :: SymbolTable -> AST.Program -> HashMap AST.Identifier (Vector (Quadruple Variable))
intermediate globalTable
= fst = fst
. flip runState 0 . flip runState 0
. runIntermediate . runGlue
. program globalTable . program globalTable
program program
:: SymbolTable :: SymbolTable
-> AST.Program -> AST.Program
-> Intermediate (HashMap AST.Identifier (Vector (Quadruple Variable))) -> Glue (HashMap AST.Identifier (Vector (Quadruple Variable)))
program globalTable (AST.Program declarations) = HashMap.fromList . catMaybes program globalTable (AST.Program declarations) = HashMap.fromList . catMaybes
<$> traverse (declaration globalTable) declarations <$> traverse (declaration globalTable) declarations
declaration declaration
:: SymbolTable :: SymbolTable
-> AST.Declaration -> AST.Declaration
-> Intermediate (Maybe (AST.Identifier, Vector (Quadruple Variable))) -> Glue (Maybe (AST.Identifier, Vector (Quadruple Variable)))
declaration globalTable (AST.ProcedureDeclaration procedureName _ _ statements) declaration globalTable (AST.ProcedureDeclaration procedureName _ _ statements)
= Just = Just
. (procedureName,) . (procedureName,)
@ -99,7 +58,7 @@ declaration globalTable (AST.ProcedureDeclaration procedureName _ _ statements)
<$> traverse (statement globalTable) statements <$> traverse (statement globalTable) statements
-- declaration (AST.TypeDefinition _ _) accumulator = pure accumulator -- 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 _ AST.EmptyStatement = pure mempty
statement localTable (AST.CallStatement (AST.Identifier callName) arguments) = do statement localTable (AST.CallStatement (AST.Identifier callName) arguments) = do
visitedArguments <- traverse (expression localTable) arguments visitedArguments <- traverse (expression localTable) arguments
@ -150,10 +109,10 @@ 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 :: Glue Variable
createTemporary = do createTemporary = do
currentCounter <- Intermediate get currentCounter <- Glue get
Intermediate $ modify' (+ 1) Glue $ modify' (+ 1)
pure $ TempVariable currentCounter pure $ TempVariable currentCounter
{- {-
@ -171,10 +130,10 @@ instance Show Label
where where
show (Label label) = '.' : Text.unpack label show (Label label) = '.' : Text.unpack label
createLabel :: Intermediate Label createLabel :: Glue Label
createLabel = do createLabel = do
currentCounter <- Intermediate $ gets labelCounter currentCounter <- Glue $ gets labelCounter
Intermediate $ modify' modifier Glue $ modify' modifier
pure pure
$ Label $ Label
$ Text.Lazy.toStrict $ Text.Lazy.toStrict
@ -188,7 +147,7 @@ createLabel = do
condition condition
:: SymbolTable :: SymbolTable
-> AST.Condition -> AST.Condition
-> Intermediate (Vector Quadruple, Label -> Quadruple) -> Glue (Vector Quadruple, Label -> Quadruple)
condition localTable (AST.EqualCondition lhs rhs) = do condition localTable (AST.EqualCondition lhs rhs) = do
(lhsOperand, lhsStatements) <- expression localTable lhs (lhsOperand, lhsStatements) <- expression localTable lhs
(rhsOperand, rhsStatements) <- expression localTable rhs (rhsOperand, rhsStatements) <- expression localTable rhs
@ -235,7 +194,7 @@ variableAccess
-> Maybe Operand -> Maybe Operand
-> Type -> Type
-> Vector Quadruple -> Vector Quadruple
-> Intermediate (AST.Identifier, Maybe Operand, Vector Quadruple) -> Glue (AST.Identifier, Maybe Operand, Vector Quadruple)
variableAccess _ (AST.VariableAccess identifier) accumulatedIndex _ accumulatedStatements = variableAccess _ (AST.VariableAccess identifier) accumulatedIndex _ accumulatedStatements =
pure (identifier, accumulatedIndex, accumulatedStatements) pure (identifier, accumulatedIndex, accumulatedStatements)
variableAccess localTable (AST.ArrayAccess access1 index1) Nothing (ArrayType _ baseType) _ = do 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 (AST.ArrayAccess arrayAccess' _) symbolTable =
variableType 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 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.SumExpression lhs rhs) -> binaryExpression AddQuadruple lhs rhs
(AST.SubtractionExpression lhs rhs) -> (AST.SubtractionExpression lhs rhs) ->
binaryExpression SubtractionQuadruple 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 {- (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
@ -279,14 +246,6 @@ expression localTable = \case
( VariableOperand arrayAddress ( VariableOperand arrayAddress
, Vector.snoc statements arrayStatement , 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) -> (AST.ProductExpression lhs rhs) ->
binaryExpression ProductQuadruple lhs rhs binaryExpression ProductQuadruple lhs rhs
(AST.DivisionExpression lhs rhs) -> (AST.DivisionExpression lhs rhs) ->

View File

@ -1,4 +1,4 @@
module Language.Elna.CodeGenerator module Language.Elna.RiscV.CodeGenerator
( Statement(..) ( Statement(..)
, generateRiscV , generateRiscV
, riscVConfiguration , riscVConfiguration
@ -11,10 +11,10 @@ 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.Allocator (MachineConfiguration(..), Store(..))
import Language.Elna.Location (Identifier(..))
import Language.Elna.Intermediate (Operand(..), Quadruple(..))
import qualified Language.Elna.Architecture.RiscV as RiscV 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(..)) import Data.Bits (Bits(..))
data Directive data Directive
@ -91,7 +91,8 @@ quadruple (AddQuadruple operand1 operand2 (Store register))
in Vector.snoc statements in Vector.snoc statements
$ Instruction $ Instruction
$ RiscV.BaseInstruction RiscV.Op $ 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)) quadruple (SubtractionQuadruple operand1 operand2 (Store register))
| IntOperand immediateOperand1 <- operand1 | IntOperand immediateOperand1 <- operand1
, IntOperand immediateOperand2 <- operand2 = , IntOperand immediateOperand2 <- operand2 =
@ -102,7 +103,8 @@ quadruple (SubtractionQuadruple operand1 operand2 (Store register))
Store operandRegister2 = variableOperand2 Store operandRegister2 = variableOperand2
in pure $ Instruction in pure $ Instruction
$ RiscV.BaseInstruction RiscV.Op $ 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 | IntOperand immediateOperand1 <- operand1
, VariableOperand variableOperand2 <- operand2 = , VariableOperand variableOperand2 <- operand2 =
let statements1 = lui immediateOperand1 register let statements1 = lui immediateOperand1 register
@ -110,7 +112,8 @@ quadruple (SubtractionQuadruple operand1 operand2 (Store register))
in Vector.snoc statements1 in Vector.snoc statements1
$ Instruction $ Instruction
$ RiscV.BaseInstruction RiscV.Op $ 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 | VariableOperand variableOperand1 <- operand1
, IntOperand immediateOperand2 <- operand2 = , IntOperand immediateOperand2 <- operand2 =
let statements2 = lui (negate immediateOperand2) register let statements2 = lui (negate immediateOperand2) register
@ -118,7 +121,17 @@ quadruple (SubtractionQuadruple operand1 operand2 (Store register))
in Vector.snoc statements2 in Vector.snoc statements2
$ Instruction $ Instruction
$ RiscV.BaseInstruction RiscV.Op $ 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 :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
loadImmediateOrRegister (IntOperand intValue) targetRegister = loadImmediateOrRegister (IntOperand intValue) targetRegister =

View File

@ -1,5 +1,5 @@
-- | Writer assembler to an object file. -- | Writer assembler to an object file.
module Language.Elna.PrinterWriter module Language.Elna.RiscV.ElfWriter
( riscv32Elf ( riscv32Elf
) where ) where
@ -44,7 +44,7 @@ import qualified Language.Elna.Architecture.RiscV as RiscV
import qualified Data.Text.Encoding as Text.Encoding import qualified Data.Text.Encoding as Text.Encoding
import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.State (get) import Control.Monad.Trans.State (get)
import Language.Elna.CodeGenerator (Statement(..)) import Language.Elna.RiscV.CodeGenerator (Statement(..))
import qualified Data.HashSet as HashSet import qualified Data.HashSet as HashSet
import GHC.Records (HasField(..)) import GHC.Records (HasField(..))

View File

@ -3,14 +3,14 @@ module Main
) where ) where
import Language.Elna.CommandLine (CommandLine(..), commandLine, execParser) import Language.Elna.CommandLine (CommandLine(..), commandLine, execParser)
import Language.Elna.PrinterWriter (riscv32Elf)
import Language.Elna.Object.Elf (elfObject) import Language.Elna.Object.Elf (elfObject)
import Language.Elna.Allocator (allocate) import Language.Elna.Backend.Allocator (allocate)
import Language.Elna.Parser (programP) import Language.Elna.Glue (glue)
import Language.Elna.NameAnalysis (nameAnalysis) import Language.Elna.Frontend.NameAnalysis (nameAnalysis)
import Language.Elna.TypeAnalysis (typeAnalysis) import Language.Elna.Frontend.Parser (programP)
import Language.Elna.Intermediate (intermediate) import Language.Elna.Frontend.TypeAnalysis (typeAnalysis)
import Language.Elna.CodeGenerator (generateRiscV, riscVConfiguration) import Language.Elna.RiscV.CodeGenerator (generateRiscV, riscVConfiguration)
import Language.Elna.RiscV.ElfWriter (riscv32Elf)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import System.FilePath (replaceExtension, takeFileName) import System.FilePath (replaceExtension, takeFileName)
import Text.Megaparsec (runParser, errorBundlePretty) import Text.Megaparsec (runParser, errorBundlePretty)
@ -34,6 +34,6 @@ main = execParser commandLine >>= withCommandLine
let _ = typeAnalysis symbolTable program let _ = typeAnalysis symbolTable program
instructions = generateRiscV instructions = generateRiscV
$ allocate riscVConfiguration $ allocate riscVConfiguration
$ intermediate symbolTable program $ glue symbolTable program
in elfObject output in elfObject output
$ riscv32Elf instructions $ riscv32Elf instructions

View File

@ -0,0 +1 @@
-8

View File

@ -0,0 +1 @@
-8

View File

@ -0,0 +1,3 @@
proc main() {
printi(-8);
}

View File

@ -0,0 +1,3 @@
proc main() {
printi(-(8));
}