summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2024-10-02 22:56:15 +0200
committerEugen Wissner <belka@caraus.de>2024-10-02 22:56:15 +0200
commitfdf56ce9d0de459dc5bd65537847ded7b02ad5c2 (patch)
tree01c13db713bfcbe3252c83d1b557ebf9fdb2b11e
parentcafae5c8307489e3c8a5bf3a5f9c0f0797b0ca6c (diff)
downloadelna-fdf56ce9d0de459dc5bd65537847ded7b02ad5c2.tar.gz
Negate integral expressions
-rw-r--r--TODO1
-rw-r--r--elna.cabal21
-rw-r--r--lib/Language/Elna/Backend/Allocator.hs (renamed from lib/Language/Elna/Allocator.hs)6
-rw-r--r--lib/Language/Elna/Backend/Intermediate.hs46
-rw-r--r--lib/Language/Elna/Frontend/AST.hs (renamed from lib/Language/Elna/AST.hs)6
-rw-r--r--lib/Language/Elna/Frontend/NameAnalysis.hs (renamed from lib/Language/Elna/NameAnalysis.hs)14
-rw-r--r--lib/Language/Elna/Frontend/Parser.hs (renamed from lib/Language/Elna/Parser.hs)23
-rw-r--r--lib/Language/Elna/Frontend/SymbolTable.hs (renamed from lib/Language/Elna/SymbolTable.hs)4
-rw-r--r--lib/Language/Elna/Frontend/TypeAnalysis.hs (renamed from lib/Language/Elna/TypeAnalysis.hs)6
-rw-r--r--lib/Language/Elna/Frontend/Types.hs (renamed from lib/Language/Elna/Types.hs)2
-rw-r--r--lib/Language/Elna/Glue.hs (renamed from lib/Language/Elna/Intermediate.hs)121
-rw-r--r--lib/Language/Elna/RiscV/CodeGenerator.hs (renamed from lib/Language/Elna/CodeGenerator.hs)29
-rw-r--r--lib/Language/Elna/RiscV/ElfWriter.hs (renamed from lib/Language/Elna/PrinterWriter.hs)4
-rw-r--r--src/Main.hs16
-rw-r--r--tests/expectations/parse_negative_numbers.txt1
-rw-r--r--tests/expectations/print_negate.txt1
-rw-r--r--tests/vm/parse_negative_numbers.elna3
-rw-r--r--tests/vm/print_negate.elna3
18 files changed, 169 insertions, 138 deletions
diff --git a/TODO b/TODO
index 2d6b5c3..6327ff2 100644
--- a/TODO
+++ b/TODO
@@ -28,4 +28,3 @@
# Other
- Type analysis.
-- Move platform dependent code generation into a submodule.
diff --git a/elna.cabal b/elna.cabal
index 2c80ea5..4f3fc8e 100644
--- a/elna.cabal
+++ b/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,
diff --git a/lib/Language/Elna/Allocator.hs b/lib/Language/Elna/Backend/Allocator.hs
index 3b32de4..9ad849e 100644
--- a/lib/Language/Elna/Allocator.hs
+++ b/lib/Language/Elna/Backend/Allocator.hs
@@ -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)
diff --git a/lib/Language/Elna/Backend/Intermediate.hs b/lib/Language/Elna/Backend/Intermediate.hs
new file mode 100644
index 0000000..01a026b
--- /dev/null
+++ b/lib/Language/Elna/Backend/Intermediate.hs
@@ -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)
diff --git a/lib/Language/Elna/AST.hs b/lib/Language/Elna/Frontend/AST.hs
index 4861318..738ddcc 100644
--- a/lib/Language/Elna/AST.hs
+++ b/lib/Language/Elna/Frontend/AST.hs
@@ -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] -}
{-
diff --git a/lib/Language/Elna/NameAnalysis.hs b/lib/Language/Elna/Frontend/NameAnalysis.hs
index 10045e9..2915331 100644
--- a/lib/Language/Elna/NameAnalysis.hs
+++ b/lib/Language/Elna/Frontend/NameAnalysis.hs
@@ -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
diff --git a/lib/Language/Elna/Parser.hs b/lib/Language/Elna/Frontend/Parser.hs
index 3c98fff..4093f25 100644
--- a/lib/Language/Elna/Parser.hs
+++ b/lib/Language/Elna/Frontend/Parser.hs
@@ -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
diff --git a/lib/Language/Elna/SymbolTable.hs b/lib/Language/Elna/Frontend/SymbolTable.hs
index 97d9621..9ace33f 100644
--- a/lib/Language/Elna/SymbolTable.hs
+++ b/lib/Language/Elna/Frontend/SymbolTable.hs
@@ -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)
diff --git a/lib/Language/Elna/TypeAnalysis.hs b/lib/Language/Elna/Frontend/TypeAnalysis.hs
index ac61b62..7d0b050 100644
--- a/lib/Language/Elna/TypeAnalysis.hs
+++ b/lib/Language/Elna/Frontend/TypeAnalysis.hs
@@ -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)
diff --git a/lib/Language/Elna/Types.hs b/lib/Language/Elna/Frontend/Types.hs
index ee76ec8..a3cc730 100644
--- a/lib/Language/Elna/Types.hs
+++ b/lib/Language/Elna/Frontend/Types.hs
@@ -1,4 +1,4 @@
-module Language.Elna.Types
+module Language.Elna.Frontend.Types
( Type(..)
, addressByteSize
, booleanType
diff --git a/lib/Language/Elna/Intermediate.hs b/lib/Language/Elna/Glue.hs
index 32c951e..2313b2b 100644
--- a/lib/Language/Elna/Intermediate.hs
+++ b/lib/Language/Elna/Glue.hs
@@ -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)
-
-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)
+import qualified Language.Elna.Frontend.AST as AST
+import Language.Elna.Backend.Intermediate (Operand(..), Quadruple(..), Variable(..))
+import Language.Elna.Frontend.SymbolTable (SymbolTable{-, Info(..) -})
-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 Glue a = Glue
+ { runGlue :: State Word32 a }
-newtype Intermediate a = Intermediate
- { runIntermediate :: State Word32 a }
-
-instance Functor Intermediate
+instance Functor Glue
where
- fmap f (Intermediate x) = Intermediate $ f <$> x
+ fmap f (Glue x) = Glue $ f <$> x
-instance Applicative Intermediate
+instance Applicative Glue
where
- pure = Intermediate . pure
- (Intermediate f) <*> (Intermediate x) = Intermediate $ f <*> x
+ pure = Glue . pure
+ (Glue f) <*> (Glue x) = Glue $ f <*> x
-instance Monad Intermediate
+instance Monad Glue
where
- (Intermediate x) >>= f = Intermediate $ x >>= (runIntermediate . f)
+ (Glue x) >>= f = Glue $ x >>= (runGlue . 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) ->
diff --git a/lib/Language/Elna/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs
index a561cb8..d20488c 100644
--- a/lib/Language/Elna/CodeGenerator.hs
+++ b/lib/Language/Elna/RiscV/CodeGenerator.hs
@@ -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 =
diff --git a/lib/Language/Elna/PrinterWriter.hs b/lib/Language/Elna/RiscV/ElfWriter.hs
index 40b60de..a83aca3 100644
--- a/lib/Language/Elna/PrinterWriter.hs
+++ b/lib/Language/Elna/RiscV/ElfWriter.hs
@@ -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(..))
diff --git a/src/Main.hs b/src/Main.hs
index 456c5ad..e5a217f 100644
--- a/src/Main.hs
+++ b/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
diff --git a/tests/expectations/parse_negative_numbers.txt b/tests/expectations/parse_negative_numbers.txt
new file mode 100644
index 0000000..de71f88
--- /dev/null
+++ b/tests/expectations/parse_negative_numbers.txt
@@ -0,0 +1 @@
+-8
diff --git a/tests/expectations/print_negate.txt b/tests/expectations/print_negate.txt
new file mode 100644
index 0000000..de71f88
--- /dev/null
+++ b/tests/expectations/print_negate.txt
@@ -0,0 +1 @@
+-8
diff --git a/tests/vm/parse_negative_numbers.elna b/tests/vm/parse_negative_numbers.elna
new file mode 100644
index 0000000..ce5d797
--- /dev/null
+++ b/tests/vm/parse_negative_numbers.elna
@@ -0,0 +1,3 @@
+proc main() {
+ printi(-8);
+}
diff --git a/tests/vm/print_negate.elna b/tests/vm/print_negate.elna
new file mode 100644
index 0000000..791bc81
--- /dev/null
+++ b/tests/vm/print_negate.elna
@@ -0,0 +1,3 @@
+proc main() {
+ printi(-(8));
+}