FUNCTION RETURN TYPES!!!!

This commit is contained in:
apio 2022-08-26 16:22:40 +02:00
parent 0d6651f813
commit 6ce5d406bb
5 changed files with 39 additions and 11 deletions

View File

@ -75,19 +75,19 @@ let @main in {
## Examples that actually work right now ## Examples that actually work right now
Exit with exit code 0 (success): Exit with exit code 0 (success):
``` ```
let @main in { let @main : i32 in {
0 0
} }
``` ```
Exit with non-zero exit code (failure): Exit with non-zero exit code (failure):
``` ```
let @main in { let @main : i32 in {
1 // or any other number 1 // or any other number
} }
``` ```
Exit with calculated exit code (yes, this language is a glorified calculator right now): Exit with calculated exit code (yes, this language is a glorified calculator right now):
``` ```
let @main in { let @main : i32 in {
3 + 5 * 6 // It doesn't even support parentheses, what a failure 3 + 5 * 6 // It doesn't even support parentheses, what a failure
} // the exit code is actually computed at compile time by LLVM (optimizations!!) } // the exit code is actually computed at compile time by LLVM (optimizations!!)
``` ```

View File

@ -8,6 +8,9 @@
Parser::Parser(const TokenStream& tokens) : tokens(tokens) Parser::Parser(const TokenStream& tokens) : tokens(tokens)
{ {
m_type_map = {{"void", llvm::Type::getVoidTy(*globalContext)}, {"bool", llvm::Type::getInt1Ty(*globalContext)},
{"i8", llvm::Type::getInt8Ty(*globalContext)}, {"i16", llvm::Type::getInt16Ty(*globalContext)},
{"i32", llvm::Type::getInt32Ty(*globalContext)}, {"i64", llvm::Type::getInt64Ty(*globalContext)}};
} }
std::shared_ptr<Parser> Parser::new_parser(const TokenStream& tokens) std::shared_ptr<Parser> Parser::new_parser(const TokenStream& tokens)
@ -101,8 +104,8 @@ Result<TopLevelNode> Parser::function()
{ {
FunctionPrototype proto; FunctionPrototype proto;
Token* start_token = current_token; Token* start_token = current_token;
proto.returnType = llvm::IntegerType::getInt32Ty(*globalContext); // FIXME: allow specifying return type proto.returnType = m_type_map["void"]; // FIXME: allow specifying return type
proto.arguments = {}; // FIXME: allow specifying arguments proto.arguments = {}; // FIXME: allow specifying arguments
if (current_token->type != TT_Let) return Err<TopLevelNode>("Expected let", current_token); if (current_token->type != TT_Let) return Err<TopLevelNode>("Expected let", current_token);
advance(); advance();
if (current_token->type != TT_At) return Err<TopLevelNode>("Expected @", current_token); if (current_token->type != TT_At) return Err<TopLevelNode>("Expected @", current_token);
@ -114,13 +117,37 @@ Result<TopLevelNode> Parser::function()
proto.name = current_token->string_value.value(); proto.name = current_token->string_value.value();
} }
advance(); advance();
if (current_token->type != TT_In && current_token->type != TT_Semicolon) if (current_token->type != TT_In && current_token->type != TT_Semicolon && current_token->type != TT_Colon)
return Err<TopLevelNode>("Expected 'in' or semicolon", current_token); return Err<TopLevelNode>("Expected 'in', colon or semicolon", current_token);
if (current_token->type == TT_Semicolon) if (current_token->type == TT_Semicolon)
{ {
advance(); advance();
return Ok<TopLevelNode>(new EmptyFunctionNode(proto), start_token); return Ok<TopLevelNode>(new EmptyFunctionNode(proto), start_token);
} }
if (current_token->type == TT_Colon)
{
advance();
if (current_token->type != TT_Identifier)
{
return Err<TopLevelNode>("Expected type name", current_token);
}
try
{
proto.returnType = m_type_map.at(current_token->string_value.value());
}
catch (std::out_of_range)
{
return Err<TopLevelNode>("Expected type name", current_token);
}
advance();
if (current_token->type != TT_In && current_token->type != TT_Semicolon)
return Err<TopLevelNode>("Expected 'in' or semicolon", current_token);
if (current_token->type == TT_Semicolon)
{
advance();
return Ok<TopLevelNode>(new EmptyFunctionNode(proto), start_token);
}
}
advance(); advance();
if (current_token->type != TT_LBracket) if (current_token->type != TT_LBracket)
return Err<TopLevelNode>("Invalid syntax", return Err<TopLevelNode>("Invalid syntax",

View File

@ -6,6 +6,7 @@
#include "Lexer.h" #include "Lexer.h"
#include "Result.h" #include "Result.h"
#include "sapphirepch.h" #include "sapphirepch.h"
#include "llvm/IR/Type.h"
/* Parser class for the Sapphire compiler. */ /* Parser class for the Sapphire compiler. */
class Parser class Parser
@ -17,6 +18,8 @@ class Parser
int advance(); int advance();
Token* current_token; Token* current_token;
std::unordered_map<std::string, llvm::Type*> m_type_map;
Result<ExprNode> factor(); Result<ExprNode> factor();
Result<ExprNode> expr(); Result<ExprNode> expr();
Result<ExprNode> term(); Result<ExprNode> term();

View File

@ -1,3 +1,3 @@
let @main in { let @main : i32 in {
1 + 3 * 5 1 + 3 * 5
} }

View File

@ -1,9 +1,7 @@
{ {
"file": "wimport.sp", "file": "wimport.sp",
"compile": { "compile": {
"flags": [ "flags": [],
"--wimport"
],
"exit-code": 1, "exit-code": 1,
"stdout": "", "stdout": "",
"stderr": "\u001b[1;1mtests/wimport.sp:1:1: \u001b[31;49merror: \u001b[0;0mExpected let\n1 \n \u001b[31;49m^\u001b[0;0m\n" "stderr": "\u001b[1;1mtests/wimport.sp:1:1: \u001b[31;49merror: \u001b[0;0mExpected let\n1 \n \u001b[31;49m^\u001b[0;0m\n"