Parse local variables

This commit is contained in:
Eugen Wissner 2024-11-06 22:23:49 +01:00
parent e2d4b76c0b
commit 060496fc6e
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
11 changed files with 115 additions and 91 deletions

17
TODO
View File

@ -1,9 +1,12 @@
# Intermediate code generation # Intermediate code generation
- To access named parameters and local variables inside a procedure, IR should - To access named parameters inside a procedure, IR should be able to reference
be able to reference them. During the generation the needed information (e.g. them. During the generation the needed information (e.g. offsets or registers)
offsets or registers) can be extracted from the symbol table and saved in the can be extracted from the symbol table and saved in the operands.
operands. - Glue always generates the same intermediate variable (LocalVariable 0) for
local variables. (LocalVariable 0) is handled the same as temporary variables
that are currently saved only in registers. There space on the stack allocated
for local variables.
# ELF generation # ELF generation
@ -15,3 +18,9 @@
- Each temporary variable gets a tn register where n is the variable index. If - Each temporary variable gets a tn register where n is the variable index. If
there more variables the allocation will fail with out of bounds runtime there more variables the allocation will fail with out of bounds runtime
error. Implement spill over. error. Implement spill over.
- The allocator puts temporary and local variables into the same registers,
causing conflicts.
# Language
- Array support.

View File

@ -30,26 +30,21 @@ allocate MachineConfiguration{..} = fmap function
quadruple (ParameterQuadruple operand1) = quadruple (ParameterQuadruple operand1) =
ParameterQuadruple (operand operand1) ParameterQuadruple (operand operand1)
quadruple (CallQuadruple name count) = CallQuadruple name count quadruple (CallQuadruple name count) = CallQuadruple name count
quadruple (AddQuadruple operand1 operand2 (TempVariable index)) quadruple (AddQuadruple operand1 operand2 variable)
= AddQuadruple (operand operand1) (operand operand2) = AddQuadruple (operand operand1) (operand operand2)
$ Store $ storeVariable variable
$ temporaryRegisters !! fromIntegral index quadruple (SubtractionQuadruple operand1 operand2 variable)
quadruple (SubtractionQuadruple operand1 operand2 (TempVariable index))
= SubtractionQuadruple (operand operand1) (operand operand2) = SubtractionQuadruple (operand operand1) (operand operand2)
$ Store $ storeVariable variable
$ temporaryRegisters !! fromIntegral index quadruple (NegationQuadruple operand1 variable)
quadruple (NegationQuadruple operand1 (TempVariable index))
= NegationQuadruple (operand operand1) = NegationQuadruple (operand operand1)
$ Store $ storeVariable variable
$ temporaryRegisters !! fromIntegral index quadruple (ProductQuadruple operand1 operand2 variable)
quadruple (ProductQuadruple operand1 operand2 (TempVariable index))
= ProductQuadruple (operand operand1) (operand operand2) = ProductQuadruple (operand operand1) (operand operand2)
$ Store $ storeVariable variable
$ temporaryRegisters !! fromIntegral index quadruple (DivisionQuadruple operand1 operand2 variable)
quadruple (DivisionQuadruple operand1 operand2 (TempVariable index))
= DivisionQuadruple (operand operand1) (operand operand2) = DivisionQuadruple (operand operand1) (operand operand2)
$ Store $ storeVariable variable
$ temporaryRegisters !! fromIntegral index
quadruple (LabelQuadruple label) = LabelQuadruple label quadruple (LabelQuadruple label) = LabelQuadruple label
quadruple (GoToQuadruple label) = GoToQuadruple label quadruple (GoToQuadruple label) = GoToQuadruple label
quadruple (EqualQuadruple operand1 operand2 goToLabel) = quadruple (EqualQuadruple operand1 operand2 goToLabel) =
@ -64,9 +59,20 @@ allocate MachineConfiguration{..} = fmap function
LessOrEqualQuadruple (operand operand1) (operand operand2) goToLabel LessOrEqualQuadruple (operand operand1) (operand operand2) goToLabel
quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel) = quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel) =
GreaterOrEqualQuadruple (operand operand1) (operand operand2) goToLabel GreaterOrEqualQuadruple (operand operand1) (operand operand2) goToLabel
quadruple (AssignQuadruple operand1 variable)
= AssignQuadruple (operand operand1)
$ storeVariable variable
operand :: Operand Variable -> Operand (Store r) operand :: Operand Variable -> Operand (Store r)
operand (IntOperand x) = IntOperand x operand (IntOperand x) = IntOperand x
operand (VariableOperand (TempVariable index)) operand (VariableOperand (TempVariable index))
= VariableOperand = VariableOperand
$ Store $ Store
$ temporaryRegisters !! fromIntegral index $ temporaryRegisters !! fromIntegral index
operand (VariableOperand (LocalVariable index))
= VariableOperand
$ Store
$ temporaryRegisters !! fromIntegral index
storeVariable (TempVariable index) =
Store $ temporaryRegisters !! fromIntegral index
storeVariable (LocalVariable index) =
Store $ temporaryRegisters !! fromIntegral index

View File

@ -17,12 +17,12 @@ instance Show Label
where where
show (Label label) = '.' : Text.unpack label show (Label label) = '.' : Text.unpack label
newtype Variable = TempVariable Word32 -- | Variable Text data Variable = TempVariable Word32 | LocalVariable Word32
deriving Eq deriving Eq
instance Show Variable instance Show Variable
where where
-- show (Variable variable) = '$' : Text.unpack variable show (LocalVariable variable) = '@' : show variable
show (TempVariable variable) = '$' : show variable show (TempVariable variable) = '$' : show variable
data Operand v data Operand v
@ -41,8 +41,8 @@ data Quadruple v
| ProductQuadruple (Operand v) (Operand v) v | ProductQuadruple (Operand v) (Operand v) v
| DivisionQuadruple (Operand v) (Operand v) v | DivisionQuadruple (Operand v) (Operand v) v
| GoToQuadruple Label | GoToQuadruple Label
{-| AssignQuadruple Operand Variable | AssignQuadruple (Operand v) v
| ArrayQuadruple Variable Operand Variable {-| ArrayQuadruple Variable Operand Variable
| ArrayAssignQuadruple Operand Operand Variable -} | ArrayAssignQuadruple Operand Operand Variable -}
| LessOrEqualQuadruple (Operand v) (Operand v) Label | LessOrEqualQuadruple (Operand v) (Operand v) Label
| GreaterOrEqualQuadruple (Operand v) (Operand v) Label | GreaterOrEqualQuadruple (Operand v) (Operand v) Label

View File

@ -6,7 +6,7 @@ module Language.Elna.Frontend.AST
, Statement(..) , Statement(..)
, TypeExpression(..) , TypeExpression(..)
, VariableDeclaration(..) , VariableDeclaration(..)
--, VariableAccess(..) , VariableAccess(..)
, Condition(..) , Condition(..)
, Expression(..) , Expression(..)
, Literal(..) , Literal(..)
@ -70,8 +70,8 @@ instance Show TypeExpression
data Statement data Statement
= EmptyStatement = EmptyStatement
| IfStatement Condition Statement (Maybe Statement) | IfStatement Condition Statement (Maybe Statement)
{-| AssignmentStatement VariableAccess Expression | AssignmentStatement VariableAccess Expression
| WhileStatement Condition Statement -} -- | WhileStatement Condition Statement
| CompoundStatement [Statement] | CompoundStatement [Statement]
| CallStatement Identifier [Expression] | CallStatement Identifier [Expression]
deriving Eq deriving Eq
@ -84,9 +84,9 @@ instance Show Statement
, show if' , show if'
, maybe "" ((<> " else ") . show) else' , maybe "" ((<> " else ") . show) else'
] ]
{-show (AssignmentStatement lhs rhs) = show (AssignmentStatement lhs rhs) =
concat [show lhs, " := ", show rhs, ";"] concat [show lhs, " := ", show rhs, ";"]
show (WhileStatement expression statement) = {-show (WhileStatement expression statement) =
concat ["while (", show expression, ") ", show statement, ";"]-} concat ["while (", show expression, ") ", show statement, ";"]-}
show (CompoundStatement statements) = show (CompoundStatement statements) =
concat ["{\n", unlines (show <$> statements), " }"] concat ["{\n", unlines (show <$> statements), " }"]
@ -163,7 +163,7 @@ data Expression
| NegationExpression Expression | NegationExpression Expression
| ProductExpression Expression Expression | ProductExpression Expression Expression
| DivisionExpression Expression Expression | DivisionExpression Expression Expression
-- | VariableExpression VariableAccess | VariableExpression VariableAccess
deriving Eq deriving Eq
instance Show Expression instance Show Expression
@ -174,19 +174,19 @@ instance Show Expression
show (NegationExpression negation) = '-' : show negation show (NegationExpression negation) = '-' : show negation
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]
-- show (VariableExpression variable) = show variable show (VariableExpression variable) = show variable
{-
data VariableAccess newtype VariableAccess
= VariableAccess Identifier = VariableAccess Identifier
| ArrayAccess VariableAccess Expression -- | ArrayAccess VariableAccess Expression
deriving Eq deriving Eq
instance Show VariableAccess instance Show VariableAccess
where where
show (VariableAccess variableName) = show variableName show (VariableAccess variableName) = show variableName
show (ArrayAccess arrayAccess elementIndex) = {- show (ArrayAccess arrayAccess elementIndex) =
concat [show arrayAccess, "[", show elementIndex, "]"] concat [show arrayAccess, "[", show elementIndex, "]"] -}
-}
data Condition data Condition
= EqualCondition Expression Expression = EqualCondition Expression Expression
| NonEqualCondition Expression Expression | NonEqualCondition Expression Expression

View File

@ -158,9 +158,9 @@ expression globalTable (AST.ProductExpression lhs rhs)
expression globalTable (AST.DivisionExpression lhs rhs) expression globalTable (AST.DivisionExpression lhs rhs)
= expression globalTable lhs = expression globalTable lhs
>> expression globalTable rhs >> expression globalTable rhs
{- expression globalTable (AST.VariableExpression variableExpression) = expression globalTable (AST.VariableExpression variableExpression) =
variableAccess globalTable variableExpression variableAccess globalTable variableExpression
-}
statement :: SymbolTable -> AST.Statement -> NameAnalysis () statement :: SymbolTable -> AST.Statement -> NameAnalysis ()
statement _ AST.EmptyStatement = pure () statement _ AST.EmptyStatement = pure ()
statement globalTable (AST.CallStatement name arguments) statement globalTable (AST.CallStatement name arguments)
@ -172,9 +172,9 @@ statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement)
= condition globalTable ifCondition = condition globalTable ifCondition
>> statement globalTable ifStatement >> statement globalTable ifStatement
>> maybe (pure ()) (statement globalTable) elseStatement >> maybe (pure ()) (statement globalTable) elseStatement
-- statement globalTable (AST.AssignmentStatement lvalue rvalue) statement globalTable (AST.AssignmentStatement lvalue rvalue)
-- = variableAccess globalTable lvalue = variableAccess globalTable lvalue
-- >> expression globalTable rvalue >> expression globalTable rvalue
--statement globalTable (AST.WhileStatement whileCondition loop) --statement globalTable (AST.WhileStatement whileCondition loop)
-- = condition globalTable whileCondition -- = condition globalTable whileCondition
-- >> statement globalTable loop -- >> statement globalTable loop
@ -198,13 +198,13 @@ condition globalTable (AST.LessOrEqualCondition lhs rhs)
condition globalTable (AST.GreaterOrEqualCondition lhs rhs) condition globalTable (AST.GreaterOrEqualCondition lhs rhs)
= expression globalTable lhs = expression globalTable lhs
>> expression globalTable rhs >> expression globalTable rhs
{-
variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis () variableAccess :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
= variableAccess globalTable arrayExpression
>> expression globalTable indexExpression
variableAccess globalTable (AST.VariableAccess identifier) = variableAccess globalTable (AST.VariableAccess identifier) =
checkSymbol globalTable identifier checkSymbol globalTable identifier
{- variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)
= variableAccess globalTable arrayExpression
>> expression globalTable indexExpression
enter :: Identifier -> Info -> SymbolTable -> NameAnalysis SymbolTable enter :: Identifier -> Info -> SymbolTable -> NameAnalysis SymbolTable
enter identifier info table enter identifier info table
@ -216,9 +216,4 @@ identifierAlreadyDefinedError = NameAnalysis
. lift . lift
. throwE . throwE
. IdentifierAlreadyDefinedError . IdentifierAlreadyDefinedError
variableDeclaration :: AST.VariableDeclaration -> NameAnalysis (Identifier, Info)
variableDeclaration (AST.VariableDeclaration identifier typeExpression)
= (identifier,) . VariableInfo False
<$> dataType typeExpression
-} -}

View File

@ -16,7 +16,7 @@ import Language.Elna.Frontend.AST
, Statement(..) , Statement(..)
, TypeExpression(..) , TypeExpression(..)
, VariableDeclaration(..) , VariableDeclaration(..)
--, VariableAccess(..) , VariableAccess(..)
, Condition(..) , Condition(..)
, Expression(..) , Expression(..)
, Literal(..) , Literal(..)
@ -64,7 +64,7 @@ termP :: Parser Expression
termP = choice termP = choice
[ parensP expressionP [ parensP expressionP
, LiteralExpression <$> literalP , LiteralExpression <$> literalP
-- , VariableExpression <$> variableAccessP , VariableExpression <$> variableAccessP
] ]
operatorTable :: [[Operator Parser Expression]] operatorTable :: [[Operator Parser Expression]]
@ -91,13 +91,13 @@ operatorTable =
expressionP :: Parser Expression expressionP :: Parser Expression
expressionP = makeExprParser termP operatorTable expressionP = makeExprParser termP operatorTable
{-
variableAccessP :: Parser VariableAccess variableAccessP :: Parser VariableAccess
variableAccessP = do variableAccessP = VariableAccess <$> identifierP {- do
identifier <- identifierP identifier <- identifierP
indices <- many $ bracketsP expressionP indices <- many $ bracketsP expressionP
pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices -}
-}
conditionP :: Parser Condition conditionP :: Parser Condition
conditionP = do conditionP = do
lhs <- expressionP lhs <- expressionP
@ -187,8 +187,8 @@ statementP
= EmptyStatement <$ semicolonP = EmptyStatement <$ semicolonP
<|> ifElseP <|> ifElseP
<|> CompoundStatement <$> blockP (many statementP) <|> CompoundStatement <$> blockP (many statementP)
{-<|> try assignmentP <|> try assignmentP
<|> try whileP -} -- <|> try whileP
<|> callP <|> callP
<?> "statement" <?> "statement"
where where
@ -202,12 +202,12 @@ statementP
<*> optional (symbol "else" *> statementP) <*> optional (symbol "else" *> statementP)
{-whileP = WhileStatement {-whileP = WhileStatement
<$> (symbol "while" *> parensP conditionP) <$> (symbol "while" *> parensP conditionP)
<*> statementP <*> statementP -}
assignmentP = AssignmentStatement assignmentP = AssignmentStatement
<$> variableAccessP <$> variableAccessP
<* symbol ":=" <* symbol ":="
<*> expressionP <*> expressionP
<* semicolonP -} <* semicolonP
variableDeclarationP :: Parser VariableDeclaration variableDeclarationP :: Parser VariableDeclaration
variableDeclarationP = VariableDeclaration variableDeclarationP = VariableDeclaration

View File

