Parse call statements

This commit is contained in:
Eugen Wissner 2024-09-24 22:20:57 +02:00
parent e66ccf46f4
commit b30bbcab28
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
10 changed files with 139 additions and 130 deletions

10
TODO
View File

@ -1,15 +1,17 @@
# Intermediate code generation # Intermediate code generation
- Put symbol table in the reader monad and it to the stack - Traverse the AST and generate IR.
or use the state monad for everything.
- Add errors handling to the monad stack.
# ELF generation # ELF generation
- Don't ignore relocations where the symbol is not defined in the symbol table. - Don't ignore relocations where the symbol is not defined in the symbol table.
Report an error about an undefined symbol. Report an error about an undefined symbol.
- Don't hardcode symbols in symbolEntry.
# Name analysis # Name analysis
- Format error messages. - Format error messages.
- Return non-zero error code on errors.
# Built-in
Printi should be able to print numbers with multiple digits.

View File

@ -7,11 +7,12 @@ module Language.Elna.AST
, TypeExpression(..) , TypeExpression(..)
, VariableDeclaration(..) , VariableDeclaration(..)
{-, VariableAccess(..) {-, VariableAccess(..)
, Condition(..) , Condition(..)-}
, Expression(..) , Expression(..)
, Literal(..)-} , Literal(..)
) where ) where
import Data.Int (Int32)
import Data.List (intercalate) import Data.List (intercalate)
import Data.Word ({-Word16, -}Word32) import Data.Word ({-Word16, -}Word32)
import Language.Elna.Location (Identifier(..), showArrayType) import Language.Elna.Location (Identifier(..), showArrayType)
@ -67,8 +68,8 @@ data Statement
{-| AssignmentStatement VariableAccess Expression {-| AssignmentStatement VariableAccess Expression
| IfStatement Condition Statement (Maybe Statement) | IfStatement Condition Statement (Maybe Statement)
| WhileStatement Condition Statement | WhileStatement Condition Statement
| CompoundStatement [Statement] | CompoundStatement [Statement]-}
| CallStatement Identifier [Expression]-} | CallStatement Identifier [Expression]
deriving Eq deriving Eq
instance Show Statement instance Show Statement
@ -84,39 +85,58 @@ instance Show Statement
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), " }"]-}
show (CallStatement name parameters) = show name <> "(" show (CallStatement name parameters) = show name <> "("
<> intercalate ", " (show <$> parameters) <> ")"-} <> intercalate ", " (show <$> parameters) <> ")"
data VariableDeclaration = data VariableDeclaration =
VariableDeclaration Identifier TypeExpression VariableDeclaration Identifier TypeExpression
deriving Eq deriving Eq
instance Show VariableDeclaration newtype Literal
where
show (VariableDeclaration identifier typeExpression) =
concat ["var ", show identifier, ": " <> show typeExpression, ";"]
{-
import Data.Int (Int32)
import Data.Char (chr)
import Numeric (showHex)
data Literal
= IntegerLiteral Int32 = IntegerLiteral Int32
| HexadecimalLiteral Int32 {- | HexadecimalLiteral Int32
| CharacterLiteral Word16 | CharacterLiteral Word16
| BooleanLiteral Bool | BooleanLiteral Bool -}
deriving Eq deriving Eq
instance Show Literal instance Show Literal
where where
show (IntegerLiteral integer) = show integer show (IntegerLiteral integer) = show integer
show (HexadecimalLiteral integer) = '0' : 'x' : showHex integer "" {- show (HexadecimalLiteral integer) = '0' : 'x' : showHex integer ""
show (CharacterLiteral character) = show (CharacterLiteral character) =
'\'' : chr (fromEnum character) : ['\''] '\'' : chr (fromEnum character) : ['\'']
show (BooleanLiteral boolean) show (BooleanLiteral boolean)
| boolean = "true" | boolean = "true"
| otherwise = "false" | otherwise = "false" -}
instance Show VariableDeclaration
where
show (VariableDeclaration identifier typeExpression) =
concat ["var ", show identifier, ": " <> show typeExpression, ";"]
newtype Expression
= LiteralExpression Literal
{- | VariableExpression VariableAccess
| NegationExpression Expression
| SumExpression Expression Expression
| SubtractionExpression Expression Expression
| ProductExpression Expression Expression
| DivisionExpression Expression Expression -}
deriving Eq
instance Show Expression
where
show (LiteralExpression literal) = show literal
{- show (VariableExpression variable) = show variable
show (NegationExpression negation) = '-' : show negation
show (SumExpression lhs rhs) = concat [show lhs, " + ", show rhs]
show (SubtractionExpression 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] -}
{-
import Data.Char (chr)
import Numeric (showHex)
data VariableAccess data VariableAccess
= VariableAccess Identifier = VariableAccess Identifier
@ -129,26 +149,6 @@ instance Show VariableAccess
show (ArrayAccess arrayAccess elementIndex) = show (ArrayAccess arrayAccess elementIndex) =
concat [show arrayAccess, "[", show elementIndex, "]"] concat [show arrayAccess, "[", show elementIndex, "]"]
data Expression
= VariableExpression VariableAccess
| LiteralExpression Literal
| NegationExpression Expression
| SumExpression Expression Expression
| SubtractionExpression Expression Expression
| ProductExpression Expression Expression
| DivisionExpression Expression Expression
deriving Eq
instance Show Expression
where
show (VariableExpression variable) = show variable
show (LiteralExpression literal) = show literal
show (NegationExpression negation) = '-' : show negation
show (SumExpression lhs rhs) = concat [show lhs, " + ", show rhs]
show (SubtractionExpression 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]
data Condition data Condition
= EqualCondition Expression Expression = EqualCondition Expression Expression
| NonEqualCondition Expression Expression | NonEqualCondition Expression Expression

View File

@ -1,5 +1,5 @@
module Language.Elna.CodeGenerator module Language.Elna.CodeGenerator
( Asm(..) ( Statement(..)
, generateCode , generateCode
) where ) where
@ -15,12 +15,12 @@ data Directive
| FunctionDirective | FunctionDirective
deriving (Eq, Show) deriving (Eq, Show)
data Asm data Statement
= Instruction RiscV.Instruction = Instruction RiscV.Instruction
| JumpLabel ByteString [Directive] | JumpLabel ByteString [Directive]
deriving Eq deriving Eq
generateCode :: SymbolTable -> Vector Quadruple -> Vector Asm generateCode :: SymbolTable -> Vector Quadruple -> Vector Statement
generateCode _ _ = Vector.fromList generateCode _ _ = Vector.fromList
[ JumpLabel "main" [GlobalDirective, FunctionDirective] [ JumpLabel "main" [GlobalDirective, FunctionDirective]
, Instruction (RiscV.CallInstruction "printi") , Instruction (RiscV.CallInstruction "printi")

View File

@ -17,7 +17,7 @@ import Data.Functor ((<&>))
import Language.Elna.Location (Identifier(..)) import Language.Elna.Location (Identifier(..))
import Language.Elna.Types (Type(..)) import Language.Elna.Types (Type(..))
import Data.Foldable (traverse_) import Data.Foldable (traverse_)
import Control.Monad (foldM) import Control.Monad (foldM, unless)
data Error data Error
= UndefinedTypeError Identifier = UndefinedTypeError Identifier
@ -128,38 +128,16 @@ dataType environmentSymbolTable (AST.NamedType baseType) = do
dataType environmentSymbolTable (AST.ArrayType arraySize baseType) = dataType environmentSymbolTable (AST.ArrayType arraySize baseType) =
dataType environmentSymbolTable baseType <&> ArrayType arraySize dataType environmentSymbolTable baseType <&> ArrayType arraySize
statement :: SymbolTable -> AST.Statement -> NameAnalysis ()
statement _ AST.EmptyStatement = pure ()
{- statement globalTable (AST.AssignmentStatement lvalue rvalue)
= variableAccess globalTable lvalue
>> expression globalTable rvalue
statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement)
= condition globalTable ifCondition
>> statement globalTable ifStatement
>> maybe (pure ()) (statement globalTable) elseStatement
statement globalTable (AST.WhileStatement whileCondition loop)
= condition globalTable whileCondition
>> statement globalTable loop
statement globalTable (AST.CompoundStatement statements) =
traverse_ (statement globalTable) statements
statement globalTable (AST.CallStatement name arguments)
= checkSymbol globalTable name
>> traverse_ (expression globalTable) arguments
checkSymbol :: SymbolTable -> Identifier -> NameAnalysis () checkSymbol :: SymbolTable -> Identifier -> NameAnalysis ()
checkSymbol globalTable identifier = checkSymbol globalTable identifier
let undefinedSymbolError = NameAnalysis = unless (SymbolTable.member identifier globalTable)
$ lift $ NameAnalysis $ throwE
$ throwE
$ UndefinedSymbolError identifier $ UndefinedSymbolError identifier
isDefined = SymbolTable.member identifier globalTable
in NameAnalysis (asks (SymbolTable.member identifier))
>>= (flip unless undefinedSymbolError . (isDefined ||))
expression :: SymbolTable -> AST.Expression -> NameAnalysis () expression :: SymbolTable -> AST.Expression -> NameAnalysis ()
expression globalTable (AST.VariableExpression variableExpression) =
variableAccess globalTable variableExpression
expression _ (AST.LiteralExpression _) = pure () expression _ (AST.LiteralExpression _) = pure ()
{- 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.SumExpression lhs rhs) expression globalTable (AST.SumExpression lhs rhs)
@ -174,6 +152,24 @@ 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
-}
statement :: SymbolTable -> AST.Statement -> NameAnalysis ()
statement _ AST.EmptyStatement = pure ()
statement globalTable (AST.CallStatement name arguments)
= checkSymbol globalTable name
>> traverse_ (expression globalTable) arguments
{- statement globalTable (AST.AssignmentStatement lvalue rvalue)
= variableAccess globalTable lvalue
>> expression globalTable rvalue
statement globalTable (AST.IfStatement ifCondition ifStatement elseStatement)
= condition globalTable ifCondition
>> statement globalTable ifStatement
>> maybe (pure ()) (statement globalTable) 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 :: SymbolTable -> AST.VariableAccess -> NameAnalysis ()
variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression) variableAccess globalTable (AST.ArrayAccess arrayExpression indexExpression)

View File

@ -4,7 +4,7 @@ module Language.Elna.Parser
) where ) where
import Control.Monad (void) import Control.Monad (void)
-- import Control.Monad.Combinators.Expr (Operator(..), makeExprParser) 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)
@ -17,19 +17,19 @@ import Language.Elna.AST
, TypeExpression(..) , TypeExpression(..)
, VariableDeclaration(..) , VariableDeclaration(..)
{-, VariableAccess(..) {-, VariableAccess(..)
, Condition(..) , Condition(..)-}
, Expression(..) , Expression(..)
, Literal(..)-} , Literal(..)
) )
import Text.Megaparsec import Text.Megaparsec
( Parsec ( Parsec
, (<?>) , (<?>)
--, MonadParsec(..) , MonadParsec(..)
, eof , eof
, optional , optional
, between , between
, sepBy , sepBy
--, choice , choice
) )
import qualified Text.Megaparsec.Char.Lexer as Lexer import qualified Text.Megaparsec.Char.Lexer as Lexer
import Text.Megaparsec.Char import Text.Megaparsec.Char
@ -44,6 +44,17 @@ import Data.Maybe (isJust)
-- import Data.Functor (($>)) -- import Data.Functor (($>))
type Parser = Parsec Void Text type Parser = Parsec Void Text
literalP :: Parser Literal
literalP
= {- HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal)
<|> -} IntegerLiteral <$> lexeme Lexer.decimal
{- <|> CharacterLiteral <$> lexeme charP
<|> BooleanLiteral <$> (symbol "true" $> True)
<|> BooleanLiteral <$> (symbol "false" $> False)
where
charP = fromIntegral . fromEnum
<$> between (char '\'') (char '\'') Lexer.charLiteral -}
{- {-
typeDefinitionP :: Parser Declaration typeDefinitionP :: Parser Declaration
typeDefinitionP = TypeDefinition typeDefinitionP = TypeDefinition
@ -51,25 +62,14 @@ typeDefinitionP = TypeDefinition
<*> (symbol "=" *> typeExpressionP) <*> (symbol "=" *> typeExpressionP)
<* semicolonP <* semicolonP
<?> "type definition" <?> "type definition"
-}
literalP :: Parser Literal
literalP
= HexadecimalLiteral <$> (string "0x" *> lexeme Lexer.hexadecimal)
<|> IntegerLiteral <$> lexeme Lexer.decimal
<|> CharacterLiteral <$> lexeme charP
<|> BooleanLiteral <$> (symbol "true" $> True)
<|> BooleanLiteral <$> (symbol "false" $> False)
where
charP = fromIntegral . fromEnum
<$> between (char '\'') (char '\'') Lexer.charLiteral
termP :: Parser Expression termP :: Parser Expression
termP = choice termP = choice
[ parensP expressionP [ parensP expressionP
, LiteralExpression <$> literalP , LiteralExpression <$> literalP
, VariableExpression <$> variableAccessP -- , VariableExpression <$> variableAccessP
] ]
{-
variableAccessP :: Parser VariableAccess variableAccessP :: Parser VariableAccess
variableAccessP = do variableAccessP = do
identifier <- identifierP identifier <- identifierP
@ -97,10 +97,10 @@ operatorTable =
] ]
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
expressionP = makeExprParser termP operatorTable expressionP = makeExprParser termP [] -- operatorTable
{-
conditionP :: Parser Condition conditionP :: Parser Condition
conditionP = do conditionP = do
lhs <- expressionP lhs <- expressionP
@ -185,21 +185,21 @@ statementP
{-<|> CompoundStatement <$> blockP (many statementP) {-<|> CompoundStatement <$> blockP (many statementP)
<|> try assignmentP <|> try assignmentP
<|> try ifElseP <|> try ifElseP
<|> try whileP <|> try whileP -}
<|> try callP -} <|> try callP
<?> "statement" <?> "statement"
{-where where
ifElseP = IfStatement callP = CallStatement
<$> identifierP
<*> parensP (sepBy expressionP commaP)
<* semicolonP
{-ifElseP = IfStatement
<$> (symbol "if" *> parensP conditionP) <$> (symbol "if" *> parensP conditionP)
<*> statementP <*> statementP
<*> optional (symbol "else" *> statementP) <*> optional (symbol "else" *> statementP)
whileP = WhileStatement whileP = WhileStatement
<$> (symbol "while" *> parensP conditionP) <$> (symbol "while" *> parensP conditionP)
<*> statementP <*> statementP
callP = CallStatement
<$> identifierP
<*> parensP (sepBy expressionP commaP)
<* semicolonP
assignmentP = AssignmentStatement assignmentP = AssignmentStatement
<$> variableAccessP <$> variableAccessP
<* symbol ":=" <* symbol ":="

View File

@ -44,12 +44,14 @@ 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 (Asm(..)) import Language.Elna.CodeGenerator (Statement(..))
import qualified Data.HashSet as HashSet
import GHC.Records (HasField(..))
data UnresolvedRelocation = UnresolvedRelocation ByteString Elf32_Addr Word8 data UnresolvedRelocation = UnresolvedRelocation ByteString Elf32_Addr Word8
data UnresolvedRelocations = UnresolvedRelocations (Vector UnresolvedRelocation) Elf32_Word data UnresolvedRelocations = UnresolvedRelocations (Vector UnresolvedRelocation) Elf32_Word
riscv32Elf :: Vector Asm -> Handle -> ElfWriter Elf32_Ehdr riscv32Elf :: Vector Statement -> Handle -> ElfWriter Elf32_Ehdr
riscv32Elf code objectHandle = text riscv32Elf code objectHandle = text
>>= uncurry symrel >>= uncurry symrel
>>= strtab >>= strtab
@ -180,9 +182,14 @@ riscv32Elf code objectHandle = text
, st_name = 0 , st_name = 0
, st_info = 0 , st_info = 0
} }
(encoded, updatedRelocations, symbols) = (encoded, updatedRelocations, symbols, definitions) =
encodeAsm textTabIndex (mempty, Vector.empty, initialHeaders) code encodeAsm textTabIndex (mempty, Vector.empty, initialHeaders, HashSet.empty) code
symbolResult = encodeEmptyDefinitions symbols
filterPredicate = not
. (`ByteString.isInfixOf` getField @"sectionNames" symbols)
. ("\0" <>) . (<> "\0")
symbolResult = HashSet.foldl' encodeEmptyDefinitions symbols
$ HashSet.filter filterPredicate definitions
size = fromIntegral $ LazyByteString.length encoded size = fromIntegral $ LazyByteString.length encoded
newHeader = Elf32_Shdr newHeader = Elf32_Shdr
{ sh_type = SHT_PROGBITS { sh_type = SHT_PROGBITS
@ -199,8 +206,8 @@ riscv32Elf code objectHandle = text
liftIO $ ByteString.hPut objectHandle $ LazyByteString.toStrict encoded liftIO $ ByteString.hPut objectHandle $ LazyByteString.toStrict encoded
addSectionHeader ".text" newHeader addSectionHeader ".text" newHeader
pure (symbolResult, UnresolvedRelocations updatedRelocations $ fromIntegral $ Vector.length sectionHeaders) pure (symbolResult, UnresolvedRelocations updatedRelocations $ fromIntegral $ Vector.length sectionHeaders)
encodeEmptyDefinitions (ElfHeaderResult names entries) = encodeEmptyDefinitions (ElfHeaderResult names entries) definition =
let printEntry = Elf32_Sym let nextEntry = Elf32_Sym
{ st_value = 0 { st_value = 0
, st_size = 0 , st_size = 0
, st_shndx = 0 , st_shndx = 0
@ -208,18 +215,18 @@ riscv32Elf code objectHandle = text
, st_name = fromIntegral (ByteString.length names) , st_name = fromIntegral (ByteString.length names)
, st_info = stInfo STB_GLOBAL STT_FUNC , st_info = stInfo STB_GLOBAL STT_FUNC
} }
in ElfHeaderResult (names <> "printi\0") in ElfHeaderResult (names <> definition <> "\0")
$ Vector.snoc entries printEntry $ Vector.snoc entries nextEntry
encodeAsm shndx (encoded, relocations, ElfHeaderResult names symbols) instructions encodeAsm shndx (encoded, relocations, ElfHeaderResult names symbols, definitions) instructions
| Just (instruction, rest) <- Vector.uncons instructions = | Just (instruction, rest) <- Vector.uncons instructions =
case instruction of case instruction of
Instruction _ -> Instruction _ ->
let (encoded', relocations', rest') = let (encoded', relocations', rest', definitions') =
encodeInstructions (encoded, relocations, instructions) encodeInstructions (encoded, relocations, instructions, definitions)
in encodeAsm shndx (encoded', relocations', ElfHeaderResult names symbols) rest' in encodeAsm shndx (encoded', relocations', ElfHeaderResult names symbols, definitions') rest'
JumpLabel labelName _ -> JumpLabel labelName _ ->
let (encoded', relocations', rest') = let (encoded', relocations', rest', definitions') =
encodeInstructions (encoded, relocations, rest) encodeInstructions (encoded, relocations, rest, definitions)
newEntry = Elf32_Sym newEntry = Elf32_Sym
{ st_value = fromIntegral $ LazyByteString.length encoded { st_value = fromIntegral $ LazyByteString.length encoded
, st_size = fromIntegral $ LazyByteString.length encoded' , st_size = fromIntegral $ LazyByteString.length encoded'
@ -232,10 +239,11 @@ riscv32Elf code objectHandle = text
( encoded <> encoded' ( encoded <> encoded'
, relocations <> relocations' , relocations <> relocations'
, ElfHeaderResult (names <> labelName <> "\0") (Vector.snoc symbols newEntry) , ElfHeaderResult (names <> labelName <> "\0") (Vector.snoc symbols newEntry)
, definitions'
) )
in encodeAsm shndx result rest' in encodeAsm shndx result rest'
| otherwise = (encoded, relocations, ElfHeaderResult names symbols) | otherwise = (encoded, relocations, ElfHeaderResult names symbols, definitions)
encodeInstructions (encoded, relocations, instructions) encodeInstructions (encoded, relocations, instructions, definitions)
| Just (Instruction instruction, rest) <- Vector.uncons instructions = | Just (Instruction instruction, rest) <- Vector.uncons instructions =
let offset = fromIntegral $ LazyByteString.length encoded let offset = fromIntegral $ LazyByteString.length encoded
unresolvedRelocation = case instruction of unresolvedRelocation = case instruction of
@ -259,6 +267,10 @@ riscv32Elf code objectHandle = text
( encoded <> chunk ( encoded <> chunk
, maybe relocations (Vector.snoc relocations) unresolvedRelocation , maybe relocations (Vector.snoc relocations) unresolvedRelocation
, rest , rest
, addDefinition unresolvedRelocation definitions
) )
in encodeInstructions result in encodeInstructions result
| otherwise = (encoded, relocations, Vector.drop 1 instructions) | otherwise = (encoded, relocations, Vector.drop 1 instructions, definitions)
addDefinition (Just (UnresolvedRelocation symbolName _ _)) =
HashSet.insert symbolName
addDefinition Nothing = id

View File

@ -20,8 +20,9 @@ import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty
import Data.Maybe (isJust) import Data.Maybe (isJust)
import Data.Vector (Vector) import Data.Vector (Vector)
import qualified Data.Vector as Vector
import Language.Elna.Location (Identifier(..)) import Language.Elna.Location (Identifier(..))
import Language.Elna.Types (Type(..), intType, booleanType) import Language.Elna.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)
@ -39,7 +40,7 @@ scope parent (SymbolTable _ mappings) = SymbolTable (Just parent) mappings
builtInSymbolTable :: SymbolTable builtInSymbolTable :: SymbolTable
builtInSymbolTable = SymbolTable Nothing $ HashMap.fromList builtInSymbolTable = SymbolTable Nothing $ HashMap.fromList
[ ("boolean", TypeInfo booleanType) [ ("printi", ProcedureInfo empty Vector.empty)
, ("int", TypeInfo intType) , ("int", TypeInfo intType)
] ]

View File

@ -1,2 +1,3 @@
proc main() { proc main() {
printi(0);
} }

View File

@ -1,6 +1,3 @@
.global main
.type main, @function
.global printi .global printi
.type printi, @function .type printi, @function
@ -35,7 +32,7 @@ printi:
ret ret
_start: _start:
call "main" call main
addi a0, zero, 0 addi a0, zero, 0
addi a7, zero, 93 addi a7, zero, 93
ecall ecall