More work on better parser logging.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
034dcb118b
commit
da82819fff
|
@ -41,9 +41,12 @@ namespace util {
|
|||
|
||||
char* endptr = nullptr;
|
||||
index = strtol(&item[0], &endptr, 10);
|
||||
if (index < 0 || index >= (int)args.size()) {
|
||||
if (index >= (int)args.size()) {
|
||||
return;
|
||||
}
|
||||
if (index < 0) {
|
||||
index = args.size() + index;
|
||||
}
|
||||
|
||||
if (*endptr == ',') {
|
||||
alignment = strtol(endptr + 1, &endptr, 10);
|
||||
|
@ -57,8 +60,21 @@ namespace util {
|
|||
if (*endptr == ':') {
|
||||
fmt = endptr + 1;
|
||||
}
|
||||
if (*endptr == '.' && *(endptr + 1) == '.') {
|
||||
auto endIndex = strtol(endptr + 2, &endptr, 10);
|
||||
if (endIndex < 0) {
|
||||
endIndex = args.size() + endIndex + 1;
|
||||
}
|
||||
|
||||
args[index]->Format(ss, fmt);
|
||||
for (; index < endIndex; index++) {
|
||||
args[index]->Format(ss, fmt);
|
||||
if (index != endIndex - 1) {
|
||||
ss << ", ";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
args[index]->Format(ss, fmt);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,14 @@ namespace MalachScript::Diagnostics {
|
|||
case DiagnosticType::ExpectedEndOfString:
|
||||
return util::Format("Expected end of string, found {0}", diag->GetFormats());
|
||||
case DiagnosticType::UnexpectedToken:
|
||||
return util::Format("Unexpected Token. Expected any of: {0}, but found {1}", diag->GetFormats());
|
||||
if (diag->GetFormats().size() == 1) {
|
||||
return util::Format("Unexpected Token: '{0}'", diag->GetFormats());
|
||||
} else if (diag->GetFormats().size() == 2) {
|
||||
return util::Format("Unexpected Token. Expected: '{0}', but found '{-1}'", diag->GetFormats());
|
||||
} else if (diag->GetFormats().size() > 2) {
|
||||
return util::Format("Unexpected Token. Expected any of: '{0..-2}', but found '{-1}'",
|
||||
diag->GetFormats());
|
||||
}
|
||||
case DiagnosticType::DoubleProperty: return "Property block found twice.";
|
||||
}
|
||||
return std::to_string((uint8_t)diag->GetType());
|
||||
|
|
|
@ -144,127 +144,127 @@ namespace MalachScript::Parser {
|
|||
|
||||
case LexTokenKind::Unknown: return "Unknown";
|
||||
case LexTokenKind::EndOfFile: return "EndOfFile";
|
||||
case LexTokenKind::Whitespace: break;
|
||||
case LexTokenKind::StarSymbol: break;
|
||||
case LexTokenKind::StarStarSymbol: break;
|
||||
case LexTokenKind::SlashSymbol: break;
|
||||
case LexTokenKind::PercentSymbol: break;
|
||||
case LexTokenKind::PlusSymbol: break;
|
||||
case LexTokenKind::MinusSymbol: break;
|
||||
case LexTokenKind::LessThanEqualsSymbol: break;
|
||||
case LexTokenKind::LessThanSymbol: break;
|
||||
case LexTokenKind::GreaterThanEqualsSymbol: break;
|
||||
case LexTokenKind::GreaterThanSymbol: break;
|
||||
case LexTokenKind::OpenParenthesisSymbol: break;
|
||||
case LexTokenKind::CloseParenthesisSymbol: break;
|
||||
case LexTokenKind::EqualsEqualsSymbol: break;
|
||||
case LexTokenKind::ExclamationMarkEqualsSymbol: break;
|
||||
case LexTokenKind::QuestionMarkSymbol: break;
|
||||
case LexTokenKind::ColonSymbol: break;
|
||||
case LexTokenKind::EqualsSymbol: break;
|
||||
case LexTokenKind::PlusEqualsSymbol: break;
|
||||
case LexTokenKind::MinusEqualsSymbol: break;
|
||||
case LexTokenKind::StarEqualsSymbol: break;
|
||||
case LexTokenKind::SlashEqualsSymbol: break;
|
||||
case LexTokenKind::PercentEqualsSymbol: break;
|
||||
case LexTokenKind::StarStarEqualsSymbol: break;
|
||||
case LexTokenKind::PlusPlusSymbol: break;
|
||||
case LexTokenKind::MinusMinusSymbol: break;
|
||||
case LexTokenKind::AmpersandSymbol: break;
|
||||
case LexTokenKind::CommaSymbol: break;
|
||||
case LexTokenKind::OpenCurlyParenthesisSymbol: break;
|
||||
case LexTokenKind::CloseCurlyParenthesisSymbol: break;
|
||||
case LexTokenKind::SemicolonSymbol: break;
|
||||
case LexTokenKind::VerticalLineSymbol: break;
|
||||
case LexTokenKind::CaretSymbol: break;
|
||||
case LexTokenKind::TildeSymbol: break;
|
||||
case LexTokenKind::LessThanLessThanSymbol: break;
|
||||
case LexTokenKind::GreaterThanGreaterThanSymbol: break;
|
||||
case LexTokenKind::GreaterThanGreaterThanGreaterThanSymbol: break;
|
||||
case LexTokenKind::AmpersandEqualsSymbol: break;
|
||||
case LexTokenKind::VerticalLineEqualsSymbol: break;
|
||||
case LexTokenKind::CaretEqualsSymbol: break;
|
||||
case LexTokenKind::LessThanLessThanEqualsSymbol: break;
|
||||
case LexTokenKind::GreaterThanGreaterThanEqualsSymbol: break;
|
||||
case LexTokenKind::GreaterThanGreaterThanGreaterThanEqualsSymbol: break;
|
||||
case LexTokenKind::DotSymbol: break;
|
||||
case LexTokenKind::AmpersandAmpersandSymbol: break;
|
||||
case LexTokenKind::VerticalLineVerticalLineSymbol: break;
|
||||
case LexTokenKind::ExclamationMarkSymbol: break;
|
||||
case LexTokenKind::OpenBlockParenthesisSymbol: break;
|
||||
case LexTokenKind::CloseBlockParenthesisSymbol: break;
|
||||
case LexTokenKind::CaretCaretSymbol: break;
|
||||
case LexTokenKind::AtSymbol: break;
|
||||
case LexTokenKind::ExclamationMarkIsSymbol: break;
|
||||
case LexTokenKind::ColonColonSymbol: break;
|
||||
case LexTokenKind::AndKeyword: break;
|
||||
case LexTokenKind::AbstractKeyword: break;
|
||||
case LexTokenKind::AutoKeyword: break;
|
||||
case LexTokenKind::BoolKeyword: break;
|
||||
case LexTokenKind::BreakKeyword: break;
|
||||
case LexTokenKind::CaseKeyword: break;
|
||||
case LexTokenKind::CastKeyword: break;
|
||||
case LexTokenKind::CatchKeyword: break;
|
||||
case LexTokenKind::ClassKeyword: break;
|
||||
case LexTokenKind::ConstKeyword: break;
|
||||
case LexTokenKind::ContinueKeyword: break;
|
||||
case LexTokenKind::DefaultKeyword: break;
|
||||
case LexTokenKind::DoKeyword: break;
|
||||
case LexTokenKind::DoubleKeyword: break;
|
||||
case LexTokenKind::ElseKeyword: break;
|
||||
case LexTokenKind::EnumKeyword: break;
|
||||
case LexTokenKind::ExplicitKeyword: break;
|
||||
case LexTokenKind::ExternalKeyword: break;
|
||||
case LexTokenKind::FalseKeyword: break;
|
||||
case LexTokenKind::FinalKeyword: break;
|
||||
case LexTokenKind::FloatKeyword: break;
|
||||
case LexTokenKind::ForKeyword: break;
|
||||
case LexTokenKind::FromKeyword: break;
|
||||
case LexTokenKind::FuncdefKeyword: break;
|
||||
case LexTokenKind::FunctionKeyword: break;
|
||||
case LexTokenKind::GetKeyword: break;
|
||||
case LexTokenKind::IfKeyword: break;
|
||||
case LexTokenKind::ImportKeyword: break;
|
||||
case LexTokenKind::InKeyword: break;
|
||||
case LexTokenKind::InoutKeyword: break;
|
||||
case LexTokenKind::IntKeyword: break;
|
||||
case LexTokenKind::InterfaceKeyword: break;
|
||||
case LexTokenKind::Int8Keyword: break;
|
||||
case LexTokenKind::Int16Keyword: break;
|
||||
case LexTokenKind::Int32Keyword: break;
|
||||
case LexTokenKind::Int64Keyword: break;
|
||||
case LexTokenKind::IsKeyword: break;
|
||||
case LexTokenKind::MixinKeyword: break;
|
||||
case LexTokenKind::NamespaceKeyword: break;
|
||||
case LexTokenKind::NotKeyword: break;
|
||||
case LexTokenKind::NullKeyword: break;
|
||||
case LexTokenKind::OrKeyword: break;
|
||||
case LexTokenKind::OutKeyword: break;
|
||||
case LexTokenKind::OverrideKeyword: break;
|
||||
case LexTokenKind::PrivateKeyword: break;
|
||||
case LexTokenKind::PropertyKeyword: break;
|
||||
case LexTokenKind::ProtectedKeyword: break;
|
||||
case LexTokenKind::ReturnKeyword: break;
|
||||
case LexTokenKind::SetKeyword: break;
|
||||
case LexTokenKind::SharedKeyword: break;
|
||||
case LexTokenKind::SuperKeyword: break;
|
||||
case LexTokenKind::SwitchKeyword: break;
|
||||
case LexTokenKind::ThisKeyword: break;
|
||||
case LexTokenKind::TrueKeyword: break;
|
||||
case LexTokenKind::TryKeyword: break;
|
||||
case LexTokenKind::TypedefKeyword: break;
|
||||
case LexTokenKind::UintKeyword: break;
|
||||
case LexTokenKind::Uint8Keyword: break;
|
||||
case LexTokenKind::Uint16Keyword: break;
|
||||
case LexTokenKind::Uint32Keyword: break;
|
||||
case LexTokenKind::Uint64Keyword: break;
|
||||
case LexTokenKind::VoidKeyword: break;
|
||||
case LexTokenKind::WhileKeyword: break;
|
||||
case LexTokenKind::XorKeyword: break;
|
||||
case LexTokenKind::FloatLiteral: break;
|
||||
case LexTokenKind::IntegerLiteral: break;
|
||||
case LexTokenKind::StringLiteral: break;
|
||||
case LexTokenKind::Identifier: break;
|
||||
case LexTokenKind::Whitespace: return "Whitespace";
|
||||
case LexTokenKind::StarSymbol: return "*";
|
||||
case LexTokenKind::StarStarSymbol: return "**";
|
||||
case LexTokenKind::SlashSymbol: return "/";
|
||||
case LexTokenKind::PercentSymbol: return "%";
|
||||
case LexTokenKind::PlusSymbol: return "+";
|
||||
case LexTokenKind::MinusSymbol: return "-";
|
||||
case LexTokenKind::LessThanEqualsSymbol: return "<=";
|
||||
case LexTokenKind::LessThanSymbol: return "<";
|
||||
case LexTokenKind::GreaterThanEqualsSymbol: return ">=";
|
||||
case LexTokenKind::GreaterThanSymbol: return ">";
|
||||
case LexTokenKind::OpenParenthesisSymbol: return "(";
|
||||
case LexTokenKind::CloseParenthesisSymbol: return ")";
|
||||
case LexTokenKind::EqualsEqualsSymbol: return "==";
|
||||
case LexTokenKind::ExclamationMarkEqualsSymbol: return "!=";
|
||||
case LexTokenKind::QuestionMarkSymbol: return "?";
|
||||
case LexTokenKind::ColonSymbol: return ":";
|
||||
case LexTokenKind::EqualsSymbol: return "=";
|
||||
case LexTokenKind::PlusEqualsSymbol: return "+=";
|
||||
case LexTokenKind::MinusEqualsSymbol: return "-=";
|
||||
case LexTokenKind::StarEqualsSymbol: return "*=";
|
||||
case LexTokenKind::SlashEqualsSymbol: return "/=";
|
||||
case LexTokenKind::PercentEqualsSymbol: return "%=";
|
||||
case LexTokenKind::StarStarEqualsSymbol: return "**=";
|
||||
case LexTokenKind::PlusPlusSymbol: return "++";
|
||||
case LexTokenKind::MinusMinusSymbol: return "--";
|
||||
case LexTokenKind::AmpersandSymbol: return "&";
|
||||
case LexTokenKind::CommaSymbol: return ",";
|
||||
case LexTokenKind::OpenCurlyParenthesisSymbol: return "{";
|
||||
case LexTokenKind::CloseCurlyParenthesisSymbol: return "}";
|
||||
case LexTokenKind::SemicolonSymbol: return ";";
|
||||
case LexTokenKind::VerticalLineSymbol: return "|";
|
||||
case LexTokenKind::CaretSymbol: return "^";
|
||||
case LexTokenKind::TildeSymbol: return "~";
|
||||
case LexTokenKind::LessThanLessThanSymbol: return "<<";
|
||||
case LexTokenKind::GreaterThanGreaterThanSymbol: return ">>";
|
||||
case LexTokenKind::GreaterThanGreaterThanGreaterThanSymbol: return ">>>";
|
||||
case LexTokenKind::AmpersandEqualsSymbol: return "&=";
|
||||
case LexTokenKind::VerticalLineEqualsSymbol: return "|=";
|
||||
case LexTokenKind::CaretEqualsSymbol: return "^=";
|
||||
case LexTokenKind::LessThanLessThanEqualsSymbol: return "<<=";
|
||||
case LexTokenKind::GreaterThanGreaterThanEqualsSymbol: return ">>=";
|
||||
case LexTokenKind::GreaterThanGreaterThanGreaterThanEqualsSymbol: return ">>>=";
|
||||
case LexTokenKind::DotSymbol: return ".";
|
||||
case LexTokenKind::AmpersandAmpersandSymbol: return "&";
|
||||
case LexTokenKind::VerticalLineVerticalLineSymbol: return "||";
|
||||
case LexTokenKind::ExclamationMarkSymbol: return "!";
|
||||
case LexTokenKind::OpenBlockParenthesisSymbol: return "[";
|
||||
case LexTokenKind::CloseBlockParenthesisSymbol: return "]";
|
||||
case LexTokenKind::CaretCaretSymbol: return "^^";
|
||||
case LexTokenKind::AtSymbol: return "@";
|
||||
case LexTokenKind::ExclamationMarkIsSymbol: return "!=";
|
||||
case LexTokenKind::ColonColonSymbol: return "::";
|
||||
case LexTokenKind::AndKeyword: return "and";
|
||||
case LexTokenKind::AbstractKeyword: return "abstract";
|
||||
case LexTokenKind::AutoKeyword: return "auto";
|
||||
case LexTokenKind::BoolKeyword: return "bool";
|
||||
case LexTokenKind::BreakKeyword: return "break";
|
||||
case LexTokenKind::CaseKeyword: return "case";
|
||||
case LexTokenKind::CastKeyword: return "cast";
|
||||
case LexTokenKind::CatchKeyword: return "catch";
|
||||
case LexTokenKind::ClassKeyword: return "class";
|
||||
case LexTokenKind::ConstKeyword: return "const";
|
||||
case LexTokenKind::ContinueKeyword: return "continue";
|
||||
case LexTokenKind::DefaultKeyword: return "default";
|
||||
case LexTokenKind::DoKeyword: return "do";
|
||||
case LexTokenKind::DoubleKeyword: return "double";
|
||||
case LexTokenKind::ElseKeyword: return "else";
|
||||
case LexTokenKind::EnumKeyword: return "enum";
|
||||
case LexTokenKind::ExplicitKeyword: return "explicit";
|
||||
case LexTokenKind::ExternalKeyword: return "external";
|
||||
case LexTokenKind::FalseKeyword: return "false";
|
||||
case LexTokenKind::FinalKeyword: return "final";
|
||||
case LexTokenKind::FloatKeyword: return "float";
|
||||
case LexTokenKind::ForKeyword: return "for";
|
||||
case LexTokenKind::FromKeyword: return "from";
|
||||
case LexTokenKind::FuncdefKeyword: return "funcdef";
|
||||
case LexTokenKind::FunctionKeyword: return "function";
|
||||
case LexTokenKind::GetKeyword: return "get";
|
||||
case LexTokenKind::IfKeyword: return "if";
|
||||
case LexTokenKind::ImportKeyword: return "import";
|
||||
case LexTokenKind::InKeyword: return "in";
|
||||
case LexTokenKind::InoutKeyword: return "inout";
|
||||
case LexTokenKind::IntKeyword: return "int";
|
||||
case LexTokenKind::InterfaceKeyword: return "interface";
|
||||
case LexTokenKind::Int8Keyword: return "int8";
|
||||
case LexTokenKind::Int16Keyword: return "int16";
|
||||
case LexTokenKind::Int32Keyword: return "int32";
|
||||
case LexTokenKind::Int64Keyword: return "int64";
|
||||
case LexTokenKind::IsKeyword: return "is";
|
||||
case LexTokenKind::MixinKeyword: return "mixin";
|
||||
case LexTokenKind::NamespaceKeyword: return "namespace";
|
||||
case LexTokenKind::NotKeyword: return "not";
|
||||
case LexTokenKind::NullKeyword: return "null";
|
||||
case LexTokenKind::OrKeyword: return "or";
|
||||
case LexTokenKind::OutKeyword: return "out";
|
||||
case LexTokenKind::OverrideKeyword: return "override";
|
||||
case LexTokenKind::PrivateKeyword: return "private";
|
||||
case LexTokenKind::PropertyKeyword: return "property";
|
||||
case LexTokenKind::ProtectedKeyword: return "protected";
|
||||
case LexTokenKind::ReturnKeyword: return "return";
|
||||
case LexTokenKind::SetKeyword: return "set";
|
||||
case LexTokenKind::SharedKeyword: return "shared";
|
||||
case LexTokenKind::SuperKeyword: return "super";
|
||||
case LexTokenKind::SwitchKeyword: return "switch";
|
||||
case LexTokenKind::ThisKeyword: return "this";
|
||||
case LexTokenKind::TrueKeyword: return "true";
|
||||
case LexTokenKind::TryKeyword: return "try";
|
||||
case LexTokenKind::TypedefKeyword: return "typedef";
|
||||
case LexTokenKind::UintKeyword: return "uint";
|
||||
case LexTokenKind::Uint8Keyword: return "uint8";
|
||||
case LexTokenKind::Uint16Keyword: return "uint16";
|
||||
case LexTokenKind::Uint32Keyword: return "uint32";
|
||||
case LexTokenKind::Uint64Keyword: return "uint64";
|
||||
case LexTokenKind::VoidKeyword: return "void";
|
||||
case LexTokenKind::WhileKeyword: return "while";
|
||||
case LexTokenKind::XorKeyword: return "xor";
|
||||
case LexTokenKind::FloatLiteral: return "float";
|
||||
case LexTokenKind::IntegerLiteral: return "integer";
|
||||
case LexTokenKind::StringLiteral: return "string";
|
||||
case LexTokenKind::Identifier: return "identifier";
|
||||
}
|
||||
return "FAIL";
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#define EXPECT_TOKEN(token, kind) \
|
||||
if ((token)->GetKind() != LexTokenKind::kind) { \
|
||||
logError(DiagnosticType::UnexpectedToken, (token)->GetSpan(), {}); \
|
||||
logUnexpectedToken(kind, token); \
|
||||
if ((token)->GetNext() != nullptr && (token)->GetNext()->GetNext() != nullptr && \
|
||||
(token)->GetNext()->GetKind() == LexTokenKind::kind) { \
|
||||
(token) = (token)->GetNext()->GetNext().get(); \
|
||||
|
@ -21,6 +21,19 @@
|
|||
}
|
||||
|
||||
#define logError(type, span, formats) log(DiagnosticLevel::Error, type, span, formats)
|
||||
#define logUnexpectedToken(expected, found) \
|
||||
log(DiagnosticLevel::Error, DiagnosticType::UnexpectedToken, (found)->GetSpan(), \
|
||||
{LexTokenKindHelper::ToString(LexTokenKind::expected), (found)->ToString()});
|
||||
#define logUnexpectedTokenWithAnyOf(found, ...) \
|
||||
std::vector<LexTokenKind> vars = {__VA_ARGS__}; \
|
||||
auto expectedTokens = std::vector<std::string>(vars.size() + 1); \
|
||||
for (size_t i = 0; i < vars.size(); i++) { \
|
||||
expectedTokens[i] = LexTokenKindHelper::ToString(vars[i]); \
|
||||
} \
|
||||
expectedTokens[expectedTokens.size() - 1] = (found)->ToString(); \
|
||||
log(DiagnosticLevel::Error, DiagnosticType::UnexpectedToken, (found)->GetSpan(), expectedTokens);
|
||||
#define logUnexpectedTokenWithoutExpected(found) \
|
||||
log(DiagnosticLevel::Error, DiagnosticType::UnexpectedToken, (found)->GetSpan(), {(found)->ToString()});
|
||||
|
||||
namespace MalachScript::Parser {
|
||||
using namespace Diagnostics;
|
||||
|
@ -64,8 +77,7 @@ namespace MalachScript::Parser {
|
|||
auto result = ParseTypeDef(statement, current, log) || ParseClass(statement, current, log) ||
|
||||
ParseFunc(statement, current, log) || ParseNamespace(statement, current, log);
|
||||
if (!result) {
|
||||
log(DiagnosticLevel::Error, DiagnosticType::UnexpectedToken, current->GetSpan(),
|
||||
{"", current->ToString()});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
PROGRESS_TOKEN(current);
|
||||
continue;
|
||||
}
|
||||
|
@ -100,7 +112,7 @@ namespace MalachScript::Parser {
|
|||
// After class keyword, an identifier should always follow, if it doesn't, log an error.
|
||||
Identifier identifier;
|
||||
if (!ParseIdentifier(identifier, current)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(Identifier, current);
|
||||
return false;
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
|
@ -116,21 +128,21 @@ namespace MalachScript::Parser {
|
|||
PROGRESS_TOKEN(current);
|
||||
Identifier id;
|
||||
if (!ParseIdentifier(id, current)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(Identifier, current);
|
||||
return false;
|
||||
}
|
||||
inherits.push_back(id);
|
||||
while (current->GetKind() == LexTokenKind::CommaSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (!ParseIdentifier(id, current)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(Identifier, current);
|
||||
return false;
|
||||
}
|
||||
inherits.push_back(id);
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(OpenCurlyParenthesisSymbol, current);
|
||||
return false;
|
||||
}
|
||||
[[fallthrough]];
|
||||
|
@ -148,14 +160,16 @@ namespace MalachScript::Parser {
|
|||
// TODO: Sort by complexity
|
||||
if (!ParseVirtProp(statement, current, log) && !ParseFunc(statement, current, log) &&
|
||||
!ParseVar(statement, current, log) && !ParseFuncDef(statement, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
break;
|
||||
}
|
||||
body.push_back(statement.TakeOwnership());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {}); return false;
|
||||
default:
|
||||
logUnexpectedTokenWithAnyOf(current, LexTokenKind::SemicolonSymbol, LexTokenKind::ColonSymbol,
|
||||
LexTokenKind::OpenCurlyParenthesisSymbol);
|
||||
}
|
||||
out = new ParsedClassStatement(TextSpan(start, current->GetSpan().GetEnd()), classAttr, identifier, inherits,
|
||||
body);
|
||||
|
@ -172,13 +186,13 @@ namespace MalachScript::Parser {
|
|||
PROGRESS_TOKEN(current);
|
||||
Identifier defineFrom;
|
||||
if (!ParsePrimType(defineFrom, current, log) && !ParseIdentifier(defineFrom, current)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
|
||||
PROGRESS_TOKEN(current);
|
||||
Identifier defineTo;
|
||||
if (!ParseIdentifier(defineTo, current)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(Identifier, current);
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
EXPECT_TOKEN(current, SemicolonSymbol);
|
||||
|
@ -195,14 +209,14 @@ namespace MalachScript::Parser {
|
|||
PROGRESS_TOKEN(current);
|
||||
Identifier identifier;
|
||||
if (!ParseIdentifier(identifier, current)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(Identifier, current);
|
||||
} else {
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
EXPECT_TOKEN(current, OpenCurlyParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> script = nullptr;
|
||||
if (!ParseScript(script, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
auto end = current->GetSpan().GetEnd();
|
||||
EXPECT_TOKEN(current, CloseCurlyParenthesisSymbol);
|
||||
|
@ -268,7 +282,7 @@ namespace MalachScript::Parser {
|
|||
ScopedPtr<const ParsedStatement> statblock = nullptr;
|
||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
if (!ParseStatBlock(statblock, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -282,39 +296,39 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
|
||||
bool Parser::ParseType(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func& log) {
|
||||
const auto* token = currentToken;
|
||||
auto start = token->GetSpan().GetStart();
|
||||
const auto* current = currentToken;
|
||||
auto start = current->GetSpan().GetStart();
|
||||
bool isConst = false;
|
||||
bool isArray = false;
|
||||
bool isHandle = false;
|
||||
if (token->GetKind() == LexTokenKind::ConstKeyword) {
|
||||
if (current->GetKind() == LexTokenKind::ConstKeyword) {
|
||||
isConst = true;
|
||||
PROGRESS_TOKEN(token);
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
ScopedIdentifier scopedIdentifier;
|
||||
ParseScope(scopedIdentifier.GetScope(), token, log);
|
||||
if (!ParseDataType(scopedIdentifier.GetIdentifier(), token, log)) {
|
||||
ParseScope(scopedIdentifier.GetScope(), current, log);
|
||||
if (!ParseDataType(scopedIdentifier.GetIdentifier(), current, log)) {
|
||||
return false;
|
||||
}
|
||||
// TODO: Generics.
|
||||
if (token->GetKind() == LexTokenKind::OpenBlockParenthesisSymbol) {
|
||||
PROGRESS_TOKEN(token);
|
||||
if (token->GetKind() != LexTokenKind::CloseBlockParenthesisSymbol) {
|
||||
logError(DiagnosticType::UnexpectedToken, token->GetSpan(), {});
|
||||
if (current->GetKind() == LexTokenKind::OpenBlockParenthesisSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (current->GetKind() != LexTokenKind::CloseBlockParenthesisSymbol) {
|
||||
logUnexpectedToken(CloseCurlyParenthesisSymbol, current);
|
||||
} else {
|
||||
PROGRESS_TOKEN(token);
|
||||
PROGRESS_TOKEN(current);
|
||||
isArray = true;
|
||||
}
|
||||
} else if (token->GetKind() == LexTokenKind::AtSymbol) {
|
||||
} else if (current->GetKind() == LexTokenKind::AtSymbol) {
|
||||
isHandle = true;
|
||||
PROGRESS_TOKEN(token);
|
||||
if (token->GetKind() == LexTokenKind::ConstKeyword) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (current->GetKind() == LexTokenKind::ConstKeyword) {
|
||||
isConst = true;
|
||||
PROGRESS_TOKEN(token);
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
}
|
||||
auto end = token->GetSpan().GetEnd();
|
||||
currentToken = token;
|
||||
auto end = current->GetSpan().GetEnd();
|
||||
currentToken = current;
|
||||
out = new ParsedTypeStatement(TextSpan(start, end), isConst, isArray, isHandle, scopedIdentifier);
|
||||
return true;
|
||||
}
|
||||
|
@ -348,7 +362,7 @@ namespace MalachScript::Parser {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
logError(DiagnosticType::UnexpectedToken, currentToken->GetSpan(), {});
|
||||
logUnexpectedToken(Identifier, current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -412,11 +426,11 @@ namespace MalachScript::Parser {
|
|||
const ParsedStatement* defaultExpression = nullptr;
|
||||
|
||||
if (!ParseType(typeStatement, currentToken, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, currentToken->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(currentToken);
|
||||
}
|
||||
ParseTypeMod(typeMod, currentToken, log);
|
||||
if (!ParseIdentifier(identifier, currentToken)) {
|
||||
logError(DiagnosticType::UnexpectedToken, currentToken->GetSpan(), {});
|
||||
logUnexpectedToken(Identifier, currentToken);
|
||||
} else {
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
}
|
||||
|
@ -503,7 +517,7 @@ namespace MalachScript::Parser {
|
|||
ParseFuncAttr(getAttr, current, log);
|
||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
if (!ParseStatBlock(getStatement, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
} else {
|
||||
PROGRESS_TOKEN(current);
|
||||
|
@ -522,7 +536,7 @@ namespace MalachScript::Parser {
|
|||
ParseFuncAttr(setAttr, current, log);
|
||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
if (!ParseStatBlock(setStatement, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
} else {
|
||||
PROGRESS_TOKEN(current);
|
||||
|
@ -537,7 +551,7 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
}
|
||||
if (current->GetKind() != LexTokenKind::CloseCurlyParenthesisSymbol) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(CloseCurlyParenthesisSymbol, current);
|
||||
} else {
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
|
@ -560,18 +574,18 @@ namespace MalachScript::Parser {
|
|||
EXPECT_TOKEN(current, OpenParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> condition = nullptr;
|
||||
if (!ParseAssign(condition, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> body = nullptr;
|
||||
if (!ParseStatement(body, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
ScopedPtr<const ParsedStatement> elseStatement = nullptr;
|
||||
if (current->GetKind() == LexTokenKind::ElseKeyword) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (!ParseStatement(elseStatement, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
}
|
||||
out = new ParsedIfStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
|
@ -649,7 +663,7 @@ namespace MalachScript::Parser {
|
|||
if (current->GetKind() == LexTokenKind::CloseCurlyParenthesisSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
} else {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(CloseCurlyParenthesisSymbol, current);
|
||||
}
|
||||
|
||||
out = new ParsedStatBlockStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
|
@ -719,7 +733,7 @@ namespace MalachScript::Parser {
|
|||
PROGRESS_TOKEN(current);
|
||||
ScopedPtr<const ParsedStatement> rightHand = nullptr;
|
||||
if (!ParseAssign(rightHand, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
out = leftHand.TakeOwnership();
|
||||
currentToken = current;
|
||||
return true;
|
||||
|
@ -743,7 +757,7 @@ namespace MalachScript::Parser {
|
|||
PROGRESS_TOKEN(current); \
|
||||
ScopedPtr<const ParsedStatement> rightHand = nullptr; \
|
||||
if (!ParseExprTerm(rightHand, current, log)) { \
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {}); \
|
||||
logUnexpectedTokenWithoutExpected(current); \
|
||||
out = leftHand.TakeOwnership(); \
|
||||
currentToken = current; \
|
||||
return true; \
|
||||
|
@ -828,7 +842,7 @@ namespace MalachScript::Parser {
|
|||
if (current->GetKind() == LexTokenKind::OpenParenthesisSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (!ParseAssign(out, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||
currentToken = current;
|
||||
|
@ -942,12 +956,12 @@ namespace MalachScript::Parser {
|
|||
EXPECT_TOKEN(current, OpenParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> init;
|
||||
if (!ParseVar(init, current, log) && !ParseExprStat(init, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
ScopedPtr<const ParsedStatement> condition;
|
||||
if (!ParseExprStat(condition, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
std::vector<const ParsedStatement*> increment;
|
||||
|
@ -963,7 +977,7 @@ namespace MalachScript::Parser {
|
|||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> statementBlock;
|
||||
if (!ParseStatement(statementBlock, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -984,13 +998,13 @@ namespace MalachScript::Parser {
|
|||
EXPECT_TOKEN(current, OpenParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> condition = nullptr;
|
||||
if (!ParseAssign(condition, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> body = nullptr;
|
||||
if (!ParseStatement(body, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
out = new ParsedWhileStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
|
@ -1007,14 +1021,14 @@ namespace MalachScript::Parser {
|
|||
PROGRESS_TOKEN(current);
|
||||
ScopedPtr<const ParsedStatement> body = nullptr;
|
||||
if (!ParseStatement(body, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
EXPECT_TOKEN(current, WhileKeyword);
|
||||
EXPECT_TOKEN(current, OpenParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> condition = nullptr;
|
||||
if (!ParseAssign(condition, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||
|
@ -1034,13 +1048,13 @@ namespace MalachScript::Parser {
|
|||
|
||||
ScopedPtr<const ParsedStatement> tryStatement = nullptr;
|
||||
if (!ParseStatBlock(tryStatement, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
EXPECT_TOKEN(current, CatchKeyword);
|
||||
ScopedPtr<const ParsedStatement> catchStatement = nullptr;
|
||||
if (!ParseStatBlock(catchStatement, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1059,7 +1073,7 @@ namespace MalachScript::Parser {
|
|||
EXPECT_TOKEN(currentToken, OpenParenthesisSymbol);
|
||||
ScopedPtr<const ParsedStatement> expression = nullptr;
|
||||
if (!ParseExpr(expression, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
EXPECT_TOKEN(currentToken, CloseParenthesisSymbol);
|
||||
|
@ -1080,7 +1094,7 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
caseStatements.push_back(stat.TakeOwnership());
|
||||
} else {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedToken(CaseKeyword, current);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1106,7 +1120,7 @@ namespace MalachScript::Parser {
|
|||
ScopedPtr<const ParsedStatement> expression = nullptr;
|
||||
if (!isDefault) {
|
||||
if (!ParseExpr(expression, current, log)) {
|
||||
logError(DiagnosticType::UnexpectedToken, current->GetSpan(), {});
|
||||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue