Fixes empty script returning segmentation fault

This commit is contained in:
Deukhoofd 2019-09-14 10:35:32 +02:00
parent 45d3bc690b
commit b462c1b873
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
3 changed files with 69 additions and 50 deletions

View File

@ -37,17 +37,17 @@ namespace Porygon::Parser {
virtual ~ParsedStatement() = default; virtual ~ParsedStatement() = default;
virtual const ParsedStatementKind GetKind() const = 0; [[nodiscard]] virtual ParsedStatementKind GetKind() const = 0;
const unsigned int GetStartPosition() const { [[nodiscard]] unsigned int GetStartPosition() const {
return _start; return _start;
} }
const unsigned int GetLength() const { [[nodiscard]] unsigned int GetLength() const {
return _length; return _length;
} }
const unsigned int GetEndPosition() const { [[nodiscard]] unsigned int GetEndPosition() const {
return _start + _length - 1; return _start + _length - 1;
} }
}; };
@ -56,7 +56,7 @@ namespace Porygon::Parser {
public: public:
ParsedBadStatement(unsigned int start, unsigned int length) : ParsedStatement(start, length) {}; ParsedBadStatement(unsigned int start, unsigned int length) : ParsedStatement(start, length) {};
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Bad; return ParsedStatementKind::Bad;
} }
}; };
@ -65,7 +65,7 @@ namespace Porygon::Parser {
public: public:
ParsedBreakStatement(unsigned int start, unsigned int length) : ParsedStatement(start, length) {}; ParsedBreakStatement(unsigned int start, unsigned int length) : ParsedStatement(start, length) {};
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Break; return ParsedStatementKind::Break;
} }
}; };
@ -73,10 +73,9 @@ namespace Porygon::Parser {
class ParsedBlockStatement : public ParsedStatement { class ParsedBlockStatement : public ParsedStatement {
const std::vector<const ParsedStatement *> _statements; const std::vector<const ParsedStatement *> _statements;
public: public:
explicit ParsedBlockStatement(const std::vector<const ParsedStatement *>& statements) explicit ParsedBlockStatement(std::vector<const ParsedStatement *> statements, size_t start, size_t length)
: ParsedStatement(statements.front()->GetStartPosition(), : ParsedStatement(start, length),
statements.back()->GetEndPosition() - statements.front()->GetStartPosition()), _statements(std::move(statements)) {}
_statements(statements) {}
ParsedBlockStatement(std::vector<const ParsedStatement *> statements, unsigned int start) : ParsedStatement( ParsedBlockStatement(std::vector<const ParsedStatement *> statements, unsigned int start) : ParsedStatement(
start, 0), _statements(std::move(statements)) { start, 0), _statements(std::move(statements)) {
@ -89,21 +88,21 @@ namespace Porygon::Parser {
} }
} }
inline const ParsedStatementKind GetKind() const override { [[nodiscard]] inline ParsedStatementKind GetKind() const override {
return ParsedStatementKind::Block; return ParsedStatementKind::Block;
} }
inline const std::vector<const ParsedStatement *> *GetStatements() const { [[nodiscard]] inline const std::vector<const ParsedStatement *> *GetStatements() const {
return &_statements; return &_statements;
} }
}; };
class ParsedScriptStatement : public ParsedBlockStatement { class ParsedScriptStatement : public ParsedBlockStatement {
public: public:
explicit ParsedScriptStatement(vector<const ParsedStatement *> statements) : ParsedBlockStatement( explicit ParsedScriptStatement(const vector<const ParsedStatement *>& statements, size_t start, size_t length) : ParsedBlockStatement(
move(statements)) {} statements, start, length) {}
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Script; return ParsedStatementKind::Script;
} }
}; };
@ -124,11 +123,11 @@ namespace Porygon::Parser {
_expression = nullptr; _expression = nullptr;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Expression; return ParsedStatementKind::Expression;
} }
inline const ParsedExpression *GetExpression() const { [[nodiscard]] inline const ParsedExpression *GetExpression() const {
return _expression; return _expression;
} }
}; };
@ -151,19 +150,19 @@ namespace Porygon::Parser {
delete _block; delete _block;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::FunctionDeclaration; return ParsedStatementKind::FunctionDeclaration;
} }
inline const HashedString GetIdentifier() const { [[nodiscard]] inline HashedString GetIdentifier() const {
return _identifier; return _identifier;
} }
inline const vector<TypedVariableIdentifier *> *GetParameters() const { [[nodiscard]] inline const vector<TypedVariableIdentifier *> *GetParameters() const {
return &_parameters; return &_parameters;
} }
inline const ParsedBlockStatement *GetBlock() const { [[nodiscard]] inline const ParsedBlockStatement *GetBlock() const {
return _block; return _block;
} }
}; };
@ -182,19 +181,19 @@ namespace Porygon::Parser {
delete _expression; delete _expression;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Assignment; return ParsedStatementKind::Assignment;
} }
inline const bool IsLocal() const { [[nodiscard]] inline bool IsLocal() const {
return _local; return _local;
} }
inline const HashedString GetIdentifier() const { [[nodiscard]] inline HashedString GetIdentifier() const {
return _identifier; return _identifier;
} }
inline const ParsedExpression *GetExpression() const { [[nodiscard]] inline const ParsedExpression *GetExpression() const {
return _expression; return _expression;
} }
}; };
@ -214,15 +213,15 @@ namespace Porygon::Parser {
delete _valueExpression; delete _valueExpression;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::IndexAssignment; return ParsedStatementKind::IndexAssignment;
} }
inline const ParsedExpression *GetIndexExpression() const { [[nodiscard]] inline const ParsedExpression *GetIndexExpression() const {
return _indexExpression; return _indexExpression;
} }
inline const ParsedExpression *GetValueExpression() const { [[nodiscard]] inline const ParsedExpression *GetValueExpression() const {
return _valueExpression; return _valueExpression;
} }
}; };
@ -239,11 +238,11 @@ namespace Porygon::Parser {
delete _expression; delete _expression;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Return; return ParsedStatementKind::Return;
} }
inline const ParsedExpression *GetExpression() const { [[nodiscard]] inline const ParsedExpression *GetExpression() const {
return _expression; return _expression;
} }
}; };
@ -273,19 +272,19 @@ namespace Porygon::Parser {
delete _elseStatement; delete _elseStatement;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Conditional; return ParsedStatementKind::Conditional;
} }
inline const ParsedExpression *GetCondition() const { [[nodiscard]] inline const ParsedExpression *GetCondition() const {
return _condition; return _condition;
} }
inline const ParsedStatement *GetBlock() const { [[nodiscard]] inline const ParsedStatement *GetBlock() const {
return _block; return _block;
} }
inline const ParsedStatement *GetElseStatement() const { [[nodiscard]] inline const ParsedStatement *GetElseStatement() const {
return _elseStatement; return _elseStatement;
} }
}; };
@ -310,27 +309,27 @@ namespace Porygon::Parser {
delete _block; delete _block;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::NumericalFor; return ParsedStatementKind::NumericalFor;
} }
inline const HashedString GetIdentifier() const{ [[nodiscard]] inline HashedString GetIdentifier() const{
return _identifier; return _identifier;
} }
inline const ParsedExpression *GetStart() const{ [[nodiscard]] inline const ParsedExpression *GetStart() const{
return _start; return _start;
} }
inline const ParsedExpression *GetEnd() const{ [[nodiscard]] inline const ParsedExpression *GetEnd() const{
return _end; return _end;
} }
inline const ParsedExpression *GetStep() const{ [[nodiscard]] inline const ParsedExpression *GetStep() const{
return _step; return _step;
} }
inline const ParsedStatement *GetBlock() const{ [[nodiscard]] inline const ParsedStatement *GetBlock() const{
return _block; return _block;
} }
}; };
@ -352,23 +351,23 @@ namespace Porygon::Parser {
delete _block; delete _block;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::GenericFor; return ParsedStatementKind::GenericFor;
} }
inline const HashedString GetKeyIdentifier() const{ [[nodiscard]] inline HashedString GetKeyIdentifier() const{
return _keyIdentifier; return _keyIdentifier;
} }
inline const HashedString GetValueIdentifier() const{ [[nodiscard]] inline HashedString GetValueIdentifier() const{
return _valueIdentifier; return _valueIdentifier;
} }
inline const ParsedExpression* GetIteratorExpression() const{ [[nodiscard]] inline const ParsedExpression* GetIteratorExpression() const{
return _iteratorExpression; return _iteratorExpression;
} }
inline const ParsedStatement* GetBlock() const{ [[nodiscard]] inline const ParsedStatement* GetBlock() const{
return _block; return _block;
} }
}; };
@ -386,15 +385,15 @@ namespace Porygon::Parser {
delete _block; delete _block;
} }
inline const ParsedStatementKind GetKind() const final { [[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::While; return ParsedStatementKind::While;
} }
inline const ParsedExpression* GetCondition(){ [[nodiscard]] inline const ParsedExpression* GetCondition(){
return _condition; return _condition;
} }
inline const ParsedStatement* GetBlock(){ [[nodiscard]] inline const ParsedStatement* GetBlock(){
return _block; return _block;
} }
}; };

