Skip to content

Commit

Permalink
Scripting|libcore: Keep track of script source line numbers
Browse files Browse the repository at this point in the history
Each Statement knows its source line number.
  • Loading branch information
skyjake committed Dec 15, 2018
1 parent 40e0295 commit 4354ca7
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 23 deletions.
2 changes: 2 additions & 0 deletions doomsday/sdk/libcore/include/de/data/dictionaryvalue.h
Expand Up @@ -87,6 +87,8 @@ class DENG2_PUBLIC DictionaryValue : public Value

void remove(Elements::iterator const &pos);

const Value *find(const Value &key) const;

enum ContentSelection { Keys, Values };

/**
Expand Down
3 changes: 2 additions & 1 deletion doomsday/sdk/libcore/include/de/scriptsys/compound.h
Expand Up @@ -57,8 +57,9 @@ class Compound : public ISerializable
*
* @param statement Statement object. The Compound takes ownership
* of the object.
* @param startLine Source line on which the statement begins.
*/
void add(Statement *statement);
void add(Statement *statement, duint startLine);

/**
* Deletes all statements.
Expand Down
6 changes: 6 additions & 0 deletions doomsday/sdk/libcore/include/de/scriptsys/statement.h
Expand Up @@ -48,6 +48,10 @@ class Statement : public ISerializable

void setNext(Statement *statement) { _next = statement; }

void setLineNumber(duint line);

duint lineNumber() const;

public:
/**
* Constructs a statement by deserializing one from a reader.
Expand Down Expand Up @@ -79,6 +83,8 @@ class Statement : public ISerializable
/// Pointer to the statement that follows this one, or NULL if
/// this is the final statement.
Statement *_next;

duint _lineNumber;
};

} // namespace de
Expand Down
10 changes: 10 additions & 0 deletions doomsday/sdk/libcore/src/data/dictionaryvalue.cpp
Expand Up @@ -92,6 +92,16 @@ void DictionaryValue::remove(Elements::iterator const &pos)
_elements.erase(pos);
}

const Value *DictionaryValue::find(const Value &key) const
{
auto i = _elements.find(ValueRef(&key));
if (i != _elements.end())
{
return i->second;
}
return nullptr;
}

ArrayValue *DictionaryValue::contentsAsArray(ContentSelection selection) const
{
QScopedPointer<ArrayValue> array(new ArrayValue);
Expand Down
5 changes: 3 additions & 2 deletions doomsday/sdk/libcore/src/scriptsys/compound.cpp
Expand Up @@ -50,8 +50,9 @@ Statement const *Compound::firstStatement() const
return *_statements.begin();
}

void Compound::add(Statement *statement)
void Compound::add(Statement *statement, duint lineNumber)
{
statement->setLineNumber(lineNumber);
if (_statements.size() > 0)
{
_statements.back()->setNext(statement);
Expand All @@ -75,6 +76,6 @@ void Compound::operator << (Reader &from)
clear();
while (count--)
{
add(Statement::constructFrom(from));
add(Statement::constructFrom(from), 0 /* unknown line number */);
}
}
40 changes: 21 additions & 19 deletions doomsday/sdk/libcore/src/scriptsys/parser.cpp
Expand Up @@ -109,26 +109,27 @@ void Parser::parseStatement(Compound &compound)
DENG2_ASSERT(!_statementRange.isEmpty());

Token const &firstToken = _statementRange.firstToken();
const auto firstTokenLine = firstToken.line();

