Initial work on parsing.

This commit is contained in:
2020-10-07 22:11:18 +02:00
parent f299d5183f
commit 2036f1ce43
10 changed files with 276 additions and 55 deletions

View File

@@ -1,15 +1,28 @@
#include "Parser.hpp"
#include <iostream>
#define PROGRESS_TOKEN(token) \
token = token->GetNext().get(); \
while (token->GetKind() == LexTokenKind::Whitespace) { \
token = token->GetNext().get(); \
}
namespace MalachScript::Parser {
ParsedScriptStatement* Parser::Parse() {
std::vector<const ParsedStatement*> statements(32);
std::vector<const ParsedStatement*> statements;
statements.reserve(32);
size_t current = 0;
while (true) {
auto next = this->Consume();
if (next->GetKind() == LexTokenKind::EndOfFile) {
while (_currentToken->GetKind() == LexTokenKind::Whitespace) {
_currentToken = _currentToken->GetNext().get();
}
if (_currentToken->GetKind() == LexTokenKind::EndOfFile) {
break;
}
statements[current] = this->ParseStatement(next);
const ParsedStatement* statement;
if (ParseClass(statement)) {
}
statements.push_back(statement);
current++;
}
statements.resize(current);
@@ -17,10 +30,84 @@ namespace MalachScript::Parser {
if (current > 0) {
end = statements.back()->GetSpan().GetEnd();
}
const auto* block = new ParsedBlockStatement(TextSpan(0, end), statements);
return new ParsedScriptStatement(block);
return new ParsedScriptStatement(TextSpan(0, end), statements);
}
const ParsedStatement* Parser::ParseStatement(const LexToken* token) {
// If modifier (shared, external, private, protected, etc) push to buffer, continue
bool Parser::ParseClass(const ParsedStatement*& out) {
const auto* current = _currentToken;
auto start = current->GetSpan().GetStart();
bool lookingForClass = true;
bool encounteredError = false;
while (lookingForClass) {
switch (current->GetKind()) {
case LexTokenKind::SharedKeyword: break;
case LexTokenKind::AbstractKeyword: break;
case LexTokenKind::FinalKeyword: break;
case LexTokenKind::ExternalKeyword: break;
case LexTokenKind::ClassKeyword: lookingForClass = false; break;
default: return false;
}
PROGRESS_TOKEN(current);
}
std::u8string_view identifier;
// After class keyword, an identifier should always follow, if it doesn't, log an error.
identifier = ParseIdentifier(current, encounteredError);
PROGRESS_TOKEN(current);
std::vector<std::u8string_view> inherits;
std::vector<const ParsedStatement*> body;
body.reserve(16);
switch (current->GetKind()) {
case LexTokenKind::SemicolonSymbol: {
PROGRESS_TOKEN(current);
break;
}
case LexTokenKind::ColonSymbol: {
PROGRESS_TOKEN(current);
auto id = ParseIdentifier(current, encounteredError);
inherits.push_back(id);
while (current->GetKind() == LexTokenKind::CommaSymbol) {
PROGRESS_TOKEN(current);
id = ParseIdentifier(current, encounteredError);
inherits.push_back(id);
PROGRESS_TOKEN(current);
}
if (!encounteredError && current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol)
{
encounteredError = true;
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
}
// Intentionally don't break so we continue into the inner body statement.
}
case LexTokenKind::OpenCurlyParenthesisSymbol: {
PROGRESS_TOKEN(current);
while (true) {
// Cheapest operation, check first
if (current->GetKind() == LexTokenKind::CloseCurlyParenthesisSymbol) {
PROGRESS_TOKEN(current);
break;
}
const ParsedStatement* statement;
// TODO: Sort by
if (!ParseVirtProp(statement) &&
!ParseFunc(statement) &&
!ParseVar(statement) &&
!ParseFuncDef(statement)){
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
} else{
body.push_back(statement);
}
}
break;
}
default: throw;
}
out = new ParsedClassStatement(TextSpan(start, current->GetSpan().GetEnd()), identifier,
inherits, body);
_currentToken = current;
return true;
}
bool Parser::ParseVirtProp([[maybe_unused]]const ParsedStatement*& out) { return false; }
bool Parser::ParseFunc([[maybe_unused]]const ParsedStatement*& out) { return false; }
bool Parser::ParseVar([[maybe_unused]]const ParsedStatement*& out) { return false; }
bool Parser::ParseFuncDef([[maybe_unused]]const ParsedStatement*& out) { return false; }
}