@ -3,10 +3,11 @@ module Language.Elna.Frontend.TypeAnalysis
, -- Error(..) , -- Error(..)
) where ) where
import Control.Applicative (Alternative(..))
import Control.Monad (unless) import Control.Monad (unless)
import Control.Monad.Trans.Class (MonadTrans(..)) import Control.Monad.Trans.Class (MonadTrans(..))
import Control.Monad.Trans.Except (Except, runExcept, throwE) import Control.Monad.Trans.Except (Except, runExcept, throwE)
import Control.Monad.Trans.Reader (ReaderT, runReaderT, withReaderT, ask) import Control.Monad.Trans.Reader (ReaderT, runReaderT, withReaderT, ask, asks)
import Data.Foldable (traverse_) import Data.Foldable (traverse_)
import qualified Data.Vector as Vector import qualified Data.Vector as Vector
import qualified Language.Elna.Frontend.AST as AST import qualified Language.Elna.Frontend.AST as AST
@ -22,9 +23,6 @@ typeAnalysis globalTable = either Just (const Nothing)
. runTypeAnalysis . runTypeAnalysis
. program . program
{-
import Control.Applicative (Alternative(..))
-}
data Error data Error
= UnexpectedProcedureInfoError Info = UnexpectedProcedureInfoError Info
| UndefinedSymbolError Identifier | UndefinedSymbolError Identifier
@ -96,14 +94,14 @@ declaration (AST.TypeDefinition _ _) = pure ()
statement :: SymbolTable -> AST.Statement -> TypeAnalysis () statement :: SymbolTable -> AST.Statement -> TypeAnalysis ()
statement globalTable = \case statement globalTable = \case
AST.EmptyStatement -> pure () AST.EmptyStatement -> pure ()
{- AST.AssignmentStatement lhs rhs -> do AST.AssignmentStatement lhs rhs -> do
lhsType <- variableAccess globalTable lhs lhsType <- variableAccess globalTable lhs
rhsType <- expression globalTable rhs rhsType <- expression globalTable rhs
unless (lhsType == intType) unless (lhsType == intType)
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError lhsType $ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError lhsType
unless (rhsType == intType) unless (rhsType == intType)
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError rhsType $ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError rhsType
AST.WhileStatement whileCondition whileStatement -> do {- AST.WhileStatement whileCondition whileStatement -> do
conditionType <- condition globalTable whileCondition conditionType <- condition globalTable whileCondition
unless (conditionType == booleanType) unless (conditionType == booleanType)
$ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError conditionType $ TypeAnalysis $ lift $ throwE $ InvalidConditionTypeError conditionType
@ -136,7 +134,7 @@ statement globalTable = \case
when (isReferenceParameter && not (isLvalue argument)) when (isReferenceParameter && not (isLvalue argument))
$ TypeAnalysis $ lift $ throwE $ ExpectedLvalueError argument $ TypeAnalysis $ lift $ throwE $ ExpectedLvalueError argument
isLvalue (AST.VariableExpression _) = True isLvalue (AST.VariableExpression _) = True
isLvalue _ = False isLvalue _ = False -}
variableAccess :: SymbolTable -> AST.VariableAccess -> TypeAnalysis Type variableAccess :: SymbolTable -> AST.VariableAccess -> TypeAnalysis Type
variableAccess globalTable (AST.VariableAccess identifier) = do variableAccess globalTable (AST.VariableAccess identifier) = do
@ -147,7 +145,7 @@ variableAccess globalTable (AST.VariableAccess identifier) = do
$ UnexpectedVariableInfoError anotherInfo $ UnexpectedVariableInfoError anotherInfo
Nothing -> TypeAnalysis $ lift $ throwE Nothing -> TypeAnalysis $ lift $ throwE
$ UndefinedSymbolError identifier $ UndefinedSymbolError identifier
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = do {-variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = do
arrayType <- variableAccess globalTable arrayExpression arrayType <- variableAccess globalTable arrayExpression
indexType <- expression globalTable indexExpression indexType <- expression globalTable indexExpression
unless (indexType == intType) unless (indexType == intType)
@ -159,8 +157,8 @@ variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) = d
-} -}
expression :: SymbolTable -> AST.Expression -> TypeAnalysis Type expression :: SymbolTable -> AST.Expression -> TypeAnalysis Type
expression globalTable = \case expression globalTable = \case
{- AST.VariableExpression variableExpression -> do AST.VariableExpression variableExpression ->
variableAccess globalTable variableExpression -} variableAccess globalTable variableExpression
AST.LiteralExpression literal' -> literal literal' AST.LiteralExpression literal' -> literal literal'
AST.NegationExpression negation -> do AST.NegationExpression negation -> do
operandType <- expression globalTable negation operandType <- expression globalTable negation

View File

