Implements indexing with period identifier style (`foo.bar`)
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2019-06-17 15:45:33 +02:00
parent d06b04cae9
commit d91caa7f32
17 changed files with 207 additions and 32 deletions

View File

@@ -25,6 +25,7 @@ enum class ParsedExpressionKind{
Parenthesized,
FunctionCall,
Indexer,
PeriodIndexer,
NumericalTable,
Table,
};
@@ -287,6 +288,34 @@ public:
}
};
class PeriodIndexExpression : public ParsedExpression{
const ParsedExpression* _indexerExpression;
const HashedString _index;
public:
PeriodIndexExpression(ParsedExpression* indexer, HashedString index, unsigned int start, unsigned int length)
:ParsedExpression(start, length),
_indexerExpression(indexer), _index(index)
{
}
~PeriodIndexExpression() final{
delete _indexerExpression;
}
const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::PeriodIndexer;
}
const ParsedExpression* GetIndexer() const{
return _indexerExpression;
}
const HashedString& GetIndex() const{
return _index;
}
};
class ParsedNumericalTableExpression : public ParsedExpression{
vector<const ParsedExpression*> _expressions;
public:

View File

@@ -46,7 +46,9 @@ ParsedStatement* Parser::ParseStatement(const IToken* current){
return ParseVariableAssignment(current);
}
auto expression = this -> ParseExpression(current);
if (expression->GetKind() == ParsedExpressionKind::Indexer && this -> Peek()->GetKind() == TokenKind::AssignmentToken){
auto expKind = expression -> GetKind();
if ((expKind == ParsedExpressionKind::Indexer || expKind == ParsedExpressionKind::PeriodIndexer)
&& this -> Peek()->GetKind() == TokenKind::AssignmentToken){
return this -> ParseIndexAssignment(expression);
}
return new ParsedExpressionStatement(expression);
@@ -206,7 +208,7 @@ ParsedExpression* Parser::ParseExpression(const IToken* current){
} else if (peekKind == TokenKind::OpenSquareBracket){
expression = this->ParseIndexExpression(expression);
} else {
//TODO: index period expression
expression = this -> ParsePeriodIndexExpression(expression);
}
if (this -> _position >= this->_tokens.size())
break;
@@ -379,6 +381,18 @@ ParsedExpression* Parser::ParseIndexExpression(ParsedExpression* indexingExpress
return new IndexExpression(indexingExpression, indexExpression, start, closeBracket->GetEndPosition() - start);
}
ParsedExpression* Parser::ParsePeriodIndexExpression(ParsedExpression* indexingExpression){
this->Next(); // consume '.' token
auto identifier = this -> Next();
if (identifier->GetKind() != TokenKind::Identifier){
this->ScriptData->Diagnostics->LogError(DiagnosticCode::UnexpectedToken, identifier->GetStartPosition(), identifier->GetLength());
return new BadExpression(indexingExpression->GetStartPosition(), identifier->GetEndPosition() - indexingExpression->GetStartPosition());
}
auto start = indexingExpression->GetStartPosition();
return new PeriodIndexExpression(indexingExpression, ((IdentifierToken*)identifier)->GetValue(), start, identifier->GetEndPosition() - start);
}
ParsedExpression* Parser::ParseTableExpression(const IToken* current){
if (this -> Peek() -> GetKind() == TokenKind::CloseCurlyBracket){
this -> Next();

View File

@@ -41,6 +41,7 @@ class Parser {
ParsedExpression* ParseFunctionCallExpression(ParsedExpression* functionExpression);
ParsedExpression *ParseIndexExpression(ParsedExpression *indexingExpression);
ParsedExpression *ParsePeriodIndexExpression(ParsedExpression *indexingExpression);
ParsedExpression *ParseTableExpression(const IToken *current);
public:
ParsedScriptStatement* Parse();
@@ -49,6 +50,7 @@ public:
_position = 0;
ScriptData = scriptData;
}
};