From a77d5bd129ecc3b7bc1890a2ec816201714010fe Mon Sep 17 00:00:00 2001 From: Pasha Bibko <156938226+PashaBibko@users.noreply.github.com> Date: Mon, 4 Aug 2025 13:16:08 +0100 Subject: [PATCH] Updated function signatures --- LXC/LXC.cpp | 4 +++ Lexer/src/Lexer.cpp | 61 +++++++++++++++++++++++++--------------- examples/Fib.lx | 2 +- examples/LawsOfMath.lx | 2 +- parser/inc/Parser.h | 22 +++++++++++++-- parser/src/Parser.cpp | 56 +++++++++++++----------------------- tests/src/LexerTests.cpp | 2 -- 7 files changed, 83 insertions(+), 66 deletions(-) diff --git a/LXC/LXC.cpp b/LXC/LXC.cpp index f93b139..6d0cdc9 100644 --- a/LXC/LXC.cpp +++ b/LXC/LXC.cpp @@ -71,6 +71,10 @@ int main(int argc, char** argv) { Util::Stop(); } + else + { + Util::PrintContainer("Function AST", functionsAST.Result()); + } return 0; } diff --git a/Lexer/src/Lexer.cpp b/Lexer/src/Lexer.cpp index 7d0cf23..a7e4043 100644 --- a/Lexer/src/Lexer.cpp +++ b/Lexer/src/Lexer.cpp @@ -15,17 +15,22 @@ namespace LXC::Internal return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } - bool IsWhitespace(const char c) + static constexpr bool IsWhitespace(const char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r'; } - static constexpr bool IsSymbolOrOperator(const char c) + static constexpr bool IsOperator(const char c) { return c == '+' || c == '-' || c == '*' || c == '/' || - c == '%' || c == '=' || + c == '%' || c == '='; + } + + static constexpr bool IsSymbol(const char c) + { + return c == ',' || c == '[' || c == ']' || c == '{' || c == '}' || c == '(' || @@ -33,7 +38,7 @@ namespace LXC::Internal c == '>'; } - static const std::unordered_map symbolAndOpMap = + static const std::unordered_map operatorMap = { { "+", Lexer::Token::Add }, { "-", Lexer::Token::Sub }, @@ -43,20 +48,24 @@ namespace LXC::Internal { "==", Lexer::Token::Eql }, - { "=", Lexer::Token::Assign }, - { ",", Lexer::Token::Comma }, + { "=", Lexer::Token::Assign } + }; - { "[", Lexer::Token::CloseBracket }, - { "]", Lexer::Token::OpenBracket }, + static const std::unordered_map symbolMap = + { + { ',', Lexer::Token::Comma }, - { "}", Lexer::Token::CloseBrace }, - { "{", Lexer::Token::OpenBrace }, + { '[', Lexer::Token::CloseBracket }, + { ']', Lexer::Token::OpenBracket }, - { ")", Lexer::Token::CloseParen }, - { "(", Lexer::Token::OpenParen }, + { '}', Lexer::Token::CloseBrace }, + { '{', Lexer::Token::OpenBrace }, - { ">", Lexer::Token::CloseCrocodile }, - { "<", Lexer::Token::OpenCrocodile } + { ')', Lexer::Token::CloseParen }, + { '(', Lexer::Token::OpenParen }, + + { '>', Lexer::Token::CloseCrocodile }, + { '<', Lexer::Token::OpenCrocodile } }; static const std::unordered_map keywords = @@ -87,7 +96,7 @@ namespace LXC::Lexer bool inStrLiteral = false; bool inIdentifier = false; bool inNumLiteral = false; - bool inSymbolOrOp = false; + bool inOperator = false; bool inComment = false; @@ -155,22 +164,22 @@ namespace LXC::Lexer } } - // === Symbols/Operators === // - else if (Internal::IsSymbolOrOperator(current)) + // === Operators === // + else if (Internal::IsOperator(current)) { // Updates trackers // - trackers.sectionStart = trackers.inSymbolOrOp ? trackers.sectionStart : ctx.index; - trackers.inSymbolOrOp = true; + trackers.sectionStart = trackers.inOperator ? trackers.sectionStart : ctx.index; + trackers.inOperator = true; // Checks for the end of the symbol or operator // - if (!Internal::IsSymbolOrOperator(next)) _LIKELY + if (!Internal::IsOperator(next)) _LIKELY { - trackers.inSymbolOrOp = false; + trackers.inOperator = false; // Finds the operator/symbol if it can // std::string_view fullSymbol(ctx.source.data() + trackers.sectionStart, ctx.index - trackers.sectionStart + 1); - auto it = Internal::symbolAndOpMap.find(fullSymbol); - if (it != Internal::symbolAndOpMap.end()) + auto it = Internal::operatorMap.find(fullSymbol); + if (it != Internal::operatorMap.end()) ctx.out.emplace_back(ctx, trackers.sectionStart, (unsigned short)(ctx.index - trackers.sectionStart + 1), it->second); else @@ -178,6 +187,12 @@ namespace LXC::Lexer } } + // === Symbols === // + else if (Internal::IsSymbol(current)) + { + ctx.out.emplace_back(ctx, ctx.index, 1, Internal::symbolMap.at(current)); + } + // === Whitespace === // else if (Internal::IsWhitespace(current)) _LIKELY {} diff --git a/examples/Fib.lx b/examples/Fib.lx index 274b691..afc334e 100644 --- a/examples/Fib.lx +++ b/examples/Fib.lx @@ -8,7 +8,7 @@ func fib(int num) return fib(n - 1) + fib(n - 2) } -func main(void) +func main() { int res = fib(8) return res == 21 diff --git a/examples/LawsOfMath.lx b/examples/LawsOfMath.lx index 7cce011..f25be8d 100644 --- a/examples/LawsOfMath.lx +++ b/examples/LawsOfMath.lx @@ -3,7 +3,7 @@ func add(int a, int b) return a + b } -func main(void) +func main() { int c = add(3, 4) if (c == 7) diff --git a/parser/inc/Parser.h b/parser/inc/Parser.h index e9f196e..bc95400 100644 --- a/parser/inc/Parser.h +++ b/parser/inc/Parser.h @@ -12,15 +12,33 @@ namespace LXC::Parser struct FunctionAST { FunctionAST() : - name{}, contents{} + name{}, contents{}, funcParams{} {} FunctionAST(FunctionAST&& other) noexcept : - name{}, contents{} + name(std::move(other.name)), contents(std::move(other.contents)), funcParams(std::move(other.funcParams)) {} std::string name; + std::vector> funcParams; + AST::SyntaxBranch contents; + + std::string LogStr() const + { + std::ostringstream os; + os << name << " ("; + + for (size_t i = 0; i < funcParams.size(); i++) + { + os << funcParams[i].first << ' ' << funcParams[i].second; + if (i != funcParams.size() - 1) + os << ", "; + } + + os << ")"; + return os.str(); + } }; Util::ReturnVal, ParserError> TurnTokensIntoAST(const Lexer::LexerOutput& input); diff --git a/parser/src/Parser.cpp b/parser/src/Parser.cpp index 409834a..3e07136 100644 --- a/parser/src/Parser.cpp +++ b/parser/src/Parser.cpp @@ -63,39 +63,6 @@ namespace LXC::Parser const size_t length; }; - static void ParseBlock(ParserContext& ctx) - { - // Local lamdba for working out if at the end (static to avoid double initalisation) // - static const std::function AtEnd = [](const ParserContext& context) - { - // Peeks the current tokens type // - const Lexer::Token* current = context.Peek(); - if (current != nullptr) - { - return current->type == Lexer::Token::CloseBrace; - } - - // If nullptr means it has overflowed so it is at the end // - return true; - }; - - // Loops over the body until it reaches the end // - while (!AtEnd(ctx)) - { - // Force ends if it has gone over the end of the tokens // - const Lexer::Token* current = ctx.Advance(); - if (current != nullptr) - { - // Recurses if at the start of another block // - if (current->type == Lexer::Token::OpenBrace) - ParseBlock(ctx); - } - } - - // Advances over the ending close brace // - ctx.Advance(); - } - static Util::ReturnVal ParseFunction(ParserContext& ctx) { // Checks for the sequence of: func funcName( // @@ -130,6 +97,8 @@ namespace LXC::Parser const Lexer::Token* paramType = ctx.At(); const Lexer::Token* paramName = ctx.Advance(); + currentFunction.funcParams.emplace_back(paramType->Str(), paramName->Str()); + // Expects a comma or close bracket for the next token // const Lexer::Token* end = ctx.Advance(); if (end == nullptr) @@ -143,10 +112,21 @@ namespace LXC::Parser } // Parses the function body // - ParseBlock(ctx); - ctx.Advance(); // <- Goes over the closing brace - - return currentFunction; + const Lexer::Token* current = ctx.At(); + while (current != nullptr) + { + if (current->type == Lexer::Token::CloseBrace) + { + // Advances over closing brace before returning the function // + ctx.Advance(); + return currentFunction; + } + + // Advances to the next token // + current = ctx.Advance(); + } + + return Util::FunctionFail(); // <- TODO: Make an actual error } Util::ReturnVal, ParserError> TurnTokensIntoAST(const Lexer::LexerOutput& input) @@ -171,6 +151,8 @@ namespace LXC::Parser if (func.Failed()) return Util::FunctionFail(func.Error()); + ctx.output.emplace_back(std::move(func.Result())); + break; } diff --git a/tests/src/LexerTests.cpp b/tests/src/LexerTests.cpp index 9f1254f..4684094 100644 --- a/tests/src/LexerTests.cpp +++ b/tests/src/LexerTests.cpp @@ -148,7 +148,6 @@ namespace LXC::Lexer Token::CloseCrocodile, // > Token::Identifier, // main Token::OpenParen, // ( - Token::Identifier, // void Token::CloseParen, // ) Token::OpenBrace, // { Token::Identifier, // int @@ -243,7 +242,6 @@ namespace LXC::Lexer Token::CloseCrocodile, // > Token::Identifier, // main Token::OpenParen, // ( - Token::Identifier, // void Token::CloseParen, // ) Token::OpenBrace, // {