diff --git a/samples/test.brc b/samples/test.brc index 9fabe98..1862622 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -33,10 +33,10 @@ i u32 <- 0, rep text[i] != 0: mov $0, $1 ;*/ -rawAdd raw: num1 sint32, num2 sint32 -> sint32 +/*rawAdd raw: num1 sint32, num2 sint32 -> sint32 add $1, $2 mov $0, $1 -; +;*/ /*printChar raw .global REGISTER @@ -54,5 +54,5 @@ main fun -> sint32 //res1 sint32 <- normAdd(4, 5) //res2 sint32 <- rawAdd(4, 5) - ret 0 + ret 2- ; \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.cpp b/src/Parser/Parsee/Parsee.cpp index 292e997..dc8c526 100644 --- a/src/Parser/Parsee/Parsee.cpp +++ b/src/Parser/Parsee/Parsee.cpp @@ -1,20 +1,29 @@ #include "Parsee.h" +#include "Parser/Expression/Expression.h" + Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn) { Parsee parsee; parsee.kind = ParseeKind::TOKEN; parsee.tokenKind = tokenKind; parsee.isRequired = isRequired; parsee.shouldReturn = shouldReturn; - return parsee; } -Parsee Parsee::valueTypeParsee() { +Parsee Parsee::valueTypeParsee(bool isRequired) { Parsee parsee; parsee.kind = ParseeKind::VALUE_TYPE; + parsee.isRequired = isRequired; parsee.shouldReturn = true; + return parsee; +} +Parsee Parsee::expressionParsee(bool isRequired) { + Parsee parsee; + parsee.kind = ParseeKind::EXPRESSION; + parsee.isRequired = isRequired; + parsee.shouldReturn = true; return parsee; } diff --git a/src/Parser/Parsee/Parsee.h b/src/Parser/Parsee/Parsee.h index dc7cfd4..9b1db48 100644 --- a/src/Parser/Parsee/Parsee.h +++ b/src/Parser/Parsee/Parsee.h @@ -1,11 +1,15 @@ #ifndef PARSEE_H #define PARSEE_H +#include + enum class TokenKind; +class Expression; enum class ParseeKind { TOKEN, - VALUE_TYPE + VALUE_TYPE, + EXPRESSION }; class Parsee { @@ -18,7 +22,8 @@ private: public: static Parsee tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn); - static Parsee valueTypeParsee(); + static Parsee valueTypeParsee(bool isRequired); + static Parsee expressionParsee(bool isRequired); ParseeKind getKind(); TokenKind getTokenKind(); diff --git a/src/Parser/Parsee/ParseeGroup.cpp b/src/Parser/Parsee/ParseeGroup.cpp index debd442..81e7b81 100644 --- a/src/Parser/Parsee/ParseeGroup.cpp +++ b/src/Parser/Parsee/ParseeGroup.cpp @@ -2,8 +2,8 @@ #include "Parsee.h" -ParseeGroup::ParseeGroup(bool isRequired, vector parsees, optional repeatedGroup): -isRequired(isRequired), parsees(parsees) { +ParseeGroup::ParseeGroup(/*bool isRequired, */vector parsees, optional repeatedGroup): +/*isRequired(isRequired), */parsees(parsees) { if (repeatedGroup) { this->repeatedGroup = *repeatedGroup; } else { @@ -11,9 +11,9 @@ isRequired(isRequired), parsees(parsees) { } } -bool ParseeGroup::getIsRequired() { +/*bool ParseeGroup::getIsRequired() { return isRequired; -} +}*/ vector ParseeGroup::getParsees() { return parsees; diff --git a/src/Parser/Parsee/ParseeGroup.h b/src/Parser/Parsee/ParseeGroup.h index 0dfb4f8..62d2570 100644 --- a/src/Parser/Parsee/ParseeGroup.h +++ b/src/Parser/Parsee/ParseeGroup.h @@ -10,13 +10,13 @@ using namespace std; class ParseeGroup { private: - bool isRequired; + //bool isRequired; vector parsees; optional> repeatedGroup; public: - ParseeGroup(bool isRequired, vector parsees, optional repeatedGroup); - bool getIsRequired(); + ParseeGroup(/*bool isRequired, */vector parsees, optional repeatedGroup); + //bool getIsRequired(); vector getParsees(); optional> getRepeatedGroup(); }; diff --git a/src/Parser/Parsee/ParseeResult.cpp b/src/Parser/Parsee/ParseeResult.cpp index ce00984..5e09309 100644 --- a/src/Parser/Parsee/ParseeResult.cpp +++ b/src/Parser/Parsee/ParseeResult.cpp @@ -19,6 +19,14 @@ ParseeResult ParseeResult::valueTypeResult(shared_ptr valueType, int return parseeResult; } +ParseeResult ParseeResult::expressionResult(shared_ptr expression, int tokensCount) { + ParseeResult result; + result.kind = ParseeResultKind::EXPRESSION; + result.expression = expression; + result.tokensCount = tokensCount; + return result; +} + ParseeResult::ParseeResult() { } @@ -34,6 +42,10 @@ shared_ptr ParseeResult::getValueType() { return valueType; } +shared_ptr ParseeResult::getExpression() { + return expression; +} + int ParseeResult::getTokensCount() { return tokensCount; } \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeResult.h b/src/Parser/Parsee/ParseeResult.h index fb56d45..f59114e 100644 --- a/src/Parser/Parsee/ParseeResult.h +++ b/src/Parser/Parsee/ParseeResult.h @@ -5,12 +5,14 @@ class Token; class ValueType; +class Expression; using namespace std; enum class ParseeResultKind { TOKEN, VALUE_TYPE, + EXPRESSION }; class ParseeResult { @@ -18,16 +20,19 @@ private: ParseeResultKind kind; shared_ptr token; shared_ptr valueType; + shared_ptr expression; int tokensCount; ParseeResult(); public: static ParseeResult tokenResult(shared_ptr token); static ParseeResult valueTypeResult(shared_ptr valueType, int tokensCount); + static ParseeResult expressionResult(shared_ptr expression, int tokensCount); ParseeResultKind getKind(); shared_ptr getToken(); shared_ptr getValueType(); + shared_ptr getExpression(); int getTokensCount(); }; diff --git a/src/Parser/Parsee/ParseeResultsGroup.cpp b/src/Parser/Parsee/ParseeResultsGroup.cpp new file mode 100644 index 0000000..ca3cc9c --- /dev/null +++ b/src/Parser/Parsee/ParseeResultsGroup.cpp @@ -0,0 +1,30 @@ +#include "ParseeResultsGroup.h" + +#include "ParseeResult.h" + +ParseeResultsGroup ParseeResultsGroup::success(vector results) { + ParseeResultsGroup resultsGroup; + resultsGroup.kind = ParseeResultsGroupKind::SUCCESS; + resultsGroup.results = results; + return resultsGroup; +} + +ParseeResultsGroup ParseeResultsGroup::noMatch() { + ParseeResultsGroup resultsGroup; + resultsGroup.kind = ParseeResultsGroupKind::NO_MATCH; + return resultsGroup; +} + +ParseeResultsGroup ParseeResultsGroup::failure() { + ParseeResultsGroup resultsGroup; + resultsGroup.kind = ParseeResultsGroupKind::FAILURE; + return resultsGroup; +} + +ParseeResultsGroupKind ParseeResultsGroup::getKind() { + return kind; +} + +vector ParseeResultsGroup::getResults() { + return results; +} \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeResultsGroup.h b/src/Parser/Parsee/ParseeResultsGroup.h new file mode 100644 index 0000000..3ba23b4 --- /dev/null +++ b/src/Parser/Parsee/ParseeResultsGroup.h @@ -0,0 +1,30 @@ +#ifndef PARSEE_RESULTS_GROUP_H +#define PARSEE_RESULTS_GROUP_H + +#include + +class ParseeResult; + +using namespace std; + +enum class ParseeResultsGroupKind { + SUCCESS, + NO_MATCH, + FAILURE +}; + +class ParseeResultsGroup { +private: + ParseeResultsGroupKind kind; + vector results; + +public: + static ParseeResultsGroup success(vector results); + static ParseeResultsGroup noMatch(); + static ParseeResultsGroup failure(); + + ParseeResultsGroupKind getKind(); + vector getResults(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 5550800..25f2204 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -28,6 +28,7 @@ #include "Parsee/Parsee.h" #include "Parsee/ParseeGroup.h" #include "Parsee/ParseeResult.h" +#include "Parsee/ParseeResultsGroup.h" Parser::Parser(vector> tokens) : tokens(tokens) { } @@ -158,7 +159,7 @@ shared_ptr Parser::matchStatementMetaExternFunction() { } shared_ptr Parser::matchStatementVariable() { - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) + /*if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) return nullptr; shared_ptr identifierToken = tokens.at(currentIndex++); @@ -174,7 +175,43 @@ shared_ptr Parser::matchStatementVariable() { if (expression == nullptr) return nullptr; - return make_shared(identifierToken->getLexme(), valueType, expression); + return make_shared(identifierToken->getLexme(), valueType, expression);*/ + + ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::valueTypeParsee(true), + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), + Parsee::expressionParsee(true) + }, + { } + ) + ); + + if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) + return nullptr; + + string name = resultsGroup.getResults().at(0).getToken()->getLexme();// tokens.at(currentIndex++); + shared_ptr valueType = resultsGroup.getResults().at(1).getValueType(); + shared_ptr expression = resultsGroup.getResults().at(2).getExpression(); + + return make_shared(name, valueType, expression); + + /*optional> parseeResults = parseeResultsForParseeGroup( + ParseeGroup( + false, + { + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::valueTypeParsee(), + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), + Parsee::expressionParsee() + }, + { } + ) + ); + + optional> parseeResults = parseeResultsForParseeGroup(parseeGroup);*/ } shared_ptr Parser::matchStatementFunction() { @@ -227,7 +264,7 @@ shared_ptr Parser::matchStatementFunction() { } // block - statementBlock = matchStatementBlock({TokenKind::SEMICOLON}); + statementBlock = matchStatementBlock({TokenKind::SEMICOLON, TokenKind::END}); if (statementBlock == nullptr) return nullptr; @@ -240,7 +277,8 @@ shared_ptr Parser::matchStatementFunction() { } shared_ptr Parser::matchStatementRawFunction() { - bool hasError = false; + return nullptr; + /*bool hasError = false; optional> parseeResults; string name; @@ -295,7 +333,7 @@ shared_ptr Parser::matchStatementRawFunction() { Parsee::tokenParsee(TokenKind::COLON, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee() + Parsee::valueTypeParsee(true) }, ParseeGroup( false, @@ -303,7 +341,7 @@ shared_ptr Parser::matchStatementRawFunction() { Parsee::tokenParsee(TokenKind::COMMA, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee() + Parsee::valueTypeParsee(true) }, {} ) @@ -329,7 +367,7 @@ shared_ptr Parser::matchStatementRawFunction() { { Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::valueTypeParsee() + Parsee::valueTypeParsee(true) }, {} ) @@ -363,7 +401,7 @@ shared_ptr Parser::matchStatementRawFunction() { return nullptr; } - return make_shared(name, constraints, arguments, returnType, rawSource); + return make_shared(name, constraints, arguments, returnType, rawSource);*/ } shared_ptr Parser::matchStatementBlock(vector terminalTokenKinds) { @@ -418,13 +456,27 @@ shared_ptr Parser::matchStatementAssignment() { } shared_ptr Parser::matchStatementReturn() { - if (!tryMatchingTokenKinds({TokenKind::RETURN}, true, true)) - return nullptr; + shared_ptr expression; + + ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::RETURN, true, false), + Parsee::expressionParsee(false) + }, + { } + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + expression = !resultsGroup.getResults().empty() ? resultsGroup.getResults().at(0).getExpression() : nullptr; + break; + case ParseeResultsGroupKind::NO_MATCH: + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } - shared_ptr expression = nextExpression(); - if (expression == nullptr) - return nullptr; - return make_shared(expression); } @@ -521,7 +573,7 @@ shared_ptr Parser::nextExpression() { if (expression != nullptr || errors.size() > errorsCount) return expression; - markError({}, {}); + //markError({}, {}); return nullptr; } @@ -757,6 +809,7 @@ shared_ptr Parser::matchExpressionBinary(shared_ptr left } if (right == nullptr) { + markError({}, "Expected expression"); return nullptr; } else { return make_shared(token, left, right); @@ -827,7 +880,8 @@ shared_ptr Parser::matchValueType() { return ValueType::valueTypeForToken(typeToken, subType, valueArg); } -optional> Parser::parseeResultsForParseeGroup(ParseeGroup group) { +ParseeResultsGroup Parser::parseeResultsGroupForParseeGroup(ParseeGroup group) { + int errorsCount = errors.size(); int startIndex = currentIndex; vector results; bool mustFulfill = false; @@ -835,12 +889,83 @@ optional> Parser::parseeResultsForParseeGroup(ParseeGroup g for (Parsee &parsee : group.getParsees()) { optional result; switch (parsee.getKind()) { - case ParseeKind::TOKEN: - result = tokenParseeResult(currentIndex, parsee.getTokenKind()); - break; - case ParseeKind::VALUE_TYPE: - result = valueTypeParseeResult(currentIndex); - break; + case ParseeKind::TOKEN: + result = tokenParseeResult(currentIndex, parsee.getTokenKind()); + break; + case ParseeKind::VALUE_TYPE: + result = valueTypeParseeResult(currentIndex); + break; + case ParseeKind::EXPRESSION: + result = expressionParseeResult(currentIndex); + break; + } + + // generated an error? + if (errors.size() > errorsCount) + return ParseeResultsGroup::failure(); + + // if doesn't match on optional group + if (!result && parsee.getIsRequired() && !mustFulfill) { + currentIndex = startIndex; + //return vector(); + return ParseeResultsGroup::noMatch(); + } + + // return matching token? + if (result && parsee.getShouldReturn()) + results.push_back(*result); + + // decide if we're decoding the expected sequence + if (!parsee.getIsRequired() && currentIndex > startIndex) + mustFulfill = true; + + // invalid sequence detected? + if (!result && parsee.getIsRequired() && mustFulfill) { + markError(parsee.getTokenKind(), {}); + //return {}; + return ParseeResultsGroup::failure(); + } + + // got to the next token if we got a match + if (result) + currentIndex += (*result).getTokensCount(); + } + + /*if (group.getRepeatedGroup()) { + bool hasSubResults = false; + + optional> subResults; + do { + subResults = parseeResultsForParseeGroup(*group.getRepeatedGroup()); + if (!subResults) + return ParseeResultsGroup::failure(); + //return {}; + + for (ParseeResult &subResult : *subResults) + results.push_back(subResult); + } while (!(*subResults).empty()); + }*/ + + return ParseeResultsGroup::success(results); +} + +/*optional> Parser::parseeResultsForParseeGroup(ParseeGroup group) { + int startIndex = currentIndex; + vector results; + bool mustFulfill = false; + + for (Parsee &parsee : group.getParsees()) { + optional result; + switch (parsee.getKind()) { + case ParseeKind::TOKEN: + result = tokenParseeResult(currentIndex, parsee.getTokenKind()); + break; + case ParseeKind::VALUE_TYPE: + result = valueTypeParseeResult(currentIndex); + break; + case ParseeKind::EXPRESSION: + result = expressionParseeResult(currentIndex); + break; } // if doesn't match on optional group @@ -883,7 +1008,7 @@ optional> Parser::parseeResultsForParseeGroup(ParseeGroup g } return results; -} +}*/ optional Parser::tokenParseeResult(int index, TokenKind tokenKind) { shared_ptr token = tokens.at(index); @@ -925,6 +1050,18 @@ optional Parser::valueTypeParseeResult(int index) { return ParseeResult::valueTypeResult(valueType, index - startIndex); } +optional Parser::expressionParseeResult(int index) { + int startIndex = currentIndex; + int errorsCount = errors.size(); + shared_ptr expression = nextExpression(); + if (errors.size() > errorsCount) + return {}; + + int tokensCount = currentIndex - startIndex; + currentIndex = startIndex; + return ParseeResult::expressionResult(expression, tokensCount); +} + bool Parser::tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance) { int requiredCount = shouldMatchAll ? kinds.size() : 1; if (currentIndex + requiredCount > tokens.size()) diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index a3c35ef..7e80f40 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -14,6 +14,7 @@ class Statement; class ParseeGroup; class ParseeResult; +class ParseeResultsGroup; using namespace std; @@ -55,9 +56,11 @@ private: shared_ptr matchValueType(); - optional> parseeResultsForParseeGroup(ParseeGroup group); + ParseeResultsGroup parseeResultsGroupForParseeGroup(ParseeGroup group); + //optional> parseeResultsForParseeGroup(ParseeGroup group); optional tokenParseeResult(int index, TokenKind tokenKind); optional valueTypeParseeResult(int index); + optional expressionParseeResult(int index); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); void markError(optional expectedTokenKind, optional message);