Implements basic virtprop parsing.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
#include "Parser.hpp"
|
||||
#include <iostream>
|
||||
#include "../CoreData/FuncAttr.hpp"
|
||||
#include "../CoreData/PrimitiveTypes.hpp"
|
||||
|
||||
#define PROGRESS_TOKEN(token) \
|
||||
@@ -104,10 +103,11 @@ namespace MalachScript::Parser {
|
||||
break;
|
||||
}
|
||||
const ParsedStatement* statement = nullptr;
|
||||
// TODO: Sort by
|
||||
if (!ParseVirtProp(statement) && !ParseFunc(statement) && !ParseVar(statement) &&
|
||||
// TODO: Sort by complexity
|
||||
if (!ParseVirtProp(statement, current) && !ParseFunc(statement) && !ParseVar(statement) &&
|
||||
!ParseFuncDef(statement)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
break;
|
||||
} else {
|
||||
body.push_back(statement);
|
||||
}
|
||||
@@ -152,7 +152,7 @@ namespace MalachScript::Parser {
|
||||
if (!ParseIdentifier(identifier, _currentToken)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
}
|
||||
const auto *script = ParseScript();
|
||||
const auto* script = ParseScript();
|
||||
auto end = _currentToken->GetSpan().GetEnd();
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
out = new ParsedNamespaceStatement(TextSpan(start, end), identifier, script);
|
||||
@@ -211,29 +211,8 @@ namespace MalachScript::Parser {
|
||||
isConst = true;
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
}
|
||||
bool lookingForFuncAttr = true;
|
||||
FuncAttr funcAttr = FuncAttr::None;
|
||||
while (lookingForFuncAttr) {
|
||||
switch (_currentToken->GetKind()) {
|
||||
case LexTokenKind::OverrideKeyword:
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
funcAttr = FuncAttrHelpers::Set(funcAttr, FuncAttr::Override);
|
||||
continue;
|
||||
case LexTokenKind::FinalKeyword:
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
funcAttr = FuncAttrHelpers::Set(funcAttr, FuncAttr::Final);
|
||||
continue;
|
||||
case LexTokenKind::ExplicitKeyword:
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
funcAttr = FuncAttrHelpers::Set(funcAttr, FuncAttr::Explicit);
|
||||
continue;
|
||||
case LexTokenKind::PropertyKeyword:
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
funcAttr = FuncAttrHelpers::Set(funcAttr, FuncAttr::Property);
|
||||
continue;
|
||||
default: lookingForFuncAttr = false; break;
|
||||
}
|
||||
}
|
||||
ParseFuncAttr(funcAttr, _currentToken);
|
||||
const ParsedStatement* statblock = nullptr;
|
||||
if (_currentToken->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
// TODO: Parse stat block.
|
||||
@@ -317,6 +296,34 @@ namespace MalachScript::Parser {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::ParseFuncAttr(FuncAttr& out, const LexToken*& currentToken) {
|
||||
bool lookingForFuncAttr = true;
|
||||
const auto* current = currentToken;
|
||||
while (lookingForFuncAttr) {
|
||||
switch (current->GetKind()) {
|
||||
case LexTokenKind::OverrideKeyword:
|
||||
PROGRESS_TOKEN(current);
|
||||
out = FuncAttrHelpers::Set(out, FuncAttr::Override);
|
||||
continue;
|
||||
case LexTokenKind::FinalKeyword:
|
||||
PROGRESS_TOKEN(current);
|
||||
out = FuncAttrHelpers::Set(out, FuncAttr::Final);
|
||||
continue;
|
||||
case LexTokenKind::ExplicitKeyword:
|
||||
PROGRESS_TOKEN(current);
|
||||
out = FuncAttrHelpers::Set(out, FuncAttr::Explicit);
|
||||
continue;
|
||||
case LexTokenKind::PropertyKeyword:
|
||||
PROGRESS_TOKEN(current);
|
||||
out = FuncAttrHelpers::Set(out, FuncAttr::Property);
|
||||
continue;
|
||||
default: lookingForFuncAttr = false; break;
|
||||
}
|
||||
}
|
||||
_currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::ParseParamList(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
if (currentToken->GetKind() != LexTokenKind::OpenParenthesisSymbol) {
|
||||
return false;
|
||||
@@ -333,7 +340,8 @@ namespace MalachScript::Parser {
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
out = new ParsedParamListStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), parameters);
|
||||
return true;
|
||||
} if (currentToken->GetKind() == LexTokenKind::CloseParenthesisSymbol) {
|
||||
}
|
||||
if (currentToken->GetKind() == LexTokenKind::CloseParenthesisSymbol) {
|
||||
out = new ParsedParamListStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), parameters);
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
@@ -396,7 +404,105 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
}
|
||||
|
||||
bool Parser::ParseVirtProp([[maybe_unused]] const ParsedStatement*& out) { return false; }
|
||||
bool Parser::ParseVirtProp([[maybe_unused]] const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
AccessModifier access = AccessModifier::Public;
|
||||
const auto* current = currentToken;
|
||||
if (current->GetKind() == LexTokenKind::PrivateKeyword) {
|
||||
access = AccessModifier::Private;
|
||||
PROGRESS_TOKEN(current);
|
||||
} else if (current->GetKind() == LexTokenKind::ProtectedKeyword) {
|
||||
access = AccessModifier::Protected;
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
const ParsedStatement* typeStatement = nullptr;
|
||||
if (!ParseType(typeStatement, current)) {
|
||||
return false;
|
||||
}
|
||||
bool ref = false;
|
||||
if (current->GetKind() == LexTokenKind::AmpersandSymbol) {
|
||||
ref = true;
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
Identifier identifier;
|
||||
if (!ParseIdentifier(identifier, current)) {
|
||||
delete typeStatement;
|
||||
return false;
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
||||
return false;
|
||||
}
|
||||
bool hasGet = false;
|
||||
bool getConst = false;
|
||||
FuncAttr getAttr = FuncAttr::None;
|
||||
const ParsedStatement* getStatement = nullptr;
|
||||
bool hasSet = false;
|
||||
bool setConst = false;
|
||||
FuncAttr setAttr = FuncAttr::None;
|
||||
const ParsedStatement* setStatement = nullptr;
|
||||
PROGRESS_TOKEN(current);
|
||||
while (true) {
|
||||
auto start = current->GetSpan().GetStart();
|
||||
if (current->GetKind() == LexTokenKind::GetKeyword) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (current->GetKind() == LexTokenKind::ConstKeyword) {
|
||||
getConst = true;
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
ParseFuncAttr(getAttr, current);
|
||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
// TODO: Parse stat block.
|
||||
// if (ParseStatBlock(getStatement, current)){
|
||||
//
|
||||
// }
|
||||
this->LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
|
||||
if (hasGet) {
|
||||
this->LogError(Diagnostics::DiagnosticType::DoubleProperty,
|
||||
TextSpan(start, current->GetSpan().GetEnd()));
|
||||
}
|
||||
hasGet = true;
|
||||
} else if (current->GetKind() == LexTokenKind::SetKeyword) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (current->GetKind() == LexTokenKind::ConstKeyword) {
|
||||
setConst = true;
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
ParseFuncAttr(setAttr, current);
|
||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
// TODO: Parse stat block.
|
||||
// if (ParseStatBlock(setStatement, current)){
|
||||
//
|
||||
// }
|
||||
this->LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
|
||||
if (hasSet) {
|
||||
this->LogError(Diagnostics::DiagnosticType::DoubleProperty,
|
||||
TextSpan(start, current->GetSpan().GetEnd()));
|
||||
}
|
||||
hasSet = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (current->GetKind() != LexTokenKind::CloseCurlyParenthesisSymbol){
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
else{
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
|
||||
out = new ParsedVirtPropStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
access, typeStatement, ref, identifier, hasGet, getConst, getAttr,
|
||||
getStatement, hasSet, setConst, setAttr, setStatement);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
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, const LexToken*& token) {
|
||||
|
||||
Reference in New Issue
Block a user