Create numerated temporary variables

This commit is contained in:
Eugen Wissner 2024-08-30 14:55:40 +02:00
parent 0c45a9886a
commit ad0bf43ba5
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
3 changed files with 43 additions and 16 deletions

View File

@ -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

View File

@ -0,0 +1,3 @@
module Language.Elna.CodeGenerator
(
) where

View File

@ -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
newtype Generator = Generator
data Variable = Variable Text | TempVariable Int32
deriving Eq
instance Show Variable
where
show (Variable variable) = '$' : Text.unpack variable
show (TempVariable variable) = '$' : show variable
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
)