summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elna.cabal1
-rw-r--r--lib/Language/Elna/CodeGenerator.hs3
-rw-r--r--lib/Language/Elna/Intermediate.hs55
3 files changed, 43 insertions, 16 deletions
diff --git a/elna.cabal b/elna.cabal
index 9f07012..136cd43 100644
--- a/elna.cabal
+++ b/elna.cabal
@@ -32,6 +32,7 @@ library elna-internal
import: warnings
exposed-modules:
Language.Elna.AST
+ Language.Elna.CodeGenerator
Language.Elna.Intermediate
Language.Elna.Location
Language.Elna.NameAnalysis
diff --git a/lib/Language/Elna/CodeGenerator.hs b/lib/Language/Elna/CodeGenerator.hs
new file mode 100644
index 0000000..cdbfc01
--- /dev/null
+++ b/lib/Language/Elna/CodeGenerator.hs
@@ -0,0 +1,3 @@
+module Language.Elna.CodeGenerator
+ (
+ ) where
diff --git a/lib/Language/Elna/Intermediate.hs b/lib/Language/Elna/Intermediate.hs
index 0cda806..4e23fd9 100644
--- a/lib/Language/Elna/Intermediate.hs
+++ b/lib/Language/Elna/Intermediate.hs
@@ -21,6 +21,7 @@ import Language.Elna.SymbolTable (SymbolTable, Info(..))
import qualified Language.Elna.SymbolTable as SymbolTable
import Data.Foldable (Foldable(..), foldrM)
import GHC.Records (HasField(..))
+import qualified Data.Text as Text
import qualified Data.Text.Lazy.Builder.Int as Text.Builder
import qualified Data.Text.Lazy.Builder as Text.Builder
import qualified Data.Text.Lazy as Text.Lazy
@@ -31,25 +32,37 @@ data Operand
deriving (Eq, Show)
newtype Label = Label Text
- deriving (Eq, Show)
+ deriving Eq
-data Variable = Variable Text | TempVariable
- deriving (Eq, Show)
+instance Show Label
+ where
+ show (Label label) = '.' : Text.unpack label
+
+data Variable = Variable Text | TempVariable Int32
+ deriving Eq
+
+instance Show Variable
+ where
+ show (Variable variable) = '$' : Text.unpack variable
+ show (TempVariable variable) = '$' : show variable
-newtype Generator = Generator
+data Generator = Generator
{ labelCounter :: Int32
+ , temporaryCounter :: Int32
} deriving (Eq, Show)
instance Semigroup Generator
where
lhs <> rhs = Generator
{ labelCounter = getField @"labelCounter" lhs + getField @"labelCounter" rhs
+ , temporaryCounter = getField @"temporaryCounter" lhs + getField @"temporaryCounter" rhs
}
instance Monoid Generator
where
mempty = Generator
{ labelCounter = 0
+ , temporaryCounter = 0
}
newtype Intermediate a = Intermediate
@@ -106,6 +119,16 @@ createLabel = do
{ labelCounter = getField @"labelCounter" generator + 1
}
+createTemporary :: Intermediate Variable
+createTemporary = do
+ currentCounter <- Intermediate $ gets temporaryCounter
+ Intermediate $ modify' modifier
+ pure $ TempVariable currentCounter
+ where
+ modifier generator = generator
+ { temporaryCounter = getField @"temporaryCounter" generator + 1
+ }
+
intermediate :: SymbolTable -> AST.Program -> HashMap AST.Identifier (Vector Quadruple)
intermediate globalTable
= fst
@@ -237,8 +260,8 @@ variableAccess localTable (AST.ArrayAccess access1 index1) Nothing (ArrayType _
variableAccess localTable access1 (Just indexPlace) baseType statements
variableAccess localTable (AST.ArrayAccess arrayAccess' arrayIndex) (Just baseIndex) (ArrayType arraySize baseType) statements = do
(indexPlace, statements') <- expression localTable arrayIndex
- let resultVariable = TempVariable
- resultOperand = VariableOperand resultVariable
+ resultVariable <- createTemporary
+ let resultOperand = VariableOperand resultVariable
indexCalculation = Vector.fromList
[ ProductQuadruple (IntOperand $ fromIntegral arraySize) baseIndex resultVariable
, AddQuadruple indexPlace resultOperand resultVariable
@@ -262,19 +285,19 @@ expression localTable = \case
case variableAccess' of
(AST.Identifier identifier, Nothing, statements) ->
pure (VariableOperand (Variable identifier), statements)
- (AST.Identifier identifier, Just operand, statements) ->
- let arrayAddress = TempVariable
- arrayStatement = ArrayQuadruple (Variable identifier) operand arrayAddress
- in pure
+ (AST.Identifier identifier, Just operand, statements) -> do
+ arrayAddress <- createTemporary
+ let arrayStatement = ArrayQuadruple (Variable identifier) operand arrayAddress
+ pure
( VariableOperand arrayAddress
, Vector.snoc statements arrayStatement
)
(AST.LiteralExpression literal') -> pure (literal literal', mempty)
(AST.NegationExpression negation) -> do
(operand, statements) <- expression localTable negation
- let tempVariable = TempVariable
- negationQuadruple = NegationQuadruple operand tempVariable
- in pure
+ tempVariable <- createTemporary
+ let negationQuadruple = NegationQuadruple operand tempVariable
+ pure
( VariableOperand tempVariable
, Vector.snoc statements negationQuadruple
)
@@ -289,9 +312,9 @@ expression localTable = \case
binaryExpression f lhs rhs = do
(lhsOperand, lhsStatements) <- expression localTable lhs
(rhsOperand, rhsStatements) <- expression localTable rhs
- let tempVariable = TempVariable
- newQuadruple = f lhsOperand rhsOperand tempVariable
- in pure
+ tempVariable <- createTemporary
+ let newQuadruple = f lhsOperand rhsOperand tempVariable
+ pure
( VariableOperand tempVariable
, Vector.snoc (lhsStatements <> rhsStatements) newQuadruple
)