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
Exit with exit code 0 (success):
```
let @main in {
let @main : i32 in {
0
}
```
Exit with non-zero exit code (failure):
```
let @main in {
let @main : i32 in {
1 // or any other number
}
```
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
} // 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)
{
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)
@ -101,8 +104,8 @@ Result<TopLevelNode> Parser::function()
{
FunctionPrototype proto;
Token* start_token = current_token;
proto.returnType = llvm::IntegerType::getInt32Ty(*globalContext); // FIXME: allow specifying return type
proto.arguments = {}; // FIXME: allow specifying arguments
proto.returnType = m_type_map["void"]; // FIXME: allow specifying return type
proto.arguments = {}; // FIXME: allow specifying arguments
if (current_token->type != TT_Let) return Err<TopLevelNode>("Expected let", current_token);
advance();
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();
}
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_In && current_token->type != TT_Semicolon && current_token->type != TT_Colon)
return Err<TopLevelNode>("Expected 'in', colon or semicolon", current_token);
if (current_token->type == TT_Semicolon)
{
advance();
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();
if (current_token->type != TT_LBracket)
return Err<TopLevelNode>("Invalid syntax",

View File

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

View File

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

View File

@ -1,9 +1,7 @@
{
"file": "wimport.sp",
"compile": {
"flags": [
"--wimport"
],
"flags": [],
"exit-code": 1,
"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"