Implemented generic for loops
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2019-06-26 16:19:34 +02:00
parent cfd558b718
commit d86e9ba8ae
18 changed files with 325 additions and 44 deletions

View File

@@ -21,7 +21,8 @@ namespace Porygon::Parser {
FunctionDeclaration,
Return,
Conditional,
NumericalFor
NumericalFor,
GenericFor
};
class ParsedStatement {
@@ -129,7 +130,7 @@ namespace Porygon::Parser {
const vector<TypedVariableIdentifier *> _parameters;
const ParsedBlockStatement *_block;
public:
ParsedFunctionDeclarationStatement(HashedString identifier, vector<TypedVariableIdentifier *> parameters,
ParsedFunctionDeclarationStatement(const HashedString& identifier, vector<TypedVariableIdentifier *> parameters,
ParsedBlockStatement *block,
unsigned int start, unsigned int length)
: ParsedStatement(start, length), _identifier(identifier), _parameters(std::move(parameters)),
@@ -164,7 +165,7 @@ namespace Porygon::Parser {
const HashedString _identifier;
const ParsedExpression *_expression;
public:
ParsedAssignmentStatement(bool local, const HashedString identifier, ParsedExpression *expression,
ParsedAssignmentStatement(bool local, const HashedString& identifier, ParsedExpression *expression,
unsigned int start, unsigned int length)
: ParsedStatement(start, length), _local(local), _identifier(identifier), _expression(expression) {
}
@@ -288,7 +289,7 @@ namespace Porygon::Parser {
const ParsedExpression *_step;
const ParsedStatement *_block;
public:
ParsedNumericalForStatement(const HashedString identifier, const ParsedExpression *start,
ParsedNumericalForStatement(const HashedString& identifier, const ParsedExpression *start,
const ParsedExpression *end, const ParsedExpression *step, const ParsedStatement *block,
unsigned int startPos, unsigned int length)
: ParsedStatement(startPos, length), _identifier(identifier), _start(start), _end(end), _step(step), _block(block) {
@@ -326,5 +327,43 @@ namespace Porygon::Parser {
}
};
class ParsedGenericForStatement : public ParsedStatement{
const HashedString _keyIdentifier;
const HashedString _valueIdentifier;
const ParsedExpression* _iteratorExpression;
const ParsedStatement* _block;
public:
ParsedGenericForStatement(const HashedString& keyIdentifier, const HashedString& valueIdentifier,
const ParsedExpression *iteratorExpression, const ParsedStatement *block,
unsigned int start, unsigned int length)
: ParsedStatement(start, length), _keyIdentifier(keyIdentifier), _valueIdentifier(valueIdentifier),
_iteratorExpression(iteratorExpression), _block(block) {}
~ParsedGenericForStatement() final{
delete _iteratorExpression;
delete _block;
}
const ParsedStatementKind GetKind() const final {
return ParsedStatementKind::GenericFor;
}
const HashedString GetKeyIdentifier() const{
return _keyIdentifier;
}
const HashedString GetValueIdentifier() const{
return _valueIdentifier;
}
const ParsedExpression* GetIteratorExpression() const{
return _iteratorExpression;
}
const ParsedStatement* GetBlock() const{
return _block;
}
};
}
#endif //PORYGONLANG_PARSEDSTATEMENT_HPP

View File

@@ -267,7 +267,47 @@ namespace Porygon::Parser {
}
ParsedStatement *Parser::ParseGenericForStatement(const IToken *current) {
return nullptr;
auto keyIdentifier = ((IdentifierToken*) current)->GetValue();
IdentifierToken* valueIdentifierToken = nullptr;
bool hasErrors = false;
auto next = this -> Next();
if (next -> GetKind() == TokenKind::CommaToken){
next = this -> Next();
if (next->GetKind() != TokenKind::Identifier){
hasErrors = true;
this->ScriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::UnexpectedToken, next->GetStartPosition(),
next->GetLength());
} else{
valueIdentifierToken = (IdentifierToken*) next;
next = this -> Next();
}
}
if (next->GetKind() != TokenKind::InKeyword && !hasErrors){
hasErrors = true;
this->ScriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::UnexpectedToken, next->GetStartPosition(),
next->GetLength());
}
auto expression = this -> ParseExpression(this -> Next());
next = this -> Next();
if (next -> GetKind() != TokenKind::DoKeyword && !hasErrors){
hasErrors = true;
this->ScriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::UnexpectedToken, next->GetStartPosition(),
next->GetLength());
}
auto block = this -> ParseBlock({TokenKind ::EndKeyword});
auto startPos = current->GetStartPosition();
if (hasErrors){
return new ParsedBadStatement(startPos, block -> GetEndPosition() - startPos);
} else{
auto valueIdentifier = HashedString::CreateLookup(0);
if (valueIdentifierToken != nullptr){
return new ParsedGenericForStatement(keyIdentifier, valueIdentifierToken -> GetValue(), expression, block,
startPos, block -> GetEndPosition() - startPos);
} else{
return new ParsedGenericForStatement(keyIdentifier, HashedString::CreateLookup(0), expression, block,
startPos, block -> GetEndPosition() - startPos);
}
}
}
/////////////////