summaryrefslogtreecommitdiff
path: root/lib/Language/Elna
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Language/Elna')
-rw-r--r--lib/Language/Elna/Backend/Allocator.hs2
-rw-r--r--lib/Language/Elna/Backend/Intermediate.hs2
-rw-r--r--lib/Language/Elna/Frontend/AST.hs31
-rw-r--r--lib/Language/Elna/Frontend/NameAnalysis.hs8
-rw-r--r--lib/Language/Elna/Frontend/Parser.hs23
-rw-r--r--lib/Language/Elna/Frontend/SymbolTable.hs15
-rw-r--r--lib/Language/Elna/Glue.hs15
-rw-r--r--lib/Language/Elna/RiscV/CodeGenerator.hs26
8 files changed, 76 insertions, 46 deletions
diff --git a/lib/Language/Elna/Backend/Allocator.hs b/lib/Language/Elna/Backend/Allocator.hs
index 9ad849e..1ffc85d 100644
--- a/lib/Language/Elna/Backend/Allocator.hs
+++ b/lib/Language/Elna/Backend/Allocator.hs
@@ -36,6 +36,8 @@ allocate MachineConfiguration{..} = fmap function
SubtractionQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
quadruple (NegationQuadruple operand1 _) =
NegationQuadruple (operand operand1) (Store temporaryRegister)
+ quadruple (ProductQuadruple operand1 operand2 _) =
+ ProductQuadruple (operand operand1) (operand operand2) (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
index 01a026b..e7c66cf 100644
--- a/lib/Language/Elna/Backend/Intermediate.hs
+++ b/lib/Language/Elna/Backend/Intermediate.hs
@@ -30,11 +30,11 @@ data Quadruple v
| AddQuadruple (Operand v) (Operand v) v
| SubtractionQuadruple (Operand v) (Operand v) v
| NegationQuadruple (Operand v) v
+ | ProductQuadruple (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
| EqualQuadruple Operand Operand Label
| NonEqualQuadruple Operand Operand Label
diff --git a/lib/Language/Elna/Frontend/AST.hs b/lib/Language/Elna/Frontend/AST.hs
index 738ddcc..4c1c20b 100644
--- a/lib/Language/Elna/Frontend/AST.hs
+++ b/lib/Language/Elna/Frontend/AST.hs
@@ -12,10 +12,12 @@ module Language.Elna.Frontend.AST
, Literal(..)
) where
+import Data.Char (chr)
import Data.Int (Int32)
import Data.List (intercalate)
-import Data.Word ({-Word16, -}Word32)
+import Data.Word (Word8, Word32)
import Language.Elna.Location (Identifier(..), showArrayType)
+import Numeric (showHex)
newtype Program = Program [Declaration]
deriving Eq
@@ -67,8 +69,8 @@ data Statement
= EmptyStatement
{-| AssignmentStatement VariableAccess Expression
| IfStatement Condition Statement (Maybe Statement)
- | WhileStatement Condition Statement
- | CompoundStatement [Statement]-}
+ | WhileStatement Condition Statement -}
+ | CompoundStatement [Statement]
| CallStatement Identifier [Expression]
deriving Eq
@@ -83,9 +85,9 @@ instance Show Statement
, maybe "" ((<> " else ") . show) else'
]
show (WhileStatement expression statement) =
- concat ["while (", show expression, ") ", show statement, ";"]
+ concat ["while (", show expression, ") ", show statement, ";"]-}
show (CompoundStatement statements) =
- concat ["{\n", unlines (show <$> statements), " }"]-}
+ concat ["{\n", unlines (show <$> statements), " }"]
show (CallStatement name parameters) = show name <> "("
<> intercalate ", " (show <$> parameters) <> ")"
@@ -93,22 +95,18 @@ data VariableDeclaration =
VariableDeclaration Identifier TypeExpression
deriving Eq
-newtype Literal
+data Literal
= IntegerLiteral Int32
- {- | HexadecimalLiteral Int32
- | CharacterLiteral Word16
- | BooleanLiteral Bool -}
+ | HexadecimalLiteral Int32
+ | CharacterLiteral Word8
deriving Eq
instance Show Literal
where
show (IntegerLiteral integer) = show integer
- {- show (HexadecimalLiteral integer) = '0' : 'x' : showHex integer ""
+ show (HexadecimalLiteral integer) = '0' : 'x' : showHex integer ""
show (CharacterLiteral character) =
'\'' : chr (fromEnum character) : ['\'']
- show (BooleanLiteral boolean)
- | boolean = "true"
- | otherwise = "false" -}
instance Show VariableDeclaration
where
@@ -120,8 +118,8 @@ data Expression
| SumExpression Expression Expression
| SubtractionExpression Expression Expression
| NegationExpression Expression
-{- | VariableExpression VariableAccess
| ProductExpression Expression Expression
+{- | VariableExpression VariableAccess
| DivisionExpression Expression Expression -}
deriving Eq
@@ -131,13 +129,10 @@ instance Show Expression
show (SumExpression lhs rhs) = concat [show lhs, " + ", show rhs]
show (SubtractionExpression lhs rhs) = concat [show lhs, " - ", show rhs]
show (NegationExpression negation) = '-' : show negation
- {- show (VariableExpression variable) = show variable
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
+ {- show (VariableExpression variable) = show variable
show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs] -}
{-
-import Data.Char (chr)
-import Numeric (showHex)
-
data VariableAccess
= VariableAccess Identifier
| ArrayAccess VariableAccess Expression
diff --git a/lib/Language/Elna/Frontend/NameAnalysis.hs b/lib/Language/Elna/Frontend/NameAnalysis.hs
index 2915331..dc39826 100644
--- a/lib/Language/Elna/Frontend/NameAnalysis.hs
+++ b/lib/Language/Elna/Frontend/NameAnalysis.hs
@@ -144,11 +144,11 @@ expression globalTable (AST.SubtractionExpression lhs rhs)
>> expression globalTable rhs
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
+{- expression globalTable (AST.VariableExpression variableExpression) =
+ variableAccess globalTable variableExpression
expression globalTable (AST.DivisionExpression lhs rhs)
= expression globalTable lhs
>> expression globalTable rhs
@@ -158,6 +158,8 @@ statement _ AST.EmptyStatement = pure ()
statement globalTable (AST.CallStatement name arguments)
= checkSymbol globalTable name
>> traverse_ (expression globalTable) arguments
+statement globalTable (AST.CompoundStatement statements) =
+ traverse_ (statement globalTable) statements
{- statement globalTable (AST.AssignmentStatement lvalue rvalue)
= variableAccess globalTable lvalue
>> expression globalTable rvalue
@@ -168,8 +170,6 @@ statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement)
statement globalTable (AST.WhileStatement whileCondition loop)
= condition globalTable whileCondition
>> statement globalTable loop
-statement globalTable (AST.CompoundStatement statements) =
- traverse_ (statement globalTable) statements
variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
diff --git a/lib/Language/Elna/Frontend/Parser.hs b/lib/Language/Elna/Frontend/Parser.hs
index 4093f25..75f359e 100644
--- a/lib/Language/Elna/Frontend/Parser.hs
+++ b/lib/Language/Elna/Frontend/Parser.hs
@@ -34,27 +34,24 @@ import Text.Megaparsec
import qualified Text.Megaparsec.Char.Lexer as Lexer
import Text.Megaparsec.Char
( alphaNumChar
--- , char
+ , char
, letterChar
, space1
--- , string
+ , string
)
import Control.Applicative (Alternative(..))
import Data.Maybe (isJust)
--- import Data.Functor (($>))
type Parser = Parsec Void Text
literalP :: Parser Literal
literalP
- = {- HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal)
- <|> -} IntegerLiteral <$> Lexer.signed space integerP
- {- <|> CharacterLiteral <$> lexeme charP
- <|> BooleanLiteral <$> (symbol "true" $> True)
- <|> BooleanLiteral <$> (symbol "false" $> False)
+ = HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal)
+ <|> IntegerLiteral <$> Lexer.signed space integerP
+ <|> CharacterLiteral <$> lexeme charP
where
charP = fromIntegral . fromEnum
- <$> between (char '\'') (char '\'') Lexer.charLiteral -}
+ <$> between (char '\'') (char '\'') Lexer.charLiteral
{-
typeDefinitionP :: Parser Declaration
typeDefinitionP = TypeDefinition
@@ -73,7 +70,7 @@ termP = choice
operatorTable :: [[Operator Parser Expression]]
operatorTable =
[ unaryOperator
- -- , factorOperator
+ , factorOperator
, termOperator
]
where
@@ -81,10 +78,10 @@ operatorTable =
[ prefix "-" NegationExpression
, prefix "+" id
]
- {- factorOperator =
+ factorOperator =
[ binary "*" ProductExpression
- , binary "/" DivisionExpression
- ] -}
+ -- , binary "/" DivisionExpression
+ ]
termOperator =
[ binary "+" SumExpression
, binary "-" SubtractionExpression
diff --git a/lib/Language/Elna/Frontend/SymbolTable.hs b/lib/Language/Elna/Frontend/SymbolTable.hs
index 9ace33f..e90a942 100644
--- a/lib/Language/Elna/Frontend/SymbolTable.hs
+++ b/lib/Language/Elna/Frontend/SymbolTable.hs
@@ -40,9 +40,22 @@ scope parent (SymbolTable _ mappings) = SymbolTable (Just parent) mappings
builtInSymbolTable :: SymbolTable
builtInSymbolTable = SymbolTable Nothing $ HashMap.fromList
- [ ("printi", ProcedureInfo empty Vector.empty)
+ [ ("printi", ProcedureInfo empty (Vector.singleton printiX))
+ , ("printc", ProcedureInfo empty (Vector.singleton printcI))
+ , ("exit", ProcedureInfo empty Vector.empty)
, ("int", TypeInfo intType)
]
+ where
+ printiX = ParameterInfo
+ { name = "x"
+ , type' = intType
+ , isReferenceParameter = False
+ }
+ printcI = ParameterInfo
+ { name = "i"
+ , type' = intType
+ , isReferenceParameter = False
+ }
toMap :: SymbolTable -> HashMap Identifier Info
toMap (SymbolTable _ map') = map'
diff --git a/lib/Language/Elna/Glue.hs b/lib/Language/Elna/Glue.hs
index 2313b2b..85c8401 100644
--- a/lib/Language/Elna/Glue.hs
+++ b/lib/Language/Elna/Glue.hs
@@ -70,6 +70,8 @@ statement localTable (AST.CallStatement (AST.Identifier callName) arguments) = d
$ CallQuadruple callName
$ fromIntegral
$ Vector.length argumentStatements
+statement localTable (AST.CompoundStatement statements) =
+ fold <$> traverse (statement localTable) statements
{- statement localTable (AST.AssignmentStatement variableAccess' assignee) = do
(rhsOperand, rhsStatements) <- expression localTable assignee
let variableType' = variableType variableAccess' localTable
@@ -105,9 +107,7 @@ statement localTable (AST.WhileStatement whileCondition whileStatement) = do
<> conditionStatements
<> Vector.fromList [jumpConstructor startLabel, GoToQuadruple endLabel, LabelQuadruple startLabel]
<> whileStatements
- <> Vector.fromList [GoToQuadruple conditionLabel, LabelQuadruple endLabel]
-statement localTable (AST.CompoundStatement statements) =
- fold <$> traverse (statement localTable) statements -}
+ <> Vector.fromList [GoToQuadruple conditionLabel, LabelQuadruple endLabel] -}
createTemporary :: Glue Variable
createTemporary = do
@@ -233,6 +233,8 @@ expression localTable = \case
( VariableOperand tempVariable
, Vector.snoc statements negationQuadruple
)
+ (AST.ProductExpression lhs rhs) ->
+ binaryExpression ProductQuadruple lhs rhs
{- (AST.VariableExpression variableExpression) -> do
let variableType' = variableType variableExpression localTable
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
@@ -246,8 +248,6 @@ expression localTable = \case
( VariableOperand arrayAddress
, Vector.snoc statements arrayStatement
)
- (AST.ProductExpression lhs rhs) ->
- binaryExpression ProductQuadruple lhs rhs
(AST.DivisionExpression lhs rhs) ->
binaryExpression DivisionQuadruple lhs rhs -}
where
@@ -263,8 +263,5 @@ expression localTable = \case
literal :: AST.Literal -> Operand Variable
literal (AST.IntegerLiteral integer) = IntOperand integer
-{-literal (AST.HexadecimalLiteral integer) = IntOperand integer
+literal (AST.HexadecimalLiteral integer) = IntOperand integer
literal (AST.CharacterLiteral character) = IntOperand $ fromIntegral character
-literal (AST.BooleanLiteral boolean)
- | boolean = IntOperand 1
- | otherwise = IntOperand 0 -}
diff --git a/lib/Language/Elna/RiscV/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs
index d20488c..439f99c 100644
--- a/lib/Language/Elna/RiscV/CodeGenerator.hs
+++ b/lib/Language/Elna/RiscV/CodeGenerator.hs
@@ -132,6 +132,32 @@ quadruple (NegationQuadruple operand1 (Store register))
$ RiscV.BaseInstruction RiscV.Op
$ RiscV.R register RiscV.SUB RiscV.Zero operandRegister1
$ RiscV.Funct7 0b0100000
+quadruple (ProductQuadruple operand1 operand2 (Store register))
+ | IntOperand immediateOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ lui (immediateOperand1 * immediateOperand2) register
+ | VariableOperand variableOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let Store operandRegister1 = variableOperand1
+ Store operandRegister2 = variableOperand2
+ in pure $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.MUL operandRegister1 operandRegister2 (RiscV.Funct7 0b0000001)
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ multiplyImmediateRegister variableOperand1 immediateOperand2
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ multiplyImmediateRegister variableOperand2 immediateOperand1
+ where
+ multiplyImmediateRegister variableOperand immediateOperand =
+ let statements = lui immediateOperand register
+ Store operandRegister = variableOperand
+ in Vector.snoc statements
+ $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.MUL register operandRegister
+ $ RiscV.Funct7 0b0000001
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
loadImmediateOrRegister (IntOperand intValue) targetRegister =