From 26d476e9e3b9a42dce2657e1a680a93613adf008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Sun, 1 Jun 2025 16:18:51 +0900 Subject: [PATCH] wip --- src/Parser.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++---- src/Parser.h | 6 +++++- src/Statement.cpp | 14 ++++++++++++- src/Statement.h | 7 ++++++- 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/Parser.cpp b/src/Parser.cpp index bb8adbb..1f66b36 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -32,8 +32,41 @@ shared_ptr Parser::nextStatement() { return matchInvalidStatement(); } +shared_ptr Parser::matchFunctionDeclarationStatement() { + if (!matchesTokenKinds({Token::Kind::IDENTIFIER, Token::Kind::COLON, Token::Kind::FUNCTION})) + return make_shared(Statement::Kind::INVALID, make_shared(tokens.at(currentIndex)), nullptr, nullptr, { }, ""); + + Token identifierToken = tokens.at(currentIndex); + currentIndex++; + currentIndex++; // skip colon + currentIndex++; // skip fun + + while (tokens.at(currentIndex).getKind() != Token::Kind::NEW_LINE) { + currentIndex++; + } + currentIndex++; // new line + shared_ptr blockStatement = matchBlockStatement(); + if (!blockStatement->isValid()) + return blockStatement; + + return make_shared(Statement::Kind::FUNCTION_DECLARATION, nullptr, nullptr, blockStatement, { }, identifierToken.getLexme()); +} + +shared_ptr Parser::matchBlockStatement() { + vector> statements; + + while (tokens.at(currentIndex).getKind() != Token::Kind::SEMICOLON) { + shared_ptr statement = nextStatement(); + if (!statement->isValid()) + return statement; + statements.push_back(statement); + } + currentIndex++; // skip ; + return make_shared(Statement::Kind::BLOCK, nullptr, nullptr, nullptr, statements, ""); +} + shared_ptr Parser::matchInvalidStatement() { - return make_shared(Statement::Kind::INVALID, make_shared(tokens.at(currentIndex)), nullptr); + return make_shared(Statement::Kind::INVALID, make_shared(tokens.at(currentIndex)), nullptr, nullptr, { }, ""); } // @@ -43,9 +76,9 @@ shared_ptr Parser::matchExpressionStatement() { shared_ptr expression = term(); if (expression->isValid() && tokens.at(currentIndex).isOfKind({Token::Kind::NEW_LINE, Token::Kind::END})) { currentIndex++; - return make_shared(Statement::Kind::EXPRESSION, nullptr, expression); + return make_shared(Statement::Kind::EXPRESSION, nullptr, expression, nullptr, { }, ""); } else { - return make_shared(Statement::Kind::INVALID, make_shared(tokens.at(currentIndex)), expression); + return make_shared(Statement::Kind::INVALID, make_shared(tokens.at(currentIndex)), expression, nullptr, { }, ""); } } @@ -128,4 +161,15 @@ shared_ptr Parser::matchBinary(shared_ptr left) { } return make_shared(Expression::Kind::INVALID, token, nullptr, nullptr); -} \ No newline at end of file +} + +bool Parser::matchesTokenKinds(vector kinds) { + if (currentIndex + kinds.size() >= tokens.size()) + return false; + + for (int i=0; i nextStatement(); - shared_ptr matchInvalidStatement() ; + shared_ptr matchFunctionDeclarationStatement(); + shared_ptr matchBlockStatement(); + shared_ptr matchInvalidStatement(); shared_ptr matchExpressionStatement(); shared_ptr term(); // +, - @@ -26,6 +28,8 @@ private: shared_ptr matchGrouping(); shared_ptr matchBinary(shared_ptr left); + bool matchesTokenKinds(vector kinds); + public: Parser(vector tokens); vector> getStatements(); diff --git a/src/Statement.cpp b/src/Statement.cpp index f612eea..d54d652 100644 --- a/src/Statement.cpp +++ b/src/Statement.cpp @@ -1,6 +1,7 @@ #include "Statement.h" -Statement::Statement(Kind kind, shared_ptr token, shared_ptr expression): kind(kind), token(token), expression(expression) { +Statement::Statement(Kind kind, shared_ptr token, shared_ptr expression, shared_ptr blockStatement, vector> statements, string name): + kind(kind), token(token), expression(expression), blockStatement(blockStatement), statements(statements), name(name) { } shared_ptr Statement::getExpression() { @@ -19,6 +20,17 @@ string Statement::toString() { switch (kind) { case EXPRESSION: return expression->toString(); + case BLOCK: { + string value; + for (int i=0; itoString(); + if (i < statements.size() - 1) + value += "\n"; + } + return value; + } + case FUNCTION_DECLARATION: + return "FUNCTION " + name + "\n" + blockStatement->toString() + "\n;"; case INVALID: return "INVALID"; } diff --git a/src/Statement.h b/src/Statement.h index aeef197..070719f 100644 --- a/src/Statement.h +++ b/src/Statement.h @@ -12,6 +12,8 @@ class Statement { public: enum Kind { EXPRESSION, + BLOCK, + FUNCTION_DECLARATION, INVALID }; @@ -19,9 +21,12 @@ private: Kind kind; shared_ptr token; shared_ptr expression; + shared_ptr blockStatement; + vector> statements; + string name; public: - Statement(Kind kind, shared_ptr token, shared_ptr expression); + Statement(Kind kind, shared_ptr token, shared_ptr expression, shared_ptr blockStatement, vector> statements, string name); shared_ptr getToken(); shared_ptr getExpression(); bool isValid();