Many fixes for namespace parsing.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
bfe27ec20f
commit
b4c18e0f09
@ -31,41 +31,53 @@ namespace MalachScript::Parser {
|
|||||||
diagnostics->Log(level, type, scriptName, span);
|
diagnostics->Log(level, type, scriptName, span);
|
||||||
};
|
};
|
||||||
|
|
||||||
return ParseScript(firstToken, log);
|
ScopedPtr<const ParsedStatement> s = nullptr;
|
||||||
|
ParseScript(s, firstToken, log);
|
||||||
|
return dynamic_cast<const ParsedScriptStatement*>(s.TakeOwnership());
|
||||||
}
|
}
|
||||||
|
|
||||||
const ParsedScriptStatement* Parser::ParseScript(const LexToken* firstToken, const log_func& log) {
|
bool Parser::ParseScript(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
||||||
|
const log_func& log) {
|
||||||
std::vector<const ParsedStatement*> statements;
|
std::vector<const ParsedStatement*> statements;
|
||||||
const size_t reservedScriptSize = 32;
|
const size_t reservedScriptSize = 32;
|
||||||
statements.reserve(reservedScriptSize);
|
statements.reserve(reservedScriptSize);
|
||||||
size_t current = 0;
|
size_t currentAmount = 0;
|
||||||
const auto* currentToken = firstToken;
|
const auto* current = currentToken;
|
||||||
while (true) {
|
while (true) {
|
||||||
while (currentToken->GetKind() == LexTokenKind::Whitespace) {
|
while (current->GetKind() == LexTokenKind::Whitespace) {
|
||||||
currentToken = currentToken->GetNext().get();
|
current = current->GetNext().get();
|
||||||
}
|
}
|
||||||
if (currentToken->GetKind() == LexTokenKind::EndOfFile) {
|
if (current->GetKind() == LexTokenKind::EndOfFile) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (current->GetKind() == LexTokenKind::SemicolonSymbol) {
|
||||||
|
PROGRESS_TOKEN(current);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Deal with namespace
|
||||||
|
if (current->GetKind() == LexTokenKind::CloseCurlyParenthesisSymbol) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ScopedPtr<const ParsedStatement> statement;
|
ScopedPtr<const ParsedStatement> statement;
|
||||||
// TODO: Sort by performance
|
// TODO: Sort by performance
|
||||||
auto result = ParseTypeDef(statement, currentToken, log) || ParseClass(statement, currentToken, log) ||
|
auto result = ParseTypeDef(statement, current, log) || ParseClass(statement, current, log) ||
|
||||||
ParseFunc(statement, currentToken, log) || ParseNamespace(statement, currentToken, log);
|
ParseFunc(statement, current, log) || ParseNamespace(statement, current, log);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
// TODO: Log error
|
logError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
logError(Diagnostics::DiagnosticType::UnexpectedToken, currentToken->GetSpan());
|
PROGRESS_TOKEN(current);
|
||||||
PROGRESS_TOKEN(currentToken);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
statements.push_back(statement.TakeOwnership());
|
statements.push_back(statement.TakeOwnership());
|
||||||
current++;
|
currentAmount++;
|
||||||
}
|
}
|
||||||
statements.resize(current);
|
statements.resize(currentAmount);
|
||||||
auto end = 0;
|
auto end = 0;
|
||||||
if (current > 0) {
|
if (currentAmount > 0) {
|
||||||
end = statements.back()->GetSpan().GetEnd();
|
end = statements.back()->GetSpan().GetEnd();
|
||||||
}
|
}
|
||||||
return new ParsedScriptStatement(TextSpan(0, end), statements);
|
out = new ParsedScriptStatement(TextSpan(0, end), statements);
|
||||||
|
currentToken = current;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
bool Parser::ParseClass(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func& log) {
|
bool Parser::ParseClass(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func& log) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
@ -182,11 +194,18 @@ namespace MalachScript::Parser {
|
|||||||
Identifier identifier;
|
Identifier identifier;
|
||||||
if (!ParseIdentifier(identifier, current)) {
|
if (!ParseIdentifier(identifier, current)) {
|
||||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan());
|
logError(DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
|
} else {
|
||||||
|
PROGRESS_TOKEN(current);
|
||||||
|
}
|
||||||
|
EXPECT_TOKEN(current, OpenCurlyParenthesisSymbol);
|
||||||
|
ScopedPtr<const ParsedStatement> script = nullptr;
|
||||||
|
if (!ParseScript(script, current, log)) {
|
||||||
|
logError(DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
}
|
}
|
||||||
const auto* script = ParseScript(current, log);
|
|
||||||
auto end = current->GetSpan().GetEnd();
|
auto end = current->GetSpan().GetEnd();
|
||||||
PROGRESS_TOKEN(current);
|
EXPECT_TOKEN(current, CloseCurlyParenthesisSymbol);
|
||||||
out = new ParsedNamespaceStatement(TextSpan(start, end), identifier, script);
|
out = new ParsedNamespaceStatement(TextSpan(start, end), identifier,
|
||||||
|
(const ParsedScriptStatement*)script.TakeOwnership());
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ namespace MalachScript::Parser {
|
|||||||
// Interface
|
// Interface
|
||||||
static bool ParseNamespace(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
static bool ParseNamespace(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
||||||
const log_func&);
|
const log_func&);
|
||||||
static const ParsedScriptStatement* ParseScript(const LexToken* firstToken, const log_func&);
|
static bool ParseScript(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user