Large chunk of work in parser for getting expressions to work.
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:
@@ -204,11 +204,13 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
Identifier identifier;
|
||||
if (!ParseIdentifier(identifier, current)) {
|
||||
delete typeStatement;
|
||||
return false;
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
const ParsedStatement* paramList = nullptr;
|
||||
if (!ParseParamList(paramList, current)) {
|
||||
delete typeStatement;
|
||||
return false;
|
||||
}
|
||||
bool isConst = false;
|
||||
@@ -285,7 +287,7 @@ namespace MalachScript::Parser {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (current != nullptr && current->GetKind() == LexTokenKind::ColonColonSymbol) {
|
||||
while (current->GetKind() == LexTokenKind::ColonColonSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
const auto* n = current;
|
||||
if (ParseIdentifier(identifier, n)) {
|
||||
@@ -440,6 +442,7 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
||||
delete typeStatement;
|
||||
return false;
|
||||
}
|
||||
bool hasGet = false;
|
||||
@@ -464,8 +467,9 @@ namespace MalachScript::Parser {
|
||||
if (!ParseStatBlock(getStatement, current)) {
|
||||
this->LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
} else {
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
|
||||
if (hasGet) {
|
||||
this->LogError(Diagnostics::DiagnosticType::DoubleProperty,
|
||||
@@ -483,8 +487,9 @@ namespace MalachScript::Parser {
|
||||
if (!ParseStatBlock(setStatement, current)) {
|
||||
this->LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
} else {
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
|
||||
if (hasSet) {
|
||||
this->LogError(Diagnostics::DiagnosticType::DoubleProperty,
|
||||
@@ -541,7 +546,9 @@ namespace MalachScript::Parser {
|
||||
|
||||
bool Parser::ParseStatement(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
// TODO: All the other statements.
|
||||
return ParseIfStatement(out, currentToken);
|
||||
|
||||
return ParseIfStatement(out, currentToken) || ParseReturn(out, currentToken) ||
|
||||
ParseStatBlock(out, currentToken) || ParseExprStat(out, currentToken);
|
||||
}
|
||||
|
||||
bool Parser::ParseVar([[maybe_unused]] const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
@@ -566,11 +573,7 @@ namespace MalachScript::Parser {
|
||||
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());
|
||||
}
|
||||
EXPECT_TOKEN(current, SemicolonSymbol);
|
||||
out = new ParsedVarStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), access,
|
||||
typeStatement, identifier);
|
||||
currentToken = current;
|
||||
@@ -582,6 +585,7 @@ namespace MalachScript::Parser {
|
||||
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
||||
return false;
|
||||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
std::vector<const ParsedStatement*> statements;
|
||||
while (true) {
|
||||
if (current->GetKind() == LexTokenKind::CloseCurlyParenthesisSymbol) {
|
||||
@@ -699,6 +703,7 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
out = new ParsedBinaryStatement<MathOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, mathOp, rightHand);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
ComparisonOperator compOp;
|
||||
@@ -713,6 +718,7 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
out = new ParsedBinaryStatement<ComparisonOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, compOp, rightHand);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
LogicOperator logicOp;
|
||||
@@ -728,6 +734,7 @@ namespace MalachScript::Parser {
|
||||
out = new ParsedBinaryStatement<LogicOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, logicOp,
|
||||
rightHand);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
BitOperator bitOp;
|
||||
@@ -742,6 +749,7 @@ namespace MalachScript::Parser {
|
||||
}
|
||||
out = new ParsedBinaryStatement<BitOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, bitOp, rightHand);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
out = leftHand;
|
||||
@@ -751,6 +759,135 @@ namespace MalachScript::Parser {
|
||||
|
||||
bool Parser::ParseExprTerm([[maybe_unused]] const ParsedStatement*& out,
|
||||
[[maybe_unused]] const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
// TODO ([type '='] initlist)
|
||||
|
||||
PreOperator preOperator;
|
||||
bool hasPreOp = ParsePreOp(preOperator, currentToken);
|
||||
if (hasPreOp) {
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
const ParsedStatement* operand = nullptr;
|
||||
if (!ParseExprValue(operand, current)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: remainder of
|
||||
if (current->GetKind() == LexTokenKind::PlusPlusSymbol) {
|
||||
operand = new ParsedIncrementStatement(TextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
operand);
|
||||
PROGRESS_TOKEN(current);
|
||||
} else if (current->GetKind() == LexTokenKind::MinusMinusSymbol) {
|
||||
operand = new ParsedDecrementStatement(TextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
operand);
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
|
||||
if (hasPreOp) {
|
||||
// TODO: integrate pre operator
|
||||
}
|
||||
out = operand;
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseExprValue(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
const auto* current = currentToken;
|
||||
if (current->GetKind() == LexTokenKind::VoidKeyword) {
|
||||
PROGRESS_TOKEN(current);
|
||||
|
||||
out = new ParsedVoidStatement(currentToken->GetSpan());
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
// TODO: constructcall
|
||||
// TODO: funccall
|
||||
if (ParseVarAccess(out, current)) {
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
// TODO: cast
|
||||
if (ParseLiteral(out, current)) {
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
if (current->GetKind() == LexTokenKind::OpenParenthesisSymbol) {
|
||||
PROGRESS_TOKEN(current);
|
||||
if (!ParseAssign(out, current)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||
}
|
||||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||
return true;
|
||||
}
|
||||
// TODO: lambda
|
||||
|
||||
return false;
|
||||
}
|
||||
bool Parser::ParseLiteral(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
switch (currentToken->GetKind()) {
|
||||
case LexTokenKind::IntegerLiteral:
|
||||
out = new ParsedLiteralStatement<ParseInt>(
|
||||
currentToken->GetSpan(), static_cast<const IntegerLiteral*>(currentToken)->GetValue());
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
case LexTokenKind::FloatLiteral:
|
||||
out = new ParsedLiteralStatement<ParseFloat>(
|
||||
currentToken->GetSpan(), static_cast<const FloatLiteral*>(currentToken)->GetValue());
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
case LexTokenKind::StringLiteral:
|
||||
out = new ParsedLiteralStatement<ParseString>(
|
||||
currentToken->GetSpan(), static_cast<const StringLiteral*>(currentToken)->GetValue());
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
case LexTokenKind::TrueKeyword:
|
||||
out = new ParsedLiteralStatement<bool>(currentToken->GetSpan(), true);
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
case LexTokenKind::FalseKeyword:
|
||||
out = new ParsedLiteralStatement<bool>(currentToken->GetSpan(), false);
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
case LexTokenKind::NullKeyword:
|
||||
out = new ParsedLiteralStatement<void*>(currentToken->GetSpan(), nullptr);
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
bool Parser::ParseReturn(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
auto start = currentToken->GetSpan().GetStart();
|
||||
if (currentToken->GetKind() != LexTokenKind::ReturnKeyword) {
|
||||
return false;
|
||||
}
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
const ParsedStatement* returnBody = nullptr;
|
||||
ParseAssign(returnBody, currentToken);
|
||||
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
||||
out = new ParsedReturnStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), returnBody);
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseExprStat(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
if (!ParseAssign(out, currentToken)){
|
||||
return false;
|
||||
}
|
||||
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseVarAccess(const ParsedStatement*& out, const LexToken*& currentToken) {
|
||||
std::vector<Identifier> scope;
|
||||
auto start = currentToken->GetSpan().GetStart();
|
||||
if (ParseScope(scope, currentToken)) {
|
||||
out = new ParsedVarAccessStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), scope);
|
||||
return true;
|
||||
}
|
||||
Identifier identifier;
|
||||
if (ParseIdentifier(identifier, currentToken)) {
|
||||
scope.clear();
|
||||
scope.push_back(identifier);
|
||||
out = new ParsedVarAccessStatement(currentToken->GetSpan(), scope);
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user