@ -15,13 +15,15 @@ import qualified Data.Text.Lazy as Text.Lazy
import qualified Data.Vector as Vector import qualified Data.Vector as Vector
import Data.Word (Word32) import Data.Word (Word32)
import qualified Language.Elna.Frontend.AST as AST import qualified Language.Elna.Frontend.AST as AST
import Language.Elna.Frontend.Types (Type(..))
import Language.Elna.Backend.Intermediate import Language.Elna.Backend.Intermediate
( Label(..) ( Label(..)
, Operand(..) , Operand(..)
, Quadruple(..) , Quadruple(..)
, Variable(..) , Variable(..)
) )
import Language.Elna.Frontend.SymbolTable (SymbolTable) import Language.Elna.Frontend.SymbolTable (Info(..), SymbolTable)
import qualified Language.Elna.Frontend.SymbolTable as SymbolTable
import GHC.Records (HasField(..)) import GHC.Records (HasField(..))
data Paste = Paste data Paste = Paste
@ -98,20 +100,20 @@ statement localTable (AST.IfStatement ifCondition ifStatement elseStatement) = d
<> Vector.snoc ifStatements (LabelQuadruple endLabel) <> Vector.snoc ifStatements (LabelQuadruple endLabel)
Nothing -> Vector.fromList [jumpConstructor ifLabel, GoToQuadruple endLabel, LabelQuadruple ifLabel] Nothing -> Vector.fromList [jumpConstructor ifLabel, GoToQuadruple endLabel, LabelQuadruple ifLabel]
<> Vector.snoc ifStatements (LabelQuadruple endLabel) <> Vector.snoc ifStatements (LabelQuadruple endLabel)
{- statement localTable (AST.AssignmentStatement variableAccess' assignee) = do statement localTable (AST.AssignmentStatement variableAccess' assignee) = do
(rhsOperand, rhsStatements) <- expression localTable assignee (rhsOperand, rhsStatements) <- expression localTable assignee
let variableType' = variableType variableAccess' localTable let variableType' = variableType variableAccess' localTable
accessResult <- variableAccess localTable variableAccess' Nothing variableType' mempty accessResult <- variableAccess localTable variableAccess' Nothing variableType' mempty
pure $ rhsStatements <> case accessResult of pure $ rhsStatements <> case accessResult of
(AST.Identifier identifier, Just accumulatedIndex, accumulatedStatements) -> {-(AST.Identifier identifier, Just accumulatedIndex, accumulatedStatements) ->
Vector.snoc accumulatedStatements Vector.snoc accumulatedStatements
$ ArrayAssignQuadruple rhsOperand accumulatedIndex $ ArrayAssignQuadruple rhsOperand accumulatedIndex
$ Variable identifier $ LocalVariable identifier -}
(AST.Identifier identifier, Nothing, accumulatedStatements) -> (AST.Identifier identifier, Nothing, accumulatedStatements) ->
Vector.snoc accumulatedStatements Vector.snoc accumulatedStatements
$ AssignQuadruple rhsOperand $ AssignQuadruple rhsOperand
$ Variable identifier $ LocalVariable 0
statement localTable (AST.WhileStatement whileCondition whileStatement) = do {- statement localTable (AST.WhileStatement whileCondition whileStatement) = do
(conditionStatements, jumpConstructor) <- condition localTable whileCondition (conditionStatements, jumpConstructor) <- condition localTable whileCondition
startLabel <- createLabel startLabel <- createLabel
endLabel <- createLabel endLabel <- createLabel
@ -189,20 +191,17 @@ condition localTable (AST.GreaterOrEqualCondition lhs rhs) = do
( lhsStatements <> rhsStatements ( lhsStatements <> rhsStatements
, GreaterOrEqualQuadruple lhsOperand rhsOperand , GreaterOrEqualQuadruple lhsOperand rhsOperand
) )
{-
import Language.Elna.Types (Type(..))
import qualified Language.Elna.SymbolTable as SymbolTable
variableAccess variableAccess
:: SymbolTable :: SymbolTable
-> AST.VariableAccess -> AST.VariableAccess
-> Maybe Operand -> Maybe (Operand Variable)
-> Type -> Type
-> Vector Quadruple -> Vector (Quadruple Variable)
-> Glue (AST.Identifier, Maybe Operand, Vector Quadruple) -> Glue (AST.Identifier, Maybe (Operand Variable), Vector (Quadruple Variable))
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
(indexPlace, statements) <- expression localTable index1 (indexPlace, statements) <- expression localTable index1
variableAccess localTable access1 (Just indexPlace) baseType statements variableAccess localTable access1 (Just indexPlace) baseType statements
variableAccess localTable (AST.ArrayAccess arrayAccess' arrayIndex) (Just baseIndex) (ArrayType arraySize baseType) statements = do variableAccess localTable (AST.ArrayAccess arrayAccess' arrayIndex) (Just baseIndex) (ArrayType arraySize baseType) statements = do
@ -216,14 +215,14 @@ variableAccess localTable (AST.ArrayAccess arrayAccess' arrayIndex) (Just baseIn
in variableAccess localTable arrayAccess' (Just resultOperand) baseType in variableAccess localTable arrayAccess' (Just resultOperand) baseType
$ statements <> indexCalculation <> statements' $ statements <> indexCalculation <> statements'
variableAccess _ _ _ _ _ = error "Array access operator doesn't match the type." variableAccess _ _ _ _ _ = error "Array access operator doesn't match the type."
-}
variableType :: AST.VariableAccess -> SymbolTable -> Type variableType :: AST.VariableAccess -> SymbolTable -> Type
variableType (AST.VariableAccess identifier) symbolTable variableType (AST.VariableAccess identifier) symbolTable
| Just (TypeInfo type') <- SymbolTable.lookup identifier symbolTable = type' | Just (TypeInfo type') <- SymbolTable.lookup identifier symbolTable = type'
| otherwise = error "Undefined type." | otherwise = error "Undefined type."
variableType (AST.ArrayAccess arrayAccess' _) symbolTable = {-variableType (AST.ArrayAccess arrayAccess' _) symbolTable =
variableType arrayAccess' symbolTable variableType arrayAccess' symbolTable -}
-}
expression :: SymbolTable -> AST.Expression -> Glue (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)
@ -242,8 +241,9 @@ expression localTable = \case
binaryExpression ProductQuadruple lhs rhs binaryExpression ProductQuadruple lhs rhs
(AST.DivisionExpression lhs rhs) -> (AST.DivisionExpression lhs rhs) ->
binaryExpression DivisionQuadruple lhs rhs binaryExpression DivisionQuadruple lhs rhs
{- (AST.VariableExpression variableExpression) -> do (AST.VariableExpression variableExpression) -> do
let variableType' = variableType variableExpression localTable pure (VariableOperand (LocalVariable 0), mempty)
{- let variableType' = variableType variableExpression localTable
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
case variableAccess' of case variableAccess' of
(AST.Identifier identifier, Nothing, statements) -> (AST.Identifier identifier, Nothing, statements) ->

View File

@ -427,11 +427,11 @@ quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel)
then pure $ Vector.singleton $ unconditionalJal goToLabel then pure $ Vector.singleton $ unconditionalJal goToLabel
else pure Vector.empty else pure Vector.empty
| VariableOperand variableOperand1 <- operand1 | VariableOperand variableOperand1 <- operand1
, VariableOperand variableOperand2 <- operand2 = do , VariableOperand variableOperand2 <- operand2 =
let Store operandRegister1 = variableOperand1 let Store operandRegister1 = variableOperand1
Store operandRegister2 = variableOperand2 Store operandRegister2 = variableOperand2
Label goToLabel' = goToLabel Label goToLabel' = goToLabel
pure $ Vector.singleton in pure $ Vector.singleton
$ Instruction $ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch $ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BGE operandRegister1 operandRegister2 $ RiscV.RBranch goToLabel' RiscV.BGE operandRegister1 operandRegister2
@ -453,6 +453,15 @@ quadruple (GreaterOrEqualQuadruple operand1 operand2 goToLabel)
$ Instruction $ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch $ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BGE immediateRegister operandRegister2 $ RiscV.RBranch goToLabel' RiscV.BGE immediateRegister operandRegister2
quadruple (AssignQuadruple operand1 (Store register))
| IntOperand immediateOperand1 <- operand1 = pure
$ lui immediateOperand1 register
| VariableOperand variableOperand1 <- operand1 =
let Store operandRegister1 = variableOperand1
in pure $ Vector.singleton
$ Instruction
$ RiscV.BaseInstruction RiscV.OpImm
$ RiscV.I register RiscV.ADDI operandRegister1 0
unconditionalJal :: Label -> Statement unconditionalJal :: Label -> Statement
unconditionalJal (Label goToLabel) = Instruction unconditionalJal (Label goToLabel) = Instruction

View File

@ -0,0 +1 @@
58

View File

@ -0,0 +1,6 @@
proc main() {
var i: int;
i := 58;
printi(i);
}