// Statements with a compound: if, for, while, def.
if (firstToken.equals(ScriptLex::IF))
{
compound.add(parseIfStatement());
compound.add(parseIfStatement(), firstTokenLine);
return;
}
else if (firstToken.equals(ScriptLex::WHILE))
{
compound.add(parseWhileStatement());
compound.add(parseWhileStatement(), firstTokenLine);
return;
}
else if (firstToken.equals(ScriptLex::FOR))
{
compound.add(parseForStatement());
compound.add(parseForStatement(), firstTokenLine);
return;
}
else if (firstToken.equals(ScriptLex::DEF))
{
compound.add(parseFunctionStatement());
compound.add(parseFunctionStatement(), firstTokenLine);
return;
}
else if (firstToken.equals(ScriptLex::TRY))
Expand All @@ -140,23 +141,23 @@ void Parser::parseStatement(Compound &compound)
// Statements without a compound (must advance to next statement manually).
if (firstToken.equals(ScriptLex::IMPORT))
{
compound.add(parseImportStatement());
compound.add(parseImportStatement(), firstTokenLine);
}
else if (firstToken.equals(ScriptLex::RECORD))
{
compound.add(parseDeclarationStatement());
compound.add(parseDeclarationStatement(), firstTokenLine);
}
else if (firstToken.equals(ScriptLex::DEL))
{
compound.add(parseDeleteStatement());
compound.add(parseDeleteStatement(), firstTokenLine);
}
else if (firstToken.equals(ScriptLex::PASS))
{
compound.add(new FlowStatement(FlowStatement::PASS));
compound.add(new FlowStatement(FlowStatement::PASS), firstTokenLine);
}
else if (firstToken.equals(ScriptLex::CONTINUE))
{
compound.add(new FlowStatement(FlowStatement::CONTINUE));
compound.add(new FlowStatement(FlowStatement::CONTINUE), firstTokenLine);
}
else if (firstToken.equals(ScriptLex::BREAK))
{
Expand All @@ -167,7 +168,7 @@ void Parser::parseStatement(Compound &compound)
{
breakCount = parseExpression(_statementRange.startingFrom(1));
}
compound.add(new FlowStatement(FlowStatement::BREAK, breakCount));
compound.add(new FlowStatement(FlowStatement::BREAK, breakCount), firstTokenLine);
}
else if (firstToken.equals(ScriptLex::RETURN) || firstToken.equals(ScriptLex::THROW))
{
Expand All @@ -178,25 +179,25 @@ void Parser::parseStatement(Compound &compound)
}
compound.add(new FlowStatement(
firstToken.equals(ScriptLex::RETURN)? FlowStatement::RETURN : FlowStatement::THROW,
argValue));
argValue), firstTokenLine);
}
else if (firstToken.equals(ScriptLex::PRINT))
{
compound.add(parsePrintStatement());
compound.add(parsePrintStatement(), firstTokenLine);
}
else if (_statementRange.hasBracketless(ScriptLex::ASSIGN) ||
_statementRange.hasBracketless(ScriptLex::SCOPE_ASSIGN) ||
_statementRange.hasBracketless(ScriptLex::WEAK_ASSIGN))
_statementRange.hasBracketless(ScriptLex::SCOPE_ASSIGN) ||
_statementRange.hasBracketless(ScriptLex::WEAK_ASSIGN))
{
compound.add(parseAssignStatement());
compound.add(parseAssignStatement(), firstTokenLine);
}
else if (firstToken.equals(ScriptLex::EXPORT))
{
compound.add(parseExportStatement());
compound.add(parseExportStatement(), firstTokenLine);
}
else
{
compound.add(parseExpressionStatement());
compound.add(parseExpressionStatement(), firstTokenLine);
}

// We've fully parsed the current set of tokens, get the next statement.
Expand Down Expand Up @@ -417,9 +418,10 @@ void Parser::parseTryCatchSequence(Compound &compound)
// "try" cond-compound catch-compound [catch-compound]*
// catch-compound: "catch" name-expr ["," ref-name-expr] cond-compound

const duint lineNumber = _statementRange.firstToken().line();
std::unique_ptr<TryStatement> tryStat(new TryStatement);
parseConditionalCompound(tryStat->compound(), StayAtClosingStatement);
compound.add(tryStat.release());
compound.add(tryStat.release(), lineNumber);

// One catch is required.
if (!_statementRange.firstToken().equals(ScriptLex::CATCH))
Expand Down Expand Up @@ -459,7 +461,7 @@ void Parser::parseTryCatchSequence(Compound &compound)
finalCatch = catchStat.get();

// Add it to the compound.
compound.add(catchStat.release());
compound.add(catchStat.release(), lineNumber);
}
if (finalCatch)
{
Expand Down
12 changes: 11 additions & 1 deletion doomsday/sdk/libcore/src/scriptsys/statement.cpp
Expand Up @@ -34,7 +34,7 @@

using namespace de;

Statement::Statement() : _next(nullptr)
Statement::Statement() : _next(nullptr), _lineNumber(0)
{}

Statement::~Statement()
Expand Down Expand Up @@ -108,3 +108,13 @@ Statement *Statement::constructFrom(Reader &reader)
reader >> *result.get();
return result.release();
}

void Statement::setLineNumber(duint line)
{
_lineNumber = line;
}

duint Statement::lineNumber() const
{
return _lineNumber;
}

0 comments on commit 4354ca7

Please sign in to comment.