This commit is contained in:
Rafał Grodziński
2025-07-15 23:30:28 +09:00
parent dc6668459f
commit 1dc6010b9b
3 changed files with 136 additions and 54 deletions

View File

@@ -1,4 +1,4 @@
@extern putchar fun: character sint32 -> sint32 //@extern putchar fun: character sint32 -> sint32
// ./build/brb samples/test.brc -S -x86-asm-syntax=intel // ./build/brb samples/test.brc -S -x86-asm-syntax=intel
@@ -24,9 +24,9 @@ i u32 <- 0, rep text[i] != 0:
add $1, $0 add $1, $0
;*/ ;*/
normAdd fun: num1 sint32, num2 sint32 -> sint32 /*normAdd fun: num1 sint32, num2 sint32 -> sint32
ret num1 + num2 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 add $1, $2

View File

@@ -238,16 +238,35 @@ shared_ptr<Statement> Parser::matchStatementFunction() {
} }
shared_ptr<Statement> Parser::matchStatementRawFunction() { shared_ptr<Statement> Parser::matchStatementRawFunction() {
ParseeTokensGroup idGroup = ParseeTokensGroup( bool hasError = false;
optional<vector<shared_ptr<Token>>> groupTokens;
string name;
string constraints;
vector<pair<string, shared_ptr<ValueType>>> arguments;
shared_ptr<ValueType> returnType = ValueType::NONE;
// identifier
groupTokens = tokensForParseeTokensGroup(
ParseeTokensGroup(
true, true,
{ {
ParseeToken(TokenKind::IDENTIFIER, true, true), ParseeToken(TokenKind::IDENTIFIER, true, true),
ParseeToken(TokenKind::RAW_FUNCTION, true, false) ParseeToken(TokenKind::RAW_FUNCTION, true, false)
}, },
{} {}
)
); );
if (groupTokens) {
name = (*groupTokens).at(0)->getLexme();
} else {
hasError = true;
}
ParseeTokensGroup optionsGroup = ParseeTokensGroup( // options
if (!hasError) {
groupTokens = tokensForParseeTokensGroup(
ParseeTokensGroup(
false, false,
{ {
ParseeToken(TokenKind::LESS, true, false), ParseeToken(TokenKind::LESS, true, false),
@@ -255,9 +274,19 @@ shared_ptr<Statement> Parser::matchStatementRawFunction() {
ParseeToken(TokenKind::GREATER, true, false) ParseeToken(TokenKind::GREATER, true, false)
}, },
{} {}
)
); );
if (groupTokens && !(*groupTokens).empty()) {
constraints = (*groupTokens).at(0)->getLexme();
} else if (!groupTokens) {
hasError = true;
}
}
ParseeTokensGroup argumentsGroup = ParseeTokensGroup( // arguments
if (!hasError) {
groupTokens = tokensForParseeTokensGroup(
ParseeTokensGroup(
false, false,
{ {
ParseeToken(TokenKind::COLON, true, false), ParseeToken(TokenKind::COLON, true, false),
@@ -275,9 +304,19 @@ shared_ptr<Statement> Parser::matchStatementRawFunction() {
}, },
{} {}
) )
)
); );
if (groupTokens && !(*groupTokens).empty()) {
ParseeTokensGroup returnGroup = ParseeTokensGroup( } else if (!groupTokens) {
hasError = true;
}
}
// return type
if (!hasError) {
groupTokens = tokensForParseeTokensGroup(
ParseeTokensGroup(
false, false,
{ {
ParseeToken(TokenKind::RIGHT_ARROW, true, false), ParseeToken(TokenKind::RIGHT_ARROW, true, false),
@@ -285,15 +324,19 @@ shared_ptr<Statement> Parser::matchStatementRawFunction() {
ParseeToken(TokenKind::TYPE, true, true) ParseeToken(TokenKind::TYPE, true, true)
}, },
{} {}
)
); );
if (groupTokens && !(*groupTokens).empty()) {
} else if (!groupTokens) {
hasError = true;
}
}
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::RAW_FUNCTION}, true, false)) if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::RAW_FUNCTION}, true, false))
return nullptr; return nullptr;
string name;
string constraints;
vector<pair<string, shared_ptr<ValueType>>> arguments;
shared_ptr<ValueType> returnType = ValueType::NONE;
string rawSource; string rawSource;
// name // name
@@ -828,6 +871,44 @@ shared_ptr<ValueType> Parser::matchValueType() {
return ValueType::valueTypeForToken(typeToken, subType, valueArg); return ValueType::valueTypeForToken(typeToken, subType, valueArg);
} }
optional<vector<shared_ptr<Token>>> Parser::tokensForParseeTokensGroup(ParseeTokensGroup group) {
int nextIndex = currentIndex;
vector<shared_ptr<Token>> returnTokens;
bool mustFulfill = false;
for (ParseeToken &parsee : group.getTokens()) {
shared_ptr<Token> currentToken = tokens.at(nextIndex);
bool matches = currentToken->isOfKind({parsee.getTokenKind()});
// if doesn't match on optional group
if (!matches && parsee.getIsRequired() && !group.getIsRequired() && mustFulfill)
return vector<shared_ptr<Token>>();
// return matching token?
if (matches && parsee.getShouldReturn())
returnTokens.push_back(currentToken);
// decide if we're decoding the expected sequence
if (!parsee.getIsRequired() && nextIndex > currentIndex)
mustFulfill = true;
// invalid sequence detected?
if (!matches && parsee.getIsRequired() && mustFulfill) {
currentIndex = nextIndex;
markError(parsee.getTokenKind(), {});
return {};
}
// got to the next token if we got a match
if (matches)
nextIndex++;
}
currentIndex = nextIndex;
return returnTokens;
}
bool Parser::tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance) { bool Parser::tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance) {
int requiredCount = shouldMatchAll ? kinds.size() : 1; int requiredCount = shouldMatchAll ? kinds.size() : 1;
if (currentIndex + requiredCount > tokens.size()) if (currentIndex + requiredCount > tokens.size())

View File

@@ -55,6 +55,7 @@ private:
shared_ptr<ValueType> matchValueType(); shared_ptr<ValueType> matchValueType();
optional<vector<shared_ptr<Token>>> tokensForParseeTokensGroup(ParseeTokensGroup group);
bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance); bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance);
void markError(optional<TokenKind> expectedTokenKind, optional<string> message); void markError(optional<TokenKind> expectedTokenKind, optional<string> message);