View File

@ -16,7 +16,11 @@ namespace Porygon::Parser {
} }
statements.push_back(this->ParseStatement(next)); statements.push_back(this->ParseStatement(next));
} }
return new ParsedScriptStatement(statements); auto end = 0;
if (statements.size() > 0){
end = statements.back()->GetEndPosition();
}
return new ParsedScriptStatement(statements, 0, end);
} }
inline const Token *Parser::Peek() { inline const Token *Parser::Peek() {
@ -123,7 +127,11 @@ namespace Porygon::Parser {
if (statements.empty()) { if (statements.empty()) {
return new ParsedBlockStatement(statements, start); return new ParsedBlockStatement(statements, start);
} }
return new ParsedBlockStatement(statements); auto end = 0;
if (statements.size() > 0){
end = statements.back()->GetEndPosition();
}
return new ParsedBlockStatement(statements, start, end - start);
} }
ParsedStatement *Parser::ParseFunctionDeclaration(const Token *current) { ParsedStatement *Parser::ParseFunctionDeclaration(const Token *current) {

View File

@ -5,6 +5,18 @@
#include "../../src/Parser/Parser.hpp" #include "../../src/Parser/Parser.hpp"
using namespace Porygon::Parser; using namespace Porygon::Parser;
TEST_CASE( "Parse empty script", "[parser]" ) {
vector<const Token*> v {
new SimpleToken(TokenKind::EndOfFile,0,0),
};
Parser parser = Parser(v, nullptr);
auto parsedScript = parser.Parse();
for (auto t : v){
delete t;
}
delete parsedScript;
}
TEST_CASE( "Parse single true keyword", "[parser]" ) { TEST_CASE( "Parse single true keyword", "[parser]" ) {
vector<const Token*> v {new SimpleToken(TokenKind::TrueKeyword,0,0), new SimpleToken(TokenKind::EndOfFile,0,0)}; vector<const Token*> v {new SimpleToken(TokenKind::TrueKeyword,0,0), new SimpleToken(TokenKind::EndOfFile,0,0)};
Parser parser = Parser(v, nullptr); Parser parser = Parser(v, nullptr);