Rework identifier handling, adds typedef statement.
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
#include "Parser.hpp"
|
||||
#include <iostream>
|
||||
#include "../CoreData/PrimitiveTypes.hpp"
|
||||
|
||||
#define PROGRESS_TOKEN(token) \
|
||||
token = token->GetNext().get(); \
|
||||
while (token->GetKind() == LexTokenKind::Whitespace) { \
|
||||
token = token->GetNext().get(); \
|
||||
token = (token)->GetNext().get(); \
|
||||
while ((token)->GetKind() == LexTokenKind::Whitespace) { \
|
||||
(token) = (token)->GetNext().get(); \
|
||||
}
|
||||
|
||||
#define EXPECT_TOKEN(token, kind) \
|
||||
if (token->GetKind() != LexTokenKind::kind) { \
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, token->GetSpan()); \
|
||||
}
|
||||
|
||||
namespace MalachScript::Parser {
|
||||
@@ -48,11 +54,11 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
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);
|
||||
Identifier identifier;
|
||||
ParseIdentifier(identifier, current, encounteredError);
|
||||
PROGRESS_TOKEN(current);
|
||||
std::vector<std::u8string_view> inherits;
|
||||
std::vector<Identifier> inherits;
|
||||
std::vector<const ParsedStatement*> body;
|
||||
body.reserve(16);
|
||||
|
||||
@@ -63,16 +69,16 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
case LexTokenKind::ColonSymbol: {
|
||||
PROGRESS_TOKEN(current);
|
||||
auto id = ParseIdentifier(current, encounteredError);
|
||||
Identifier id;
|
||||
ParseIdentifier(id, current, encounteredError);
|
||||
inherits.push_back(id);
|
||||
while (current->GetKind() == LexTokenKind::CommaSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
id = ParseIdentifier(current, encounteredError);
|
||||
ParseIdentifier(id, current, encounteredError);
|
||||
inherits.push_back(id);
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
if (!encounteredError && current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol)
|
||||
{
|
||||
if (!encounteredError && current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
||||
encounteredError = true;
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
@@ -88,12 +94,10 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
const ParsedStatement* statement;
|
||||
// TODO: Sort by
|
||||
if (!ParseVirtProp(statement) &&
|
||||
!ParseFunc(statement) &&
|
||||
!ParseVar(statement) &&
|
||||
!ParseFuncDef(statement)){
|
||||
if (!ParseVirtProp(statement) && !ParseFunc(statement) && !ParseVar(statement) &&
|
||||
!ParseFuncDef(statement)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
} else{
|
||||
} else {
|
||||
body.push_back(statement);
|
||||
}
|
||||
}
|
||||
@@ -101,13 +105,56 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
default: throw;
|
||||
}
|
||||
out = new ParsedClassStatement(TextSpan(start, current->GetSpan().GetEnd()), identifier,
|
||||
inherits, body);
|
||||
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; }
|
||||
bool Parser::ParseTypeDef(const ParsedStatement*& out) {
|
||||
if (_currentToken->GetKind() != LexTokenKind::TypedefKeyword) {
|
||||
return false;
|
||||
}
|
||||
auto start = _currentToken->GetSpan().GetStart();
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
Identifier defineFrom;
|
||||
auto encounteredErrors = false;
|
||||
if (!ParsePrimType(defineFrom) && !ParseIdentifier(defineFrom, _currentToken, encounteredErrors)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
}
|
||||
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
Identifier defineTo;
|
||||
if (!ParseIdentifier(defineTo, _currentToken, encounteredErrors)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
}
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
if (_currentToken->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
}
|
||||
out = new ParsedTypeDefStatement(TextSpan(start, _currentToken->GetSpan().GetEnd()), defineTo, defineFrom);
|
||||
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; }
|
||||
bool Parser::ParsePrimType(Identifier& out) {
|
||||
// TODO: out needs to return a value.
|
||||
switch (_currentToken->GetKind()) {
|
||||
case LexTokenKind::VoidKeyword: out = PrimitiveTypes::VoidName(); return true;
|
||||
case LexTokenKind::IntKeyword: out = PrimitiveTypes::IntName(); return true;
|
||||
case LexTokenKind::Int8Keyword: out = PrimitiveTypes::Int8Name(); return true;
|
||||
case LexTokenKind::Int16Keyword: out = PrimitiveTypes::Int16Name(); return true;
|
||||
case LexTokenKind::Int32Keyword: out = PrimitiveTypes::Int32Name(); return true;
|
||||
case LexTokenKind::Int64Keyword: out = PrimitiveTypes::Int64Name(); return true;
|
||||
case LexTokenKind::UintKeyword: PrimitiveTypes::UintName(); return true;
|
||||
case LexTokenKind::Uint8Keyword: PrimitiveTypes::Uint8Name(); return true;
|
||||
case LexTokenKind::Uint16Keyword: PrimitiveTypes::Uint16Name(); return true;
|
||||
case LexTokenKind::Uint32Keyword: PrimitiveTypes::Uint32Name(); return true;
|
||||
case LexTokenKind::Uint64Keyword: PrimitiveTypes::Uint64Name(); return true;
|
||||
case LexTokenKind::FloatKeyword: PrimitiveTypes::FloatName(); return true;
|
||||
case LexTokenKind::DoubleKeyword: PrimitiveTypes::DoubleName(); return true;
|
||||
case LexTokenKind::BoolKeyword: PrimitiveTypes::BoolName(); return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user