Large chunk of work in parser for getting expressions to work.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2020-11-08 15:41:18 +01:00
parent c20a1089a9
commit 5fb64e12e1
12 changed files with 344 additions and 41 deletions

View File

@@ -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;
}
}