From 3d1865de59bebfa70041ddf538721a934c1a39ba Mon Sep 17 00:00:00 2001 From: Pasha Bibko <156938226+PashaBibko@users.noreply.github.com> Date: Mon, 11 Aug 2025 17:46:58 +0100 Subject: [PATCH] Finished parser functions Time for fixing bugs YAYYYYYYYYYYY --- LXC/LXC.cpp | 2 +- examples/Basic.lx | 6 +++ parser/src/Parser.cpp | 102 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 examples/Basic.lx diff --git a/LXC/LXC.cpp b/LXC/LXC.cpp index 8164298..61ac09f 100644 --- a/LXC/LXC.cpp +++ b/LXC/LXC.cpp @@ -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); diff --git a/examples/Basic.lx b/examples/Basic.lx new file mode 100644 index 0000000..334383e --- /dev/null +++ b/examples/Basic.lx @@ -0,0 +1,6 @@ +func main() +{ + int: res = 5 + 34 + + return res +} diff --git a/parser/src/Parser.cpp b/parser/src/Parser.cpp index 23aae2a..1c77059 100644 --- a/parser/src/Parser.cpp +++ b/parser/src/Parser.cpp @@ -109,7 +109,7 @@ namespace PashaBibko::LXC::Parser static Util::ReturnVal 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(arg.Error()); + arguments.push_back(std::move(arg.Result())); } } @@ -138,18 +141,99 @@ namespace PashaBibko::LXC::Parser return ParsePrimary(ctx); } - static Util::ReturnVal ParseOperation(ParserContext& ctx) - {} + static Util::ReturnVal ParseOperation(ParserContext& ctx) + { + // Parses the left hand side of the operation // + Util::ReturnVal lhs = ParseFunctionCall(ctx); + if (lhs.Failed()) + return Util::FunctionFail(lhs.Error()); + + // Checks if the left hand side was part of an operation // + const Lexer::Token* operand = ctx.At(); + if (operand != nullptr && Lexer::Token::IsTypeClass(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(rhs.Error()); + + // Else the sides can be returned as an operation // + return Internal::CreateNodeV(lhs.Result(), operand->type, rhs.Result()); + } + + // If not returns the left node on its own // + return std::move(lhs.Result()); + } static Util::ReturnVal ParseReturn(ParserContext& ctx) - {} + { + // Checks if it is at a return statement // + const Lexer::Token* at = ctx.At(); + if (at == nullptr) + return Util::FunctionFail(); // <- 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(returnVal.Error()); + + return Internal::CreateNode(returnVal.Result()); + } + + // Else traverses down the call stack (has to be upcasted) // + Util::ReturnVal value = ParseOperation(ctx); + if (value.Failed()) + return Util::FunctionFail(value.Error()); + + AST::NodePtr upcast = std::move(value.Result()); + return upcast; + } static Util::ReturnVal ParseVarDeclaration(ParserContext& ctx) - {} - - static Util::ReturnVal 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(); // <- TODO: Make an actual error + + if (varName->type != Lexer::Token::Identifier) + return Util::FunctionFail(); // <- 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(varNameStr); + + if (varAssign->type != Lexer::Token::Assign) + return Internal::CreateNode(varNameStr); + + // Creates a node with the default value of the variable // + ctx.Advance(); + Util::ReturnVal defaultVal = ParseOperation(ctx); + if (defaultVal.Failed()) + return Util::FunctionFail(defaultVal.Error()); + + return Internal::CreateNode(varNameStr, defaultVal.Result()); + } + + // Else traverses up the call stack // + return ParseReturn(ctx); + } + + static inline Util::ReturnVal Parse(ParserContext& ctx) + { + // Alias for the top of the call stack // + return ParseVarDeclaration(ctx); } static Util::ReturnVal ParseFunction(ParserContext& ctx)