Fixes empty script returning segmentation fault
This commit is contained in:
parent
45d3bc690b
commit
b462c1b873
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue