diff --git a/samples/test.brc b/samples/test.brc index 78e2ede..9fabe98 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -28,7 +28,12 @@ i u32 <- 0, rep text[i] != 0: ret num1 + num2 ;*/ -rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 +/*rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 + add $1, $2 + mov $0, $1 +;*/ + +rawAdd raw: num1 sint32, num2 sint32 -> sint32 add $1, $2 mov $0, $1 ; @@ -46,8 +51,8 @@ rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 main fun -> sint32 //printChar() - res1 sint32 <- normAdd(4, 5) - res2 sint32 <- rawAdd(4, 5) + //res1 sint32 <- normAdd(4, 5) + //res2 sint32 <- rawAdd(4, 5) ret 0 ; \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.cpp b/src/Parser/Parsee/Parsee.cpp index 227b23e..292e997 100644 --- a/src/Parser/Parsee/Parsee.cpp +++ b/src/Parser/Parsee/Parsee.cpp @@ -13,6 +13,7 @@ Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldRetu Parsee Parsee::valueTypeParsee() { Parsee parsee; parsee.kind = ParseeKind::VALUE_TYPE; + parsee.shouldReturn = true; return parsee; } diff --git a/src/Parser/Parsee/ParseeResult.cpp b/src/Parser/Parsee/ParseeResult.cpp index 66dc619..ce00984 100644 --- a/src/Parser/Parsee/ParseeResult.cpp +++ b/src/Parser/Parsee/ParseeResult.cpp @@ -7,13 +7,15 @@ ParseeResult ParseeResult::tokenResult(shared_ptr token) { ParseeResult parseeResult; parseeResult.kind = ParseeResultKind::TOKEN; parseeResult.token = token; + parseeResult.tokensCount = 1; return parseeResult; } -ParseeResult ParseeResult::valueTypeResult(shared_ptr valueType) { +ParseeResult ParseeResult::valueTypeResult(shared_ptr valueType, int tokensCount) { ParseeResult parseeResult; parseeResult.kind = ParseeResultKind::VALUE_TYPE; parseeResult.valueType = valueType; + parseeResult.tokensCount = tokensCount; return parseeResult; } @@ -30,4 +32,8 @@ shared_ptr ParseeResult::getToken() { shared_ptr ParseeResult::getValueType() { return valueType; +} + +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 a909152..fb56d45 100644 --- a/src/Parser/Parsee/ParseeResult.h +++ b/src/Parser/Parsee/ParseeResult.h @@ -18,15 +18,17 @@ private: ParseeResultKind kind; shared_ptr token; shared_ptr valueType; + int tokensCount; ParseeResult(); public: static ParseeResult tokenResult(shared_ptr token); - static ParseeResult valueTypeResult(shared_ptr valueType); + static ParseeResult valueTypeResult(shared_ptr valueType, int tokensCount); ParseeResultKind getKind(); shared_ptr getToken(); shared_ptr getValueType(); + int getTokensCount(); }; #endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index cd0d81e..5550800 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -247,6 +247,7 @@ shared_ptr Parser::matchStatementRawFunction() { string constraints; vector>> arguments; shared_ptr returnType = ValueType::NONE; + string rawSource; // identifier parseeResults = parseeResultsForParseeGroup( @@ -297,7 +298,7 @@ shared_ptr Parser::matchStatementRawFunction() { Parsee::valueTypeParsee() }, ParseeGroup( - true, + false, { Parsee::tokenParsee(TokenKind::COMMA, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), @@ -341,58 +342,6 @@ shared_ptr Parser::matchStatementRawFunction() { } } - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::RAW_FUNCTION}, true, false)) - return nullptr; - - string rawSource; - - // name - name = tokens.at(currentIndex++)->getLexme(); - currentIndex++; // skip raw - - // constraints - - if (tryMatchingTokenKinds({TokenKind::LESS}, true, true)) { - if (tokens.at(currentIndex)->isOfKind({TokenKind::STRING})) { - constraints = tokens.at(currentIndex++)->getLexme(); - // remove enclosing quotes - if (constraints.length() >= 2) - constraints = constraints.substr(1, constraints.length() - 2); - } - if (!tryMatchingTokenKinds({TokenKind::GREATER}, true, true)) - markError({TokenKind::GREATER}, {}); - } - - // arguments - if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { - do { - tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) { - markError({}, "Expected function argument"); - return nullptr; - } - shared_ptr identifierToken = tokens.at(currentIndex++); - shared_ptr argumentType = matchValueType(); - if (argumentType == nullptr) { - markError(TokenKind::TYPE, {}); - return nullptr; - } - - arguments.push_back(pair>(identifierToken->getLexme(), argumentType)); - } while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)); - } - - // return type - if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) { - tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line - - returnType = matchValueType(); - if (returnType == nullptr) { - markError(TokenKind::TYPE, {}); - return nullptr; - } - } - // consume new line if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { markError(TokenKind::NEW_LINE, {}); @@ -879,43 +828,103 @@ shared_ptr Parser::matchValueType() { } optional> Parser::parseeResultsForParseeGroup(ParseeGroup group) { - int nextIndex = currentIndex; + int startIndex = currentIndex; vector results; bool mustFulfill = false; for (Parsee &parsee : group.getParsees()) { - shared_ptr currentToken = tokens.at(nextIndex); - bool matches = currentToken->isOfKind({parsee.getTokenKind()}); + optional result; + switch (parsee.getKind()) { + case ParseeKind::TOKEN: + result = tokenParseeResult(currentIndex, parsee.getTokenKind()); + break; + case ParseeKind::VALUE_TYPE: + result = valueTypeParseeResult(currentIndex); + break; + } // if doesn't match on optional group - if (!matches && parsee.getIsRequired() && !group.getIsRequired() && mustFulfill) + if (!result && parsee.getIsRequired() && !group.getIsRequired() && !mustFulfill) { + currentIndex = startIndex; return vector(); + } // return matching token? - if (matches && parsee.getShouldReturn()) - results.push_back(ParseeResult::tokenResult(currentToken)); + if (result && parsee.getShouldReturn()) + results.push_back(*result); // decide if we're decoding the expected sequence - if (!parsee.getIsRequired() && nextIndex > currentIndex) + if (!parsee.getIsRequired() && currentIndex > startIndex) mustFulfill = true; // invalid sequence detected? - if (!matches && parsee.getIsRequired() && mustFulfill) { - currentIndex = nextIndex; + if (!result && parsee.getIsRequired() && mustFulfill) { markError(parsee.getTokenKind(), {}); return {}; } // got to the next token if we got a match - if (matches) - nextIndex++; + if (result) + currentIndex += (*result).getTokensCount(); } - currentIndex = nextIndex; + if (group.getRepeatedGroup()) { + bool hasSubResults = false; + + optional> subResults; + do { + subResults = parseeResultsForParseeGroup(*group.getRepeatedGroup()); + if (!subResults) + return {}; + + for (ParseeResult &subResult : *subResults) + results.push_back(subResult); + } while (!(*subResults).empty()); + } return results; } +optional Parser::tokenParseeResult(int index, TokenKind tokenKind) { + shared_ptr token = tokens.at(index); + if (token->isOfKind({tokenKind})) + return ParseeResult::tokenResult(token); + return {}; +} + +optional Parser::valueTypeParseeResult(int index) { + int startIndex = index; + + if (!tokens.at(index)->isOfKind({TokenKind::TYPE})) + return {}; + + shared_ptr typeToken = tokens.at(index++); + shared_ptr subType; + int typeArg = 0; + + if (tokens.at(index)->isOfKind({TokenKind::LESS})) { + index++; + optional subResult = valueTypeParseeResult(index); + if (!subResult) + return {}; + subType = (*subResult).getValueType(); + + + if (tokens.at(index)->isOfKind({TokenKind::COMMA})) { + index++; + + if (!tokens.at(index)->isOfKind({TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, TokenKind::INTEGER_BIN, TokenKind::INTEGER_CHAR})) + return {}; + } + + if (!tokens.at(index)->isOfKind({TokenKind::GREATER})) + return {}; + } + + shared_ptr valueType = ValueType::valueTypeForToken(typeToken, subType, 0); + return ParseeResult::valueTypeResult(valueType, index - startIndex); +} + 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 db079d4..a3c35ef 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -56,6 +56,8 @@ private: shared_ptr matchValueType(); optional> parseeResultsForParseeGroup(ParseeGroup group); + optional tokenParseeResult(int index, TokenKind tokenKind); + optional valueTypeParseeResult(int index); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); void markError(optional expectedTokenKind, optional message);