Initial work on expression 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:
@@ -11,6 +11,8 @@
|
||||
#define EXPECT_TOKEN(token, kind) \
|
||||
if (token->GetKind() != LexTokenKind::kind) { \
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, token->GetSpan()); \
|
||||
} else { \
|
||||
PROGRESS_TOKEN(token); \
|
||||
}
|
||||
|
||||
namespace MalachScript::Parser {
|
||||
@@ -20,18 +22,20 @@ namespace MalachScript::Parser {
|
||||
std::vector<const ParsedStatement*> statements;
|
||||
statements.reserve(32);
|
||||
size_t current = 0;
|
||||
const auto* currentToken = _firstToken;
|
||||
while (true) {
|
||||
while (_currentToken->GetKind() == LexTokenKind::Whitespace) {
|
||||
_currentToken = _currentToken->GetNext().get();
|
||||
while (currentToken->GetKind() == LexTokenKind::Whitespace) {
|
||||
currentToken = currentToken->GetNext().get();
|
||||
}
|
||||
if (_currentToken->GetKind() == LexTokenKind::EndOfFile) {
|
||||
if (currentToken->GetKind() == LexTokenKind::EndOfFile) {
|
||||
break;
|
||||
}
|
||||
const ParsedStatement* statement;
|
||||
auto result = ParseClass(statement) || ParseFunc(statement) || ParseNamespace(statement);
|
||||
auto result = ParseClass(statement, currentToken) || ParseFunc(statement, currentToken) ||
|
||||
ParseNamespace(statement, currentToken);
|
||||
if (!result) {
|
||||
// TODO: Log error
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
continue;
|
||||
}
|
||||
statements.push_back(statement);
|
||||
@@ -44,8 +48,8 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
return new ParsedScriptStatement(TextSpan(0, end), statements);
|
||||
}
|
||||
bool Parser::ParseClass(const ParsedStatement*& out) {
|
||||
const auto* current = _currentToken;
|
||||
bool Parser::ParseClass(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
auto start = current->GetSpan().GetStart();
|
||||
bool lookingForClass = true;
|
||||
while (lookingForClass) {
|
||||
@@ -62,7 +66,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(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
std::vector<Identifier> inherits;
|
||||
@@ -77,14 +81,14 @@ namespace MalachScript::Parser {
|
||||
case LexTokenKind::ColonSymbol: {
|
||||
PROGRESS_TOKEN(current);
|
||||
Identifier id;
|
||||
if (!ParseIdentifier(id, _currentToken)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
if (!ParseIdentifier(id, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
inherits.push_back(id);
|
||||
while (current->GetKind() == LexTokenKind::CommaSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (!ParseIdentifier(id, _currentToken)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
if (!ParseIdentifier(id, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
inherits.push_back(id);
|
||||
PROGRESS_TOKEN(current);
|
||||
@@ -105,123 +109,124 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
const ParsedStatement* statement = nullptr;
|
||||
// TODO: Sort by complexity
|
||||
if (!ParseVirtProp(statement, current) && !ParseFunc(statement) && !ParseVar(statement) &&
|
||||
!ParseFuncDef(statement)) {
|
||||
if (!ParseVirtProp(statement, current) && !ParseFunc(statement, current) &&
|
||||
!ParseVar(statement, current) && !ParseFuncDef(statement, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
break;
|
||||
} else {
|
||||
body.push_back(statement);
|
||||
}
|
||||
body.push_back(statement);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: throw;
|
||||
}
|
||||
out = new ParsedClassStatement(TextSpan(start, current->GetSpan().GetEnd()), identifier, inherits, body);
|
||||
_currentToken = current;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseTypeDef(const ParsedStatement*& out) {
|
||||
if (_currentToken->GetKind() != LexTokenKind::TypedefKeyword) {
|
||||
bool Parser::ParseTypeDef(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
if (current->GetKind() != LexTokenKind::TypedefKeyword) {
|
||||
return false;
|
||||
}
|
||||
auto start = _currentToken->GetSpan().GetStart();
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
auto start = current->GetSpan().GetStart();
|
||||
PROGRESS_TOKEN(current);
|
||||
Identifier defineFrom;
|
||||
if (!ParsePrimType(defineFrom, _currentToken) && !ParseIdentifier(defineFrom, _currentToken)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
if (!ParsePrimType(defineFrom, current) && !ParseIdentifier(defineFrom, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
PROGRESS_TOKEN(current);
|
||||
Identifier defineTo;
|
||||
if (!ParseIdentifier(defineTo, _currentToken)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
if (!ParseIdentifier(defineTo, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
EXPECT_TOKEN(_currentToken, SemicolonSymbol);
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
out = new ParsedTypeDefStatement(TextSpan(start, _currentToken->GetSpan().GetEnd()), defineTo, defineFrom);
|
||||
PROGRESS_TOKEN(current);
|
||||
EXPECT_TOKEN(current, SemicolonSymbol);
|
||||
out = new ParsedTypeDefStatement(TextSpan(start, current->GetSpan().GetEnd()), defineTo, defineFrom);
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseNamespace(const ParsedStatement*& out) {
|
||||
if (_currentToken->GetKind() != LexTokenKind::NamespaceKeyword) {
|
||||
bool Parser::ParseNamespace(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
if (current->GetKind() != LexTokenKind::NamespaceKeyword) {
|
||||
return false;
|
||||
}
|
||||
auto start = _currentToken->GetSpan().GetStart();
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
auto start = current->GetSpan().GetStart();
|
||||
PROGRESS_TOKEN(current);
|
||||
Identifier identifier;
|
||||
if (!ParseIdentifier(identifier, _currentToken)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
if (!ParseIdentifier(identifier, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
const auto* script = ParseScript();
|
||||
auto end = _currentToken->GetSpan().GetEnd();
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
auto end = current->GetSpan().GetEnd();
|
||||
PROGRESS_TOKEN(current);
|
||||
out = new ParsedNamespaceStatement(TextSpan(start, end), identifier, script);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseFunc(const ParsedStatement*& out) {
|
||||
auto start = _currentToken->GetSpan().GetStart();
|
||||
const auto* token = _currentToken;
|
||||
bool Parser::ParseFunc(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
auto start = current->GetSpan().GetStart();
|
||||
bool isShared = false;
|
||||
bool isExternal = false;
|
||||
bool modifiers = true;
|
||||
while (modifiers) {
|
||||
switch (token->GetKind()) {
|
||||
switch (current->GetKind()) {
|
||||
case LexTokenKind::SharedKeyword:
|
||||
isShared = true;
|
||||
PROGRESS_TOKEN(token);
|
||||
PROGRESS_TOKEN(current);
|
||||
continue;
|
||||
case LexTokenKind::ExternalKeyword:
|
||||
isExternal = true;
|
||||
PROGRESS_TOKEN(token);
|
||||
PROGRESS_TOKEN(current);
|
||||
continue;
|
||||
default: modifiers = false; break;
|
||||
}
|
||||
}
|
||||
AccessModifier accessModifier = AccessModifier::Public;
|
||||
if (token->GetKind() == LexTokenKind::PrivateKeyword) {
|
||||
if (current->GetKind() == LexTokenKind::PrivateKeyword) {
|
||||
accessModifier = AccessModifier::Private;
|
||||
PROGRESS_TOKEN(token);
|
||||
} else if (token->GetKind() == LexTokenKind::ProtectedKeyword) {
|
||||
PROGRESS_TOKEN(current);
|
||||
} else if (current->GetKind() == LexTokenKind::ProtectedKeyword) {
|
||||
accessModifier = AccessModifier::Protected;
|
||||
PROGRESS_TOKEN(token);
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
const ParsedStatement* typeStatement = nullptr;
|
||||
bool returnsReference = false;
|
||||
if (token->GetKind() == LexTokenKind::TildeSymbol) {
|
||||
if (current->GetKind() == LexTokenKind::TildeSymbol) {
|
||||
// TODO: Handle destructor
|
||||
throw std::logic_error("not implemented");
|
||||
} else if (ParseType(typeStatement, token)) {
|
||||
if (token->GetKind() == LexTokenKind::AmpersandSymbol) {
|
||||
} else if (ParseType(typeStatement, current)) {
|
||||
if (current->GetKind() == LexTokenKind::AmpersandSymbol) {
|
||||
returnsReference = true;
|
||||
PROGRESS_TOKEN(token);
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
}
|
||||
Identifier identifier;
|
||||
if (!ParseIdentifier(identifier, token)) {
|
||||
if (!ParseIdentifier(identifier, current)) {
|
||||
return false;
|
||||
}
|
||||
PROGRESS_TOKEN(token);
|
||||
PROGRESS_TOKEN(current);
|
||||
const ParsedStatement* paramList = nullptr;
|
||||
if (!ParseParamList(paramList, token)) {
|
||||
if (!ParseParamList(paramList, current)) {
|
||||
return false;
|
||||
}
|
||||
_currentToken = token;
|
||||
bool isConst = false;
|
||||
if (_currentToken->GetKind() == LexTokenKind::ConstKeyword) {
|
||||
if (current->GetKind() == LexTokenKind::ConstKeyword) {
|
||||
isConst = true;
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
FuncAttr funcAttr = FuncAttr::None;
|
||||
ParseFuncAttr(funcAttr, _currentToken);
|
||||
ParseFuncAttr(funcAttr, current);
|
||||
const ParsedStatement* statblock = nullptr;
|
||||
if (_currentToken->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
// TODO: Parse stat block.
|
||||
throw std::logic_error("not implemented");
|
||||
}
|
||||
out = new ParsedFuncStatement(TextSpan(start, _currentToken->GetSpan().GetEnd()), isShared, isExternal,
|
||||
out = new ParsedFuncStatement(TextSpan(start, current->GetSpan().GetEnd()), isShared, isExternal,
|
||||
accessModifier, typeStatement, returnsReference, identifier, paramList, isConst,
|
||||
funcAttr, statblock);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -355,7 +360,7 @@ namespace MalachScript::Parser {
|
||||
const ParsedStatement* typeStatement = nullptr;
|
||||
TypeMod typeMod = TypeMod::None;
|
||||
Identifier identifier;
|
||||
const ParsedExpression* defaultExpression = nullptr;
|
||||
const ParsedStatement* defaultExpression = nullptr;
|
||||
|
||||
if (!ParseType(typeStatement, currentToken)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, currentToken->GetSpan());
|
||||
@@ -410,8 +415,8 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
|
||||
bool Parser::ParseVirtProp([[maybe_unused]] const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
AccessModifier access = AccessModifier::Public;
|
||||
const auto* current = currentToken;
|
||||
AccessModifier access = AccessModifier::Public;
|
||||
if (current->GetKind() == LexTokenKind::PrivateKeyword) {
|
||||
access = AccessModifier::Private;
|
||||
PROGRESS_TOKEN(current);
|
||||
@@ -456,11 +461,9 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
ParseFuncAttr(getAttr, current);
|
||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
// TODO: Parse stat block.
|
||||
// if (ParseStatBlock(getStatement, current)){
|
||||
//
|
||||
// }
|
||||
this->LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
if (!ParseStatBlock(getStatement, current)) {
|
||||
this->LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
|
||||
@@ -477,11 +480,9 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
ParseFuncAttr(setAttr, current);
|
||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
// TODO: Parse stat block.
|
||||
// if (ParseStatBlock(setStatement, current)){
|
||||
//
|
||||
// }
|
||||
this->LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
if (!ParseStatBlock(setStatement, current)) {
|
||||
this->LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
|
||||
@@ -507,8 +508,108 @@ namespace MalachScript::Parser {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::ParseVar([[maybe_unused]] const ParsedStatement*& out) { return false; }
|
||||
bool Parser::ParseFuncDef([[maybe_unused]] const ParsedStatement*& out) { return false; }
|
||||
bool Parser::ParseIfStatement([[maybe_unused]] const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
if (current->GetKind() != LexTokenKind::IfKeyword) {
|
||||
return false;
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
EXPECT_TOKEN(current, OpenParenthesisSymbol);
|
||||
const ParsedStatement* condition = nullptr;
|
||||
if (!ParseAssign(condition, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
return false;
|
||||
}
|
||||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||
const ParsedStatement* body = nullptr;
|
||||
if (!ParseStatement(body, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
return false;
|
||||
}
|
||||
const ParsedStatement* elseStatement = nullptr;
|
||||
if (current->GetKind() == LexTokenKind::ElseKeyword) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (!ParseStatement(elseStatement, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
}
|
||||
out = new ParsedIfStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
condition, body, elseStatement);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::ParseStatement(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
// TODO: All the other statements.
|
||||
return ParseIfStatement(out, currentToken);
|
||||
}
|
||||
|
||||
bool Parser::ParseVar([[maybe_unused]] const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
AccessModifier access = AccessModifier::Public;
|
||||
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;
|
||||
}
|
||||
Identifier identifier;
|
||||
if (!ParseIdentifier(identifier, current)) {
|
||||
delete typeStatement;
|
||||
return false;
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
// TODO: Default values
|
||||
// TODO: Creating multiple vars in a single line (int a, b, c)
|
||||
if (current->GetKind() == LexTokenKind::SemicolonSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
} else {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
out = new ParsedVarStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), access,
|
||||
typeStatement, identifier);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::ParseStatBlock(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
||||
return false;
|
||||
}
|
||||
std::vector<const ParsedStatement*> statements;
|
||||
while (true) {
|
||||
if (current->GetKind() == LexTokenKind::CloseCurlyParenthesisSymbol) {
|
||||
break;
|
||||
}
|
||||
const ParsedStatement* stat = nullptr;
|
||||
if (ParseVar(stat, current) || ParseStatement(stat, current)) {
|
||||
statements.push_back(stat);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (current->GetKind() == LexTokenKind::CloseCurlyParenthesisSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
} else {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
|
||||
out = new ParsedStatBlockStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
statements);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::ParseFuncDef([[maybe_unused]] const ParsedStatement*& out,
|
||||
[[maybe_unused]] const LexToken*& currentToken) {
|
||||
return false;
|
||||
}
|
||||
bool Parser::ParsePrimType(Identifier& out, const LexToken*& token) {
|
||||
switch (token->GetKind()) {
|
||||
case LexTokenKind::VoidKeyword: out = PrimitiveTypes::VoidName(); return true;
|
||||
@@ -549,4 +650,107 @@ namespace MalachScript::Parser {
|
||||
default: typeMod = TypeMod::RefInOut; return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool Parser::ParseAssign(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
const ParsedStatement* leftHand = nullptr;
|
||||
if (!ParseTernary(leftHand, current)) {
|
||||
return false;
|
||||
}
|
||||
AssignmentOperator op;
|
||||
if (!ParseAssignOp(op, current)) {
|
||||
out = leftHand;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
const ParsedStatement* rightHand = nullptr;
|
||||
if (!ParseAssign(rightHand, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
out = leftHand;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
out = new ParsedBinaryStatement<AssignmentOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, op, rightHand);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::ParseTernary(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
// TODO: implement ternary.
|
||||
return ParseExpr(out, currentToken);
|
||||
}
|
||||
|
||||
bool Parser::ParseExpr(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
const ParsedStatement* leftHand = nullptr;
|
||||
if (!ParseExprTerm(leftHand, current)) {
|
||||
return false;
|
||||
}
|
||||
MathOperator mathOp;
|
||||
if (ParseMathOp(mathOp, current)) {
|
||||
PROGRESS_TOKEN(current);
|
||||
const ParsedStatement* rightHand = nullptr;
|
||||
if (!ParseExprTerm(rightHand, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
out = leftHand;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
out = new ParsedBinaryStatement<MathOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, mathOp, rightHand);
|
||||
return true;
|
||||
}
|
||||
ComparisonOperator compOp;
|
||||
if (ParseCompOp(compOp, current)) {
|
||||
PROGRESS_TOKEN(current);
|
||||
const ParsedStatement* rightHand = nullptr;
|
||||
if (!ParseExprTerm(rightHand, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
out = leftHand;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
out = new ParsedBinaryStatement<ComparisonOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, compOp, rightHand);
|
||||
return true;
|
||||
}
|
||||
LogicOperator logicOp;
|
||||
if (ParseLogicOp(logicOp, current)) {
|
||||
PROGRESS_TOKEN(current);
|
||||
const ParsedStatement* rightHand = nullptr;
|
||||
if (!ParseExprTerm(rightHand, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
out = leftHand;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
out = new ParsedBinaryStatement<LogicOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, logicOp,
|
||||
rightHand);
|
||||
return true;
|
||||
}
|
||||
BitOperator bitOp;
|
||||
if (ParseBitOp(bitOp, current)) {
|
||||
PROGRESS_TOKEN(current);
|
||||
const ParsedStatement* rightHand = nullptr;
|
||||
if (!ParseExprTerm(rightHand, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
out = leftHand;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
out = new ParsedBinaryStatement<BitOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, bitOp, rightHand);
|
||||
return true;
|
||||
}
|
||||
out = leftHand;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::ParseExprTerm([[maybe_unused]] const ParsedStatement*& out,
|
||||
[[maybe_unused]] const LexToken*& currentToken) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user