Negate integral expressions
This commit is contained in:
parent
cafae5c830
commit
fdf56ce9d0
1
TODO
1
TODO
@ -28,4 +28,3 @@
|
|||||||
# Other
|
# Other
|
||||||
|
|
||||||
- Type analysis.
|
- 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
|
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,
|
||||||
|
@ -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)
|
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(..)
|
( 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] -}
|
||||||
{-
|
{-
|
@ -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
|
@ -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
|
@ -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)
|
@ -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)
|
@ -1,4 +1,4 @@
|
|||||||
module Language.Elna.Types
|
module Language.Elna.Frontend.Types
|
||||||
( Type(..)
|
( Type(..)
|
||||||
, addressByteSize
|
, addressByteSize
|
||||||
, booleanType
|
, booleanType
|
@ -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) ->
|
@ -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 =
|
@ -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(..))
|
||||||
|
|
16
src/Main.hs
16
src/Main.hs
@ -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
|
||||||
|
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