Finished parser functions
Time for fixing bugs YAYYYYYYYYYYY
This commit is contained in:
@@ -9,7 +9,7 @@ int main(int argc, char** argv)
|
||||
using namespace PashaBibko::LXC;
|
||||
using namespace PashaBibko;
|
||||
|
||||
std::filesystem::path src = "examples/Fib.lx";
|
||||
std::filesystem::path src = "examples/Basic.lx";
|
||||
|
||||
// Reads the given file to a string //
|
||||
Util::ReturnVal fileContents = Util::ReadFile(src);
|
||||
|
||||
6
examples/Basic.lx
Normal file
6
examples/Basic.lx
Normal file
@@ -0,0 +1,6 @@
|
||||
func<int> main()
|
||||
{
|
||||
int: res = 5 + 34
|
||||
|
||||
return res
|
||||
}
|
||||
@@ -109,7 +109,7 @@ namespace PashaBibko::LXC::Parser
|
||||
static Util::ReturnVal<AST::NodeValuePtr, ParserError> ParseFunctionCall(ParserContext& ctx)
|
||||
{
|
||||
// Checks if the upcoming pattern matches a function signature: [Identifier(function name), OpenBracket(Start of params)] //
|
||||
if (!ctx.Expect(std::array{ Lexer::Token::Identifier, Lexer::Token::OpenParen }))
|
||||
if (ctx.Expect(std::array{ Lexer::Token::Identifier, Lexer::Token::OpenParen }))
|
||||
{
|
||||
// Captures the function name and advances over it and the start paren //
|
||||
const Lexer::Token* functionNameToken = ctx.At();
|
||||
@@ -130,7 +130,10 @@ namespace PashaBibko::LXC::Parser
|
||||
ctx.Advance();
|
||||
|
||||
// Adds the current argument to the ValueList //
|
||||
arguments.push_back(std::move(ParsePrimary(ctx).Result()));
|
||||
Util::ReturnVal arg = ParsePrimary(ctx);
|
||||
if (arg.Failed())
|
||||
return Util::FunctionFail<ParserError>(arg.Error<Util::Result::Force>());
|
||||
arguments.push_back(std::move(arg.Result<Util::Result::Force>()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,18 +141,99 @@ namespace PashaBibko::LXC::Parser
|
||||
return ParsePrimary(ctx);
|
||||
}
|
||||
|
||||
static Util::ReturnVal<AST::NodePtr, ParserError> ParseOperation(ParserContext& ctx)
|
||||
{}
|
||||
static Util::ReturnVal<AST::NodeValuePtr, ParserError> ParseOperation(ParserContext& ctx)
|
||||
{
|
||||
// Parses the left hand side of the operation //
|
||||
Util::ReturnVal lhs = ParseFunctionCall(ctx);
|
||||
if (lhs.Failed())
|
||||
return Util::FunctionFail<ParserError>(lhs.Error<Util::Result::Force>());
|
||||
|
||||
// Checks if the left hand side was part of an operation //
|
||||
const Lexer::Token* operand = ctx.At();
|
||||
if (operand != nullptr && Lexer::Token::IsTypeClass<Lexer::TokenClass::Operator>(operand->type))
|
||||
{
|
||||
// Iterates over the operand and parses the right hand side of the operation //
|
||||
ctx.Advance();
|
||||
Util::ReturnVal rhs = ParseOperation(ctx);
|
||||
if (rhs.Failed())
|
||||
return Util::FunctionFail<ParserError>(rhs.Error<Util::Result::Force>());
|
||||
|
||||
// Else the sides can be returned as an operation //
|
||||
return Internal::CreateNodeV<AST::Operation>(lhs.Result<Util::Result::Force>(), operand->type, rhs.Result<Util::Result::Force>());
|
||||
}
|
||||
|
||||
// If not returns the left node on its own //
|
||||
return std::move(lhs.Result<Util::Result::Force>());
|
||||
}
|
||||
|
||||
static Util::ReturnVal<AST::NodePtr, ParserError> ParseReturn(ParserContext& ctx)
|
||||
{}
|
||||
{
|
||||
// Checks if it is at a return statement //
|
||||
const Lexer::Token* at = ctx.At();
|
||||
if (at == nullptr)
|
||||
return Util::FunctionFail<ParserError>(); // <- TODO: Make an actual error
|
||||
|
||||
if (at->type == Lexer::Token::Return)
|
||||
{
|
||||
// Iterates over the return token and parses the value to be returned //
|
||||
ctx.Advance();
|
||||
Util::ReturnVal returnVal = ParseOperation(ctx);
|
||||
if (returnVal.Failed())
|
||||
return Util::FunctionFail<ParserError>(returnVal.Error<Util::Result::Force>());
|
||||
|
||||
return Internal::CreateNode<AST::ReturnStatement>(returnVal.Result<Util::Result::Force>());
|
||||
}
|
||||
|
||||
// Else traverses down the call stack (has to be upcasted) //
|
||||
Util::ReturnVal value = ParseOperation(ctx);
|
||||
if (value.Failed())
|
||||
return Util::FunctionFail<ParserError>(value.Error());
|
||||
|
||||
AST::NodePtr upcast = std::move(value.Result<Util::Result::Force>());
|
||||
return upcast;
|
||||
}
|
||||
|
||||
static Util::ReturnVal<AST::NodePtr, ParserError> ParseVarDeclaration(ParserContext& ctx)
|
||||
{}
|
||||
|
||||
static Util::ReturnVal<AST::NodePtr, ParserError> Parse(ParserContext& ctx)
|
||||
{
|
||||
return (AST::NodePtr)nullptr;
|
||||
// Checks for the pattern of a variable declaration //
|
||||
if (ctx.Expect(std::array{ Lexer::Token::Identifier, Lexer::Token::Colon }))
|
||||
{
|
||||
// Can safely advance over the pattern (types are not checked/stored yet) //
|
||||
ctx.Advance(2);
|
||||
|
||||
const Lexer::Token* varName = ctx.At();
|
||||
std::string varNameStr = varName->Str();
|
||||
if (varName == nullptr)
|
||||
return Util::FunctionFail<ParserError>(); // <- TODO: Make an actual error
|
||||
|
||||
if (varName->type != Lexer::Token::Identifier)
|
||||
return Util::FunctionFail<ParserError>(); // <- TODO: Make an actual error
|
||||
|
||||
// Checks for a default value for the variable //
|
||||
const Lexer::Token* varAssign = ctx.Peek();
|
||||
if (varAssign == nullptr)
|
||||
return Internal::CreateNode<AST::VarDeclaration>(varNameStr);
|
||||
|
||||
if (varAssign->type != Lexer::Token::Assign)
|
||||
return Internal::CreateNode<AST::VarDeclaration>(varNameStr);
|
||||
|
||||
// Creates a node with the default value of the variable //
|
||||
ctx.Advance();
|
||||
Util::ReturnVal defaultVal = ParseOperation(ctx);
|
||||
if (defaultVal.Failed())
|
||||
return Util::FunctionFail<ParserError>(defaultVal.Error<Util::Result::Force>());
|
||||
|
||||
return Internal::CreateNode<AST::VarDeclaration>(varNameStr, defaultVal.Result<Util::Result::Force>());
|
||||
}
|
||||
|
||||
// Else traverses up the call stack //
|
||||
return ParseReturn(ctx);
|
||||
}
|
||||
|
||||
static inline Util::ReturnVal<AST::NodePtr, ParserError> Parse(ParserContext& ctx)
|
||||
{
|
||||
// Alias for the top of the call stack //
|
||||
return ParseVarDeclaration(ctx);
|
||||
}
|
||||
|
||||
static Util::ReturnVal<FunctionAST, ParserError> ParseFunction(ParserContext& ctx)
|
||||
|
||||
Reference in New Issue
Block a user