Implements parsing for loop, cleanup of memory handling in parser.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
0c8b9f3943
commit
a3a996d68a
|
@ -1,5 +1,5 @@
|
||||||
Checks: 'readability-*,clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*,performance-*,cppcoreguidelines-*,
|
Checks: 'readability-*,clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*,performance-*,
|
||||||
bugprone-*,modernize-*,-modernize-use-trailing-return-type'
|
bugprone-*,modernize-*,-modernize-use-trailing-return-type,-readability-function-cognitive-complexity'
|
||||||
HeaderFilterRegex: ''
|
HeaderFilterRegex: ''
|
||||||
AnalyzeTemporaryDtors: false
|
AnalyzeTemporaryDtors: false
|
||||||
CheckOptions:
|
CheckOptions:
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace MalachScript::Parser {
|
||||||
if (currentToken->GetKind() == LexTokenKind::EndOfFile) {
|
if (currentToken->GetKind() == LexTokenKind::EndOfFile) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const ParsedStatement* statement;
|
ScopedPtr<const ParsedStatement> statement;
|
||||||
auto result = ParseClass(statement, currentToken) || ParseFunc(statement, currentToken) ||
|
auto result = ParseClass(statement, currentToken) || ParseFunc(statement, currentToken) ||
|
||||||
ParseNamespace(statement, currentToken);
|
ParseNamespace(statement, currentToken);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -38,7 +38,7 @@ namespace MalachScript::Parser {
|
||||||
PROGRESS_TOKEN(currentToken);
|
PROGRESS_TOKEN(currentToken);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
statements.push_back(statement);
|
statements.push_back(statement.TakeOwnership());
|
||||||
current++;
|
current++;
|
||||||
}
|
}
|
||||||
statements.resize(current);
|
statements.resize(current);
|
||||||
|
@ -48,7 +48,7 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
return new ParsedScriptStatement(TextSpan(0, end), statements);
|
return new ParsedScriptStatement(TextSpan(0, end), statements);
|
||||||
}
|
}
|
||||||
bool Parser::ParseClass(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseClass(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
auto start = current->GetSpan().GetStart();
|
auto start = current->GetSpan().GetStart();
|
||||||
bool lookingForClass = true;
|
bool lookingForClass = true;
|
||||||
|
@ -107,14 +107,14 @@ namespace MalachScript::Parser {
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const ParsedStatement* statement = nullptr;
|
ScopedPtr<const ParsedStatement> statement = nullptr;
|
||||||
// TODO: Sort by complexity
|
// TODO: Sort by complexity
|
||||||
if (!ParseVirtProp(statement, current) && !ParseFunc(statement, current) &&
|
if (!ParseVirtProp(statement, current) && !ParseFunc(statement, current) &&
|
||||||
!ParseVar(statement, current) && !ParseFuncDef(statement, current)) {
|
!ParseVar(statement, current) && !ParseFuncDef(statement, current)) {
|
||||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
body.push_back(statement);
|
body.push_back(statement.TakeOwnership());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ namespace MalachScript::Parser {
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Parser::ParseTypeDef(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseTypeDef(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
if (current->GetKind() != LexTokenKind::TypedefKeyword) {
|
if (current->GetKind() != LexTokenKind::TypedefKeyword) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -143,10 +143,10 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
EXPECT_TOKEN(current, SemicolonSymbol);
|
EXPECT_TOKEN(current, SemicolonSymbol);
|
||||||
out = new ParsedTypeDefStatement(TextSpan(start, current->GetSpan().GetEnd()), defineTo, defineFrom);
|
out = new ParsedTypeDefStatement(TextSpan(start, current->GetSpan().GetEnd()), defineFrom, defineTo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Parser::ParseNamespace(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseNamespace(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
if (current->GetKind() != LexTokenKind::NamespaceKeyword) {
|
if (current->GetKind() != LexTokenKind::NamespaceKeyword) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -164,7 +164,7 @@ namespace MalachScript::Parser {
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Parser::ParseFunc(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseFunc(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
auto start = current->GetSpan().GetStart();
|
auto start = current->GetSpan().GetStart();
|
||||||
bool isShared = false;
|
bool isShared = false;
|
||||||
|
@ -191,7 +191,7 @@ namespace MalachScript::Parser {
|
||||||
accessModifier = AccessModifier::Protected;
|
accessModifier = AccessModifier::Protected;
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
}
|
}
|
||||||
const ParsedStatement* typeStatement = nullptr;
|
ScopedPtr<const ParsedStatement> typeStatement = nullptr;
|
||||||
bool returnsReference = false;
|
bool returnsReference = false;
|
||||||
if (current->GetKind() == LexTokenKind::TildeSymbol) {
|
if (current->GetKind() == LexTokenKind::TildeSymbol) {
|
||||||
// TODO: Handle destructor
|
// TODO: Handle destructor
|
||||||
|
@ -204,13 +204,11 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
Identifier identifier;
|
Identifier identifier;
|
||||||
if (!ParseIdentifier(identifier, current)) {
|
if (!ParseIdentifier(identifier, current)) {
|
||||||
delete typeStatement;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
const ParsedStatement* paramList = nullptr;
|
ScopedPtr<const ParsedStatement> paramList = nullptr;
|
||||||
if (!ParseParamList(paramList, current)) {
|
if (!ParseParamList(paramList, current)) {
|
||||||
delete typeStatement;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool isConst = false;
|
bool isConst = false;
|
||||||
|
@ -220,7 +218,7 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
FuncAttr funcAttr = FuncAttr::None;
|
FuncAttr funcAttr = FuncAttr::None;
|
||||||
ParseFuncAttr(funcAttr, current);
|
ParseFuncAttr(funcAttr, current);
|
||||||
const ParsedStatement* statblock = nullptr;
|
ScopedPtr<const ParsedStatement> statblock = nullptr;
|
||||||
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
if (current->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||||
if (!ParseStatBlock(statblock, current)) {
|
if (!ParseStatBlock(statblock, current)) {
|
||||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
|
@ -229,13 +227,13 @@ namespace MalachScript::Parser {
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
}
|
}
|
||||||
out = new ParsedFuncStatement(TextSpan(start, current->GetSpan().GetEnd()), isShared, isExternal,
|
out = new ParsedFuncStatement(TextSpan(start, current->GetSpan().GetEnd()), isShared, isExternal,
|
||||||
accessModifier, typeStatement, returnsReference, identifier, paramList, isConst,
|
accessModifier, typeStatement.TakeOwnership(), returnsReference, identifier,
|
||||||
funcAttr, statblock);
|
paramList.TakeOwnership(), isConst, funcAttr, statblock.TakeOwnership());
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseType(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseType(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* token = currentToken;
|
const auto* token = currentToken;
|
||||||
auto start = token->GetSpan().GetStart();
|
auto start = token->GetSpan().GetStart();
|
||||||
bool isConst = false;
|
bool isConst = false;
|
||||||
|
@ -339,7 +337,7 @@ namespace MalachScript::Parser {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseParamList(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseParamList(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
if (currentToken->GetKind() != LexTokenKind::OpenParenthesisSymbol) {
|
if (currentToken->GetKind() != LexTokenKind::OpenParenthesisSymbol) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -362,7 +360,7 @@ namespace MalachScript::Parser {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
const ParsedStatement* typeStatement = nullptr;
|
ScopedPtr<const ParsedStatement> typeStatement = nullptr;
|
||||||
TypeMod typeMod = TypeMod::None;
|
TypeMod typeMod = TypeMod::None;
|
||||||
Identifier identifier;
|
Identifier identifier;
|
||||||
const ParsedStatement* defaultExpression = nullptr;
|
const ParsedStatement* defaultExpression = nullptr;
|
||||||
|
@ -376,7 +374,8 @@ namespace MalachScript::Parser {
|
||||||
// TODO: Default expression
|
// TODO: Default expression
|
||||||
|
|
||||||
parameters.push_back(new ParsedParamListStatement::ParsedParameter(
|
parameters.push_back(new ParsedParamListStatement::ParsedParameter(
|
||||||
dynamic_cast<const ParsedTypeStatement*>(typeStatement), typeMod, identifier, defaultExpression));
|
dynamic_cast<const ParsedTypeStatement*>(typeStatement.TakeOwnership()), typeMod, identifier,
|
||||||
|
defaultExpression));
|
||||||
|
|
||||||
if (currentToken->GetKind() != LexTokenKind::CommaSymbol) {
|
if (currentToken->GetKind() != LexTokenKind::CommaSymbol) {
|
||||||
break;
|
break;
|
||||||
|
@ -419,7 +418,7 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseVirtProp([[maybe_unused]] const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseVirtProp([[maybe_unused]] ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
AccessModifier access = AccessModifier::Public;
|
AccessModifier access = AccessModifier::Public;
|
||||||
if (current->GetKind() == LexTokenKind::PrivateKeyword) {
|
if (current->GetKind() == LexTokenKind::PrivateKeyword) {
|
||||||
|
@ -429,7 +428,7 @@ namespace MalachScript::Parser {
|
||||||
access = AccessModifier::Protected;
|
access = AccessModifier::Protected;
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
}
|
}
|
||||||
const ParsedStatement* typeStatement = nullptr;
|
ScopedPtr<const ParsedStatement> typeStatement = nullptr;
|
||||||
if (!ParseType(typeStatement, current)) {
|
if (!ParseType(typeStatement, current)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -440,22 +439,20 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
Identifier identifier;
|
Identifier identifier;
|
||||||
if (!ParseIdentifier(identifier, current)) {
|
if (!ParseIdentifier(identifier, current)) {
|
||||||
delete typeStatement;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
||||||
delete typeStatement;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool hasGet = false;
|
bool hasGet = false;
|
||||||
bool getConst = false;
|
bool getConst = false;
|
||||||
FuncAttr getAttr = FuncAttr::None;
|
FuncAttr getAttr = FuncAttr::None;
|
||||||
const ParsedStatement* getStatement = nullptr;
|
ScopedPtr<const ParsedStatement> getStatement = nullptr;
|
||||||
bool hasSet = false;
|
bool hasSet = false;
|
||||||
bool setConst = false;
|
bool setConst = false;
|
||||||
FuncAttr setAttr = FuncAttr::None;
|
FuncAttr setAttr = FuncAttr::None;
|
||||||
const ParsedStatement* setStatement = nullptr;
|
ScopedPtr<const ParsedStatement> setStatement = nullptr;
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
while (true) {
|
while (true) {
|
||||||
auto start = current->GetSpan().GetStart();
|
auto start = current->GetSpan().GetStart();
|
||||||
|
@ -510,31 +507,33 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
out = new ParsedVirtPropStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
out = new ParsedVirtPropStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||||
access, typeStatement, ref, identifier, hasGet, getConst, getAttr,
|
access, typeStatement.TakeOwnership(), ref, identifier, hasGet, getConst,
|
||||||
getStatement, hasSet, setConst, setAttr, setStatement);
|
getAttr, getStatement.TakeOwnership(), hasSet, setConst, setAttr,
|
||||||
|
setStatement.TakeOwnership());
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseIfStatement([[maybe_unused]] const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseIfStatement([[maybe_unused]] ScopedPtr<const ParsedStatement>& out,
|
||||||
|
const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
if (current->GetKind() != LexTokenKind::IfKeyword) {
|
if (current->GetKind() != LexTokenKind::IfKeyword) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
EXPECT_TOKEN(current, OpenParenthesisSymbol);
|
EXPECT_TOKEN(current, OpenParenthesisSymbol);
|
||||||
const ParsedStatement* condition = nullptr;
|
ScopedPtr<const ParsedStatement> condition = nullptr;
|
||||||
if (!ParseAssign(condition, current)) {
|
if (!ParseAssign(condition, current)) {
|
||||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||||
const ParsedStatement* body = nullptr;
|
ScopedPtr<const ParsedStatement> body = nullptr;
|
||||||
if (!ParseStatement(body, current)) {
|
if (!ParseStatement(body, current)) {
|
||||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const ParsedStatement* elseStatement = nullptr;
|
ScopedPtr<const ParsedStatement> elseStatement = nullptr;
|
||||||
if (current->GetKind() == LexTokenKind::ElseKeyword) {
|
if (current->GetKind() == LexTokenKind::ElseKeyword) {
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
if (!ParseStatement(elseStatement, current)) {
|
if (!ParseStatement(elseStatement, current)) {
|
||||||
|
@ -542,19 +541,20 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out = new ParsedIfStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
out = new ParsedIfStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||||
condition, body, elseStatement);
|
condition.TakeOwnership(), body.TakeOwnership(), elseStatement.TakeOwnership());
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseStatement(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
// TODO: All the other statements.
|
// TODO: All the other statements.
|
||||||
|
|
||||||
return ParseIfStatement(out, currentToken) || ParseReturn(out, currentToken) ||
|
return ParseIfStatement(out, currentToken) || ParseForStatement(out, currentToken) ||
|
||||||
ParseStatBlock(out, currentToken) || ParseExprStat(out, currentToken);
|
ParseReturn(out, currentToken) || ParseStatBlock(out, currentToken) || ParseBreak(out, currentToken) ||
|
||||||
|
ParseContinue(out, currentToken) || ParseExprStat(out, currentToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseVar([[maybe_unused]] const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseVar([[maybe_unused]] ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
AccessModifier access = AccessModifier::Public;
|
AccessModifier access = AccessModifier::Public;
|
||||||
if (current->GetKind() == LexTokenKind::PrivateKeyword) {
|
if (current->GetKind() == LexTokenKind::PrivateKeyword) {
|
||||||
|
@ -564,13 +564,12 @@ namespace MalachScript::Parser {
|
||||||
access = AccessModifier::Protected;
|
access = AccessModifier::Protected;
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
}
|
}
|
||||||
const ParsedStatement* typeStatement = nullptr;
|
ScopedPtr<const ParsedStatement> typeStatement = nullptr;
|
||||||
if (!ParseType(typeStatement, current)) {
|
if (!ParseType(typeStatement, current)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Identifier identifier;
|
Identifier identifier;
|
||||||
if (!ParseIdentifier(identifier, current)) {
|
if (!ParseIdentifier(identifier, current)) {
|
||||||
delete typeStatement;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
|
@ -578,12 +577,12 @@ namespace MalachScript::Parser {
|
||||||
// TODO: Creating multiple vars in a single line (int a, b, c)
|
// TODO: Creating multiple vars in a single line (int a, b, c)
|
||||||
EXPECT_TOKEN(current, SemicolonSymbol);
|
EXPECT_TOKEN(current, SemicolonSymbol);
|
||||||
out = new ParsedVarStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), access,
|
out = new ParsedVarStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), access,
|
||||||
typeStatement, identifier);
|
typeStatement.TakeOwnership(), identifier);
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseStatBlock(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseStatBlock(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -594,9 +593,9 @@ namespace MalachScript::Parser {
|
||||||
if (current->GetKind() == LexTokenKind::CloseCurlyParenthesisSymbol) {
|
if (current->GetKind() == LexTokenKind::CloseCurlyParenthesisSymbol) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const ParsedStatement* stat = nullptr;
|
ScopedPtr<const ParsedStatement> stat = nullptr;
|
||||||
if (ParseVar(stat, current) || ParseStatement(stat, current)) {
|
if (ParseVar(stat, current) || ParseStatement(stat, current)) {
|
||||||
statements.push_back(stat);
|
statements.push_back(stat.TakeOwnership());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -613,7 +612,7 @@ namespace MalachScript::Parser {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseFuncDef([[maybe_unused]] const ParsedStatement*& out,
|
bool Parser::ParseFuncDef([[maybe_unused]] ScopedPtr<const ParsedStatement>& out,
|
||||||
[[maybe_unused]] const LexToken*& currentToken) {
|
[[maybe_unused]] const LexToken*& currentToken) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -657,111 +656,73 @@ namespace MalachScript::Parser {
|
||||||
default: typeMod = TypeMod::RefInOut; return true;
|
default: typeMod = TypeMod::RefInOut; return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool Parser::ParseAssign(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseAssign(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
const ParsedStatement* leftHand = nullptr;
|
ScopedPtr<const ParsedStatement> leftHand = nullptr;
|
||||||
if (!ParseTernary(leftHand, current)) {
|
if (!ParseTernary(leftHand, current)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AssignmentOperator op;
|
AssignmentOperator op;
|
||||||
if (!ParseAssignOp(op, current)) {
|
if (!ParseAssignOp(op, current)) {
|
||||||
out = leftHand;
|
out = leftHand.TakeOwnership();
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
const ParsedStatement* rightHand = nullptr;
|
ScopedPtr<const ParsedStatement> rightHand = nullptr;
|
||||||
if (!ParseAssign(rightHand, current)) {
|
if (!ParseAssign(rightHand, current)) {
|
||||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
out = leftHand;
|
out = leftHand.TakeOwnership();
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
out = new ParsedBinaryStatement<AssignmentOperator>(
|
out = new ParsedBinaryStatement<AssignmentOperator>(
|
||||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, op, rightHand);
|
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand.TakeOwnership(), op,
|
||||||
|
rightHand.TakeOwnership());
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseTernary(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseTernary(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
// TODO: implement ternary.
|
// TODO: implement ternary.
|
||||||
return ParseExpr(out, currentToken);
|
return ParseExpr(out, currentToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseExpr(const ParsedStatement*& out, const LexToken*& currentToken) {
|
#define EXPR_PARSER(operator, name, func) \
|
||||||
|
operator name; \
|
||||||
|
if (func(name, current)) { \
|
||||||
|
PROGRESS_TOKEN(current); \
|
||||||
|
ScopedPtr<const ParsedStatement> rightHand = nullptr; \
|
||||||
|
if (!ParseExprTerm(rightHand, current)) { \
|
||||||
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan()); \
|
||||||
|
out = leftHand.TakeOwnership(); \
|
||||||
|
currentToken = current; \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
out = new ParsedBinaryStatement < operator>(TextSpan(currentToken->GetSpan().GetStart(), \
|
||||||
|
current->GetSpan().GetEnd()), \
|
||||||
|
leftHand.TakeOwnership(), name, rightHand.TakeOwnership()); \
|
||||||
|
currentToken = current; \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Parser::ParseExpr(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
const ParsedStatement* leftHand = nullptr;
|
ScopedPtr<const ParsedStatement> leftHand = nullptr;
|
||||||
if (!ParseExprTerm(leftHand, current)) {
|
if (!ParseExprTerm(leftHand, current)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MathOperator mathOp;
|
EXPR_PARSER(MathOperator, mathOp, ParseMathOp);
|
||||||
if (ParseMathOp(mathOp, current)) {
|
EXPR_PARSER(ComparisonOperator, compOp, ParseCompOp);
|
||||||
PROGRESS_TOKEN(current);
|
EXPR_PARSER(LogicOperator, logicOp, ParseLogicOp);
|
||||||
const ParsedStatement* rightHand = nullptr;
|
EXPR_PARSER(BitOperator, bitOp, ParseBitOp);
|
||||||
if (!ParseExprTerm(rightHand, current)) {
|
|
||||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
out = leftHand.TakeOwnership();
|
||||||
out = leftHand;
|
|
||||||
currentToken = current;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
out = new ParsedBinaryStatement<MathOperator>(
|
|
||||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand, mathOp, rightHand);
|
|
||||||
currentToken = current;
|
|
||||||
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);
|
|
||||||
currentToken = current;
|
|
||||||
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);
|
|
||||||
currentToken = current;
|
|
||||||
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);
|
|
||||||
currentToken = current;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
out = leftHand;
|
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::ParseExprTerm([[maybe_unused]] const ParsedStatement*& out,
|
bool Parser::ParseExprTerm(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
[[maybe_unused]] const LexToken*& currentToken) {
|
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
// TODO ([type '='] initlist)
|
// TODO ([type '='] initlist)
|
||||||
|
|
||||||
|
@ -770,7 +731,7 @@ namespace MalachScript::Parser {
|
||||||
if (hasPreOp) {
|
if (hasPreOp) {
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
}
|
}
|
||||||
const ParsedStatement* operand = nullptr;
|
ScopedPtr<const ParsedStatement> operand = nullptr;
|
||||||
if (!ParseExprValue(operand, current)) {
|
if (!ParseExprValue(operand, current)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -778,22 +739,22 @@ namespace MalachScript::Parser {
|
||||||
// TODO: remainder of
|
// TODO: remainder of
|
||||||
if (current->GetKind() == LexTokenKind::PlusPlusSymbol) {
|
if (current->GetKind() == LexTokenKind::PlusPlusSymbol) {
|
||||||
operand = new ParsedIncrementStatement(TextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
operand = new ParsedIncrementStatement(TextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||||
operand);
|
operand.TakeOwnership());
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
} else if (current->GetKind() == LexTokenKind::MinusMinusSymbol) {
|
} else if (current->GetKind() == LexTokenKind::MinusMinusSymbol) {
|
||||||
operand = new ParsedDecrementStatement(TextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
operand = new ParsedDecrementStatement(TextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||||
operand);
|
operand.TakeOwnership());
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPreOp) {
|
if (hasPreOp) {
|
||||||
// TODO: integrate pre operator
|
// TODO: integrate pre operator
|
||||||
}
|
}
|
||||||
out = operand;
|
out = operand.TakeOwnership();
|
||||||
currentToken = current;
|
currentToken = current;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Parser::ParseExprValue(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseExprValue(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
const auto* current = currentToken;
|
const auto* current = currentToken;
|
||||||
if (current->GetKind() == LexTokenKind::VoidKeyword) {
|
if (current->GetKind() == LexTokenKind::VoidKeyword) {
|
||||||
PROGRESS_TOKEN(current);
|
PROGRESS_TOKEN(current);
|
||||||
|
@ -825,7 +786,7 @@ namespace MalachScript::Parser {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool Parser::ParseLiteral(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseLiteral(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
switch (currentToken->GetKind()) {
|
switch (currentToken->GetKind()) {
|
||||||
case LexTokenKind::IntegerLiteral:
|
case LexTokenKind::IntegerLiteral:
|
||||||
out = new ParsedLiteralStatement<ParseInt>(
|
out = new ParsedLiteralStatement<ParseInt>(
|
||||||
|
@ -857,26 +818,26 @@ namespace MalachScript::Parser {
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool Parser::ParseReturn(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseReturn(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
auto start = currentToken->GetSpan().GetStart();
|
auto start = currentToken->GetSpan().GetStart();
|
||||||
if (currentToken->GetKind() != LexTokenKind::ReturnKeyword) {
|
if (currentToken->GetKind() != LexTokenKind::ReturnKeyword) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PROGRESS_TOKEN(currentToken);
|
PROGRESS_TOKEN(currentToken);
|
||||||
const ParsedStatement* returnBody = nullptr;
|
ScopedPtr<const ParsedStatement> returnBody;
|
||||||
ParseAssign(returnBody, currentToken);
|
ParseAssign(returnBody, currentToken);
|
||||||
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
||||||
out = new ParsedReturnStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), returnBody);
|
out = new ParsedReturnStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), returnBody.TakeOwnership());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Parser::ParseExprStat(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseExprStat(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
if (!ParseAssign(out, currentToken)) {
|
if (!ParseAssign(out, currentToken)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Parser::ParseVarAccess(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseVarAccess(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
std::vector<Identifier> scope;
|
std::vector<Identifier> scope;
|
||||||
auto start = currentToken->GetSpan().GetStart();
|
auto start = currentToken->GetSpan().GetStart();
|
||||||
if (ParseScope(scope, currentToken)) {
|
if (ParseScope(scope, currentToken)) {
|
||||||
|
@ -893,8 +854,8 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool Parser::ParseContinue(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseContinue(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
if (currentToken->GetKind() == LexTokenKind::ContinueKeyword) {
|
if (currentToken->GetKind() != LexTokenKind::ContinueKeyword) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto start = currentToken->GetSpan().GetStart();
|
auto start = currentToken->GetSpan().GetStart();
|
||||||
|
@ -903,8 +864,8 @@ namespace MalachScript::Parser {
|
||||||
out = new ParsedContinueStatement(TextSpan(start, currentToken->GetSpan().GetEnd()));
|
out = new ParsedContinueStatement(TextSpan(start, currentToken->GetSpan().GetEnd()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Parser::ParseBreak(const ParsedStatement*& out, const LexToken*& currentToken) {
|
bool Parser::ParseBreak(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
if (currentToken->GetKind() == LexTokenKind::BreakKeyword) {
|
if (currentToken->GetKind() != LexTokenKind::BreakKeyword) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto start = currentToken->GetSpan().GetStart();
|
auto start = currentToken->GetSpan().GetStart();
|
||||||
|
@ -913,4 +874,44 @@ namespace MalachScript::Parser {
|
||||||
out = new ParsedBreakStatement(TextSpan(start, currentToken->GetSpan().GetEnd()));
|
out = new ParsedBreakStatement(TextSpan(start, currentToken->GetSpan().GetEnd()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool Parser::ParseForStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken) {
|
||||||
|
if (currentToken->GetKind() != LexTokenKind::ForKeyword) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto* current = currentToken;
|
||||||
|
PROGRESS_TOKEN(current);
|
||||||
|
EXPECT_TOKEN(current, OpenParenthesisSymbol);
|
||||||
|
ScopedPtr<const ParsedStatement> init;
|
||||||
|
if (!ParseVar(init, current) && !ParseExprStat(init, current)) {
|
||||||
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ScopedPtr<const ParsedStatement> condition;
|
||||||
|
if (!ParseExprStat(condition, current)) {
|
||||||
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::vector<const ParsedStatement*> increment;
|
||||||
|
while (true) {
|
||||||
|
ScopedPtr<const ParsedStatement> element;
|
||||||
|
if (ParseAssign(element, current)) {
|
||||||
|
increment.push_back(element.TakeOwnership());
|
||||||
|
}
|
||||||
|
if (current->GetKind() != LexTokenKind::CommaSymbol) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||||
|
ScopedPtr<const ParsedStatement> statementBlock;
|
||||||
|
if (!ParseStatement(statementBlock, current)) {
|
||||||
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out = new ParsedForStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||||
|
init.TakeOwnership(), condition.TakeOwnership(), increment,
|
||||||
|
statementBlock.TakeOwnership());
|
||||||
|
currentToken = current;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "../CoreData/Operators.hpp"
|
#include "../CoreData/Operators.hpp"
|
||||||
#include "../Diagnostics/Diagnostics.hpp"
|
#include "../Diagnostics/Diagnostics.hpp"
|
||||||
|
#include "../Utils/ScopedPtr.hpp"
|
||||||
#include "Lexer/LexToken.hpp"
|
#include "Lexer/LexToken.hpp"
|
||||||
#include "Statements/ParsedStatement.hpp"
|
#include "Statements/ParsedStatement.hpp"
|
||||||
|
|
||||||
|
@ -114,8 +115,8 @@ namespace MalachScript::Parser {
|
||||||
bool ParsePrimType(Identifier& out, const LexToken*& currentToken);
|
bool ParsePrimType(Identifier& out, const LexToken*& currentToken);
|
||||||
bool ParseDataType(Identifier& out, const LexToken*& currentToken);
|
bool ParseDataType(Identifier& out, const LexToken*& currentToken);
|
||||||
bool ParseScope(std::vector<Identifier>& out, const LexToken*& currentToken);
|
bool ParseScope(std::vector<Identifier>& out, const LexToken*& currentToken);
|
||||||
bool ParseType(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseType(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseAssign(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseAssign(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
// InitList
|
// InitList
|
||||||
inline static bool ParsePreOp(PreOperator& op, const LexToken*& token) {
|
inline static bool ParsePreOp(PreOperator& op, const LexToken*& token) {
|
||||||
switch (token->GetKind()) {
|
switch (token->GetKind()) {
|
||||||
|
@ -132,51 +133,51 @@ namespace MalachScript::Parser {
|
||||||
// ArgList
|
// ArgList
|
||||||
// FuncCall
|
// FuncCall
|
||||||
// ConstructCall
|
// ConstructCall
|
||||||
bool ParseVarAccess(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseVarAccess(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
// Cast
|
// Cast
|
||||||
bool ParseLiteral(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseLiteral(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseTypeMod(TypeMod& typeMod, const LexToken*& currentToken);
|
bool ParseTypeMod(TypeMod& typeMod, const LexToken*& currentToken);
|
||||||
// Lambda
|
// Lambda
|
||||||
|
|
||||||
bool ParseExprValue(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseExprValue(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
// ExprPostOp
|
// ExprPostOp
|
||||||
bool ParseExprTerm(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseExprTerm(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseExpr(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseExpr(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseTernary(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseTernary(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
|
|
||||||
bool ParseReturn(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseReturn(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseExprStat(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseExprStat(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseContinue(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseContinue(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseBreak(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseBreak(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
|
|
||||||
bool ParseIfStatement(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseIfStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
// For
|
bool ParseForStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
// While
|
// While
|
||||||
// DoWhile
|
// DoWhile
|
||||||
// Try
|
// Try
|
||||||
// Case
|
// Case
|
||||||
// Switch
|
// Switch
|
||||||
|
|
||||||
bool ParseStatement(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseVar(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseVar(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseStatBlock(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseStatBlock(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
|
|
||||||
bool ParseFuncAttr(FuncAttr& out, const LexToken*& currentToken);
|
bool ParseFuncAttr(FuncAttr& out, const LexToken*& currentToken);
|
||||||
bool ParseParamList(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseParamList(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
|
|
||||||
bool ParseVirtProp(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseVirtProp(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseFunc(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseFunc(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseFuncDef(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseFuncDef(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
bool ParseClass(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseClass(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
|
|
||||||
// Mixin
|
// Mixin
|
||||||
// Enum
|
// Enum
|
||||||
// Import
|
// Import
|
||||||
bool ParseTypeDef(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseTypeDef(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
|
|
||||||
// InterfaceMethod
|
// InterfaceMethod
|
||||||
// Interface
|
// Interface
|
||||||
bool ParseNamespace(const ParsedStatement*& out, const LexToken*& currentToken);
|
bool ParseNamespace(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken);
|
||||||
const ParsedScriptStatement* ParseScript();
|
const ParsedScriptStatement* ParseScript();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,6 +370,30 @@ namespace MalachScript::Parser {
|
||||||
ParsedBreakStatement(const TextSpan& span) : ParsedStatementImpl(span) {}
|
ParsedBreakStatement(const TextSpan& span) : ParsedStatementImpl(span) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ParsedForStatement : public ParsedStatementImpl<ParsedStatementKind::For> {
|
||||||
|
public:
|
||||||
|
ParsedForStatement(const TextSpan& span, const ParsedStatement* init, const ParsedStatement* condition,
|
||||||
|
std::vector<const ParsedStatement*> increment, const ParsedStatement* body)
|
||||||
|
: ParsedStatementImpl(span), _init(init), _condition(condition), _increment(increment.size()), _body(body) {
|
||||||
|
for (size_t i = 0; i < increment.size(); i++) {
|
||||||
|
_increment[i] = std::unique_ptr<const ParsedStatement>(increment[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::unique_ptr<const ParsedStatement>& GetInit() const noexcept { return _init; }
|
||||||
|
inline const std::unique_ptr<const ParsedStatement>& GetCondition() const noexcept { return _condition; }
|
||||||
|
inline const std::vector<std::unique_ptr<const ParsedStatement>>& GetIncrement() const noexcept {
|
||||||
|
return _increment;
|
||||||
|
}
|
||||||
|
inline const std::unique_ptr<const ParsedStatement>& GetBody() const noexcept { return _body; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<const ParsedStatement> _init;
|
||||||
|
std::unique_ptr<const ParsedStatement> _condition;
|
||||||
|
std::vector<std::unique_ptr<const ParsedStatement>> _increment;
|
||||||
|
std::unique_ptr<const ParsedStatement> _body;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MALACHSCRIPT_PARSEDSTATEMENT_HPP
|
#endif // MALACHSCRIPT_PARSEDSTATEMENT_HPP
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace MalachScript::Parser {
|
||||||
Decrement,
|
Decrement,
|
||||||
Continue,
|
Continue,
|
||||||
Break,
|
Break,
|
||||||
|
For,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef MALACHSCRIPT_SCOPEDPTR_HPP
|
||||||
|
#define MALACHSCRIPT_SCOPEDPTR_HPP
|
||||||
|
|
||||||
|
template <class T> class ScopedPtr {
|
||||||
|
T* _raw;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline ScopedPtr() { _raw = nullptr; }
|
||||||
|
|
||||||
|
inline ScopedPtr(T* ptr) { _raw = ptr; }
|
||||||
|
|
||||||
|
inline ScopedPtr& operator=(T* b) {
|
||||||
|
_raw = b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopedPtr(const ScopedPtr& b) = delete;
|
||||||
|
ScopedPtr& operator=(ScopedPtr const&) = delete;
|
||||||
|
|
||||||
|
inline ~ScopedPtr() { delete _raw; }
|
||||||
|
|
||||||
|
inline T* TakeOwnership() noexcept {
|
||||||
|
auto b = _raw;
|
||||||
|
_raw = nullptr;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T* operator->() { return _raw; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MALACHSCRIPT_SCOPEDPTR_HPP
|
Loading…
Reference in New Issue