[Scummvm-git-logs] scummvm master -> f600534707504b3a67f8e61298a507dea2fc292f
scemino
noreply at scummvm.org
Fri May 17 12:18:01 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f600534707 DIRECTOR: Start to add code decompiler (WIP)
Commit: f600534707504b3a67f8e61298a507dea2fc292f
https://github.com/scummvm/scummvm/commit/f600534707504b3a67f8e61298a507dea2fc292f
Author: scemino (scemino74 at gmail.com)
Date: 2024-05-17T14:17:41+02:00
Commit Message:
DIRECTOR: Start to add code decompiler (WIP)
Changed paths:
engines/director/cast.cpp
engines/director/debugtools.cpp
engines/director/lingo/lingodec/ast.cpp
engines/director/lingo/lingodec/ast.h
engines/director/lingo/lingodec/handler.cpp
engines/director/lingo/lingodec/handler.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 7f7394e295c..39a8ed9fe09 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -1146,7 +1146,7 @@ public:
Common::SeekableReadStreamEndian *r;
r = _cast->_castArchive->getResource(MKTAG('L', 's', 'c', 'r'), id);
- _scripts[id] = new LingoDec::Script(_cast->_version);
+ _scripts[id] = new LingoDec::Script(g_director->getVersion());
_scripts[id]->read(*r);
delete r;
@@ -1264,7 +1264,6 @@ void Cast::loadLingoContext(Common::SeekableReadStreamEndian &stream) {
error("Cast::loadLingoContext: unsupported Director version (%d)", _version);
}
-#if 0
// Rewind stream
stream.seek(0);
_chunkResolver = new ChunkResolver(this);
@@ -1274,10 +1273,8 @@ void Cast::loadLingoContext(Common::SeekableReadStreamEndian &stream) {
_lingodec->parseScripts();
for (auto it = _lingodec->scripts.begin(); it != _lingodec->scripts.end(); ++it) {
- warning("%s", it->second->scriptText("\n", false).c_str());
+ warning("[%d/%d] %s", it->second->castID, it->first, it->second->scriptText("\n", false).c_str());
}
-
-#endif
}
void Cast::loadScriptV2(Common::SeekableReadStreamEndian &stream, uint16 id) {
diff --git a/engines/director/debugtools.cpp b/engines/director/debugtools.cpp
index 5d64c7806c8..e1472eaedfb 100644
--- a/engines/director/debugtools.cpp
+++ b/engines/director/debugtools.cpp
@@ -31,6 +31,12 @@
#include "director/director.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingodec/ast.h"
+#include "director/lingo/lingodec/codewriter.h"
+#include "director/lingo/lingodec/context.h"
+#include "director/lingo/lingodec/handler.h"
+#include "director/lingo/lingodec/resolver.h"
+#include "director/lingo/lingodec/script.h"
#include "director/cast.h"
#include "director/castmember/bitmap.h"
#include "director/castmember/castmember.h"
@@ -54,7 +60,7 @@ typedef struct ImGuiImage {
} ImGuiImage;
typedef struct ImGuiScriptCode {
- uint pc;
+ uint32 pc;
Common::String code;
} ImGuiScriptCode;
@@ -75,6 +81,167 @@ typedef struct ImGuiScript {
}
} ImGuiScript;
+class ImGuiNodeVisitor : public LingoDec::NodeVisitor {
+public:
+ explicit ImGuiNodeVisitor(ImGuiScript &script) : _script(script) {}
+
+ virtual void visit(const LingoDec::BlockNode &node) override {
+ _indent++;
+ for (const auto &child : node.children) {
+ child->accept(*this);
+ }
+ _indent--;
+ }
+
+ virtual void visit(const LingoDec::HandlerNode &node) override {
+ if (node.handler->isGenericEvent) {
+ node.block->accept(*this);
+ return;
+ }
+
+ LingoDec::Script *script = node.handler->script;
+ bool isMethod = script->isFactory();
+ {
+ LingoDec::CodeWriter code("\n");
+ if (isMethod) {
+ code.write("method ");
+ } else {
+ code.write("on ");
+ }
+ code.write(node.handler->name);
+
+ if (node.handler->argumentNames.size() > 0) {
+ code.write(" ");
+ for (size_t i = 0; i < node.handler->argumentNames.size(); i++) {
+ if (i > 0)
+ code.write(", ");
+ code.write(node.handler->argumentNames[i]);
+ }
+ }
+ write(node._startOffset, code.str());
+ }
+
+ {
+ LingoDec::CodeWriter code("\n");
+ if (isMethod && node.handler->script->propertyNames.size() > 0 && node.handler == &node.handler->script->handlers[0]) {
+ code.write("instance ");
+ for (size_t i = 0; i < node.handler->script->propertyNames.size(); i++) {
+ if (i > 0)
+ code.write(", ");
+ code.write(node.handler->script->propertyNames[i]);
+ }
+ write(node._startOffset, code.str());
+ }
+ }
+
+ {
+ if (node.handler->globalNames.size() > 0) {
+ LingoDec::CodeWriter code("\n");
+ code.write("global ");
+ for (size_t i = 0; i < node.handler->globalNames.size(); i++) {
+ if (i > 0)
+ code.write(", ");
+ code.write(node.handler->globalNames[i]);
+ }
+ write(node._startOffset, code.str());
+ }
+ }
+
+ node.block->accept(*this);
+
+ {
+ LingoDec::CodeWriter code("\n");
+ if (!isMethod) {
+ code.writeLine("end");
+ }
+ _script.code.push_back({node.block->_endOffset, code.str()});
+ }
+ }
+
+ virtual void visit(const LingoDec::RepeatWhileStmtNode &node) override {
+ LingoDec::CodeWriter code("\n");
+ code.write("repeat while ");
+ node.condition->writeScriptText(code, _dot, false);
+ write(node._startOffset, code.str());
+
+ node.block->accept(*this);
+
+ write(node._endOffset, "end repeat");
+ }
+
+ virtual void visit(const LingoDec::RepeatWithInStmtNode &node) override {
+ LingoDec::CodeWriter code("\n");
+ code.write("repeat with ");
+ code.write(node.varName);
+ code.write(" in ");
+ node.list->writeScriptText(code, _dot, false);
+ write(node._startOffset, code.str());
+ node.block->accept(*this);
+ write(node._endOffset, "end repeat");
+ }
+
+ virtual void visit(const LingoDec::RepeatWithToStmtNode &node) override {
+ LingoDec::CodeWriter code("\n");
+ code.write("repeat with ");
+ code.write(node.varName);
+ code.write(" = ");
+ node.start->writeScriptText(code, _dot, false);
+ if (node.up) {
+ code.write(" to ");
+ } else {
+ code.write(" down to ");
+ }
+ node.end->writeScriptText(code, _dot, false);
+ write(node._startOffset, code.str());
+ node.block->accept(*this);
+ write(node._endOffset, "end repeat");
+ }
+
+ virtual void visit(const LingoDec::IfStmtNode &node) override {
+ {
+ LingoDec::CodeWriter code("\n");
+ code.write("if ");
+ node.condition->writeScriptText(code, _dot, false);
+ code.write(" then");
+ write(node._startOffset, code.str());
+ }
+ node.block1->accept(*this);
+ if (node.hasElse) {
+ write(node.block2->_startOffset, "else");
+ node.block2->accept(*this);
+ }
+ write(node._endOffset, "end if");
+ }
+
+ virtual void visit(const LingoDec::TellStmtNode &node) override {
+ LingoDec::CodeWriter code("\n");
+ code.write("tell ");
+ node.window->writeScriptText(code, _dot, false);
+ write(node._startOffset, code.str());
+ node.block->accept(*this);
+ write(node._endOffset, "end tell");
+ }
+
+ virtual void defaultVisit(const LingoDec::Node &node) override {
+ LingoDec::CodeWriter code("\n");
+ node.writeScriptText(code, _dot, false);
+ write(node._startOffset, code.str());
+ }
+
+ void write(uint32 offset, const Common::String &code) {
+ Common::String s;
+ for (int i = 0; i < _indent; i++) {
+ s += " ";
+ }
+ _script.code.push_back({offset, s + code});
+ }
+
+private:
+ ImGuiScript &_script;
+ bool _dot = false;
+ int _indent = 0;
+};
+
typedef struct ImGuiState {
struct {
Common::HashMap<Graphics::Surface *, ImGuiImage> _textures;
@@ -1025,7 +1192,7 @@ static void displayScripts() {
ImGui::End();
}
-static void getScriptCode(ImGuiScript& script, Symbol &sym) {
+static void getScriptCode(ImGuiScript &script, Symbol &sym) {
uint pc = 0;
while (pc < sym.u.defn->size()) {
script.code.push_back({pc, g_lingo->decodeInstruction(sym.u.defn, pc, &pc)});
@@ -1090,11 +1257,10 @@ static void showFuncList() {
ImGui::Text("-");
ImGui::TableNextColumn();
ImGui::Text("%s", scriptType.c_str());
-
}
}
- for (auto cast : *movie->getCasts()) {
+ for (auto &cast : *movie->getCasts()) {
for (int i = 0; i <= kMaxScriptType; i++) {
if (cast._value->_lingoArchive->scriptContexts[i].empty())
continue;
@@ -1120,7 +1286,12 @@ static void showFuncList() {
script.type = (ScriptType)i;
script.handlerId = functionHandler._key;
script.handlerName = getHandlerName(functionHandler._value);
- getScriptCode(script, functionHandler._value);
+ uint32 scriptId = movie->getCastMemberInfo(memberID)->scriptId;
+ const LingoDec::Script *s = cast._value->_lingodec->scripts[scriptId];
+ ImGuiNodeVisitor visitor(script);
+ for (auto &h : s->handlers) {
+ h.ast.root->accept(visitor);
+ }
setScriptToDisplay(script);
}
ImGui::TableNextColumn();
@@ -1129,7 +1300,6 @@ static void showFuncList() {
ImGui::Text("%d", cast._key);
ImGui::TableNextColumn();
ImGui::Text("%s", scriptType.c_str());
-
}
}
}
diff --git a/engines/director/lingo/lingodec/ast.cpp b/engines/director/lingo/lingodec/ast.cpp
index 49aa410ac6f..044255ab28e 100644
--- a/engines/director/lingo/lingodec/ast.cpp
+++ b/engines/director/lingo/lingodec/ast.cpp
@@ -683,8 +683,8 @@ void CaseStmtNode::writeScriptText(CodeWriter &code, bool dot, bool sum) const {
}
}
-void CaseStmtNode::addOtherwise() {
- otherwise = Common::SharedPtr<OtherwiseNode>(new OtherwiseNode());
+void CaseStmtNode::addOtherwise(uint32 offset) {
+ otherwise = Common::SharedPtr<OtherwiseNode>(new OtherwiseNode(offset));
otherwise->parent = this;
otherwise->block->endPos = endPos;
}
@@ -1166,4 +1166,52 @@ void NewObjNode::writeScriptText(CodeWriter &code, bool dot, bool sum) const {
code.write(")");
}
+void ErrorNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void CommentNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void LiteralNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void IfStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void NewObjNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void EndCaseNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void HandlerNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ObjCallNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void PutStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void TheExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void BinaryOpNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void CaseStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ExitStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void TellStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void WhenStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void CaseLabelNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ChunkExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void InverseOpNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ObjCallV4Node::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void OtherwiseNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void MemberExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ObjPropExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void PlayCmdStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ThePropExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void MenuPropExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void SoundCmdStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void SoundPropExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void AssignmentStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ExitRepeatStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void NextRepeatStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ObjBracketExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void SpritePropExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ChunkDeleteStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ChunkHiliteStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void RepeatWhileStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void MenuItemPropExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void ObjPropIndexExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void RepeatWithInStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void RepeatWithToStmtNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void SpriteWithinExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void LastStringChunkExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void SpriteIntersectsExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void StringChunkCountExprNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void VarNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void CallNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void BlockNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+void NotOpNode::accept(NodeVisitor &visitor) const { visitor.visit(*this); }
+
} // namespace LingoDec
diff --git a/engines/director/lingo/lingodec/ast.h b/engines/director/lingo/lingodec/ast.h
index caeb9bf6e1f..3ec33b7e22f 100644
--- a/engines/director/lingo/lingodec/ast.h
+++ b/engines/director/lingo/lingodec/ast.h
@@ -55,6 +55,8 @@ struct Datum {
void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
};
+class NodeVisitor;
+
/* Node */
struct Node {
@@ -64,10 +66,13 @@ struct Node {
bool isLabel;
bool isLoop;
Node *parent;
+ uint32 _startOffset;
+ uint32 _endOffset;
- Node(NodeType t) : type(t), isExpression(false), isStatement(false), isLabel(false), isLoop(false), parent(nullptr) {}
+ Node(NodeType t, uint32 offset) : type(t), isExpression(false), isStatement(false), isLabel(false), isLoop(false), parent(nullptr), _startOffset(offset), _endOffset(offset) {}
virtual ~Node() {}
virtual void writeScriptText(CodeWriter&, bool, bool) const {}
+ virtual void accept(NodeVisitor& visitor) const = 0;
virtual Common::SharedPtr<Datum> getValue();
Node *ancestorStatement();
LoopNode *ancestorLoop();
@@ -77,7 +82,7 @@ struct Node {
/* ExprNode */
struct ExprNode : Node {
- ExprNode(NodeType t) : Node(t) {
+ ExprNode(NodeType t, uint32 offset) : Node(t, offset) {
isExpression = true;
}
};
@@ -85,7 +90,7 @@ struct ExprNode : Node {
/* StmtNode */
struct StmtNode : Node {
- StmtNode(NodeType t) : Node(t) {
+ StmtNode(NodeType t, uint32 offset) : Node(t, offset) {
isStatement = true;
}
};
@@ -93,7 +98,7 @@ struct StmtNode : Node {
/* LabelNode */
struct LabelNode : Node {
- LabelNode(NodeType t) : Node(t) {
+ LabelNode(NodeType t, uint32 offset) : Node(t, offset) {
isLabel = true;
}
};
@@ -103,7 +108,7 @@ struct LabelNode : Node {
struct LoopNode : StmtNode {
uint32 startIndex;
- LoopNode(NodeType t, uint32 startIndex_) : StmtNode(t), startIndex(startIndex_) {
+ LoopNode(NodeType t, uint32 startIndex_, uint32 offset) : StmtNode(t, offset), startIndex(startIndex_) {
isLoop = true;
}
};
@@ -111,9 +116,10 @@ struct LoopNode : StmtNode {
/* ErrorNode */
struct ErrorNode : ExprNode {
- ErrorNode() : ExprNode(kErrorNode) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ explicit ErrorNode(uint32 offset) : ExprNode(kErrorNode, offset) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* CommentNode */
@@ -121,8 +127,9 @@ struct ErrorNode : ExprNode {
struct CommentNode : Node {
Common::String text;
- CommentNode(Common::String t) : Node(kCommentNode), text(t) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ CommentNode(uint32 offset, Common::String t) : Node(kCommentNode, offset), text(t) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* LiteralNode */
@@ -130,12 +137,13 @@ struct CommentNode : Node {
struct LiteralNode : ExprNode {
Common::SharedPtr<Datum> value;
- LiteralNode(Common::SharedPtr<Datum> d) : ExprNode(kLiteralNode) {
+ LiteralNode(uint32 offset, Common::SharedPtr<Datum> d) : ExprNode(kLiteralNode, offset) {
value = Common::move(d);
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual Common::SharedPtr<Datum> getValue();
- virtual bool hasSpaces(bool dot);
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual Common::SharedPtr<Datum> getValue() override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* BlockNode */
@@ -147,9 +155,10 @@ struct BlockNode : Node {
uint32 endPos;
CaseLabelNode *currentCaseLabel;
- BlockNode() : Node(kBlockNode), endPos(-1), currentCaseLabel(nullptr) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ explicit BlockNode(uint32 offset) : Node(kBlockNode, offset), endPos(-1), currentCaseLabel(nullptr) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
void addChild(Common::SharedPtr<Node> child);
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* HandlerNode */
@@ -158,19 +167,21 @@ struct HandlerNode : Node {
Handler *handler;
Common::SharedPtr<BlockNode> block;
- HandlerNode(Handler *h)
- : Node(kHandlerNode), handler(h) {
- block = Common::SharedPtr<BlockNode>(new BlockNode());
+ HandlerNode(uint32 offset, Handler *h)
+ : Node(kHandlerNode, offset), handler(h) {
+ block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
block->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ExitStmtNode */
struct ExitStmtNode : StmtNode {
- ExitStmtNode() : StmtNode(kExitStmtNode) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ explicit ExitStmtNode(uint32 offset) : StmtNode(kExitStmtNode, offset) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* InverseOpNode */
@@ -178,11 +189,12 @@ struct ExitStmtNode : StmtNode {
struct InverseOpNode : ExprNode {
Common::SharedPtr<Node> operand;
- InverseOpNode(Common::SharedPtr<Node> o) : ExprNode(kInverseOpNode) {
+ InverseOpNode(uint32 offset, Common::SharedPtr<Node> o) : ExprNode(kInverseOpNode, offset) {
operand = Common::move(o);
operand->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* NotOpNode */
@@ -190,11 +202,12 @@ struct InverseOpNode : ExprNode {
struct NotOpNode : ExprNode {
Common::SharedPtr<Node> operand;
- NotOpNode(Common::SharedPtr<Node> o) : ExprNode(kNotOpNode) {
+ NotOpNode(uint32 offset, Common::SharedPtr<Node> o) : ExprNode(kNotOpNode, offset) {
operand = Common::move(o);
operand->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* BinaryOpNode */
@@ -204,15 +217,16 @@ struct BinaryOpNode : ExprNode {
Common::SharedPtr<Node> left;
Common::SharedPtr<Node> right;
- BinaryOpNode(OpCode op, Common::SharedPtr<Node> a, Common::SharedPtr<Node> b)
- : ExprNode(kBinaryOpNode), opcode(op) {
+ BinaryOpNode(uint32 offset, OpCode op, Common::SharedPtr<Node> a, Common::SharedPtr<Node> b)
+ : ExprNode(kBinaryOpNode, offset), opcode(op) {
left = Common::move(a);
left->parent = this;
right = Common::move(b);
right->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
virtual unsigned int getPrecedence() const;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ChunkExprNode */
@@ -223,8 +237,8 @@ struct ChunkExprNode : ExprNode {
Common::SharedPtr<Node> last;
Common::SharedPtr<Node> string;
- ChunkExprNode(ChunkExprType t, Common::SharedPtr<Node> a, Common::SharedPtr<Node> b, Common::SharedPtr<Node> s)
- : ExprNode(kChunkExprNode), type(t) {
+ ChunkExprNode(uint32 offset, ChunkExprType t, Common::SharedPtr<Node> a, Common::SharedPtr<Node> b, Common::SharedPtr<Node> s)
+ : ExprNode(kChunkExprNode, offset), type(t) {
first = Common::move(a);
first->parent = this;
last = Common::move(b);
@@ -232,7 +246,8 @@ struct ChunkExprNode : ExprNode {
string = Common::move(s);
string->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ChunkHiliteStmtNode */
@@ -240,11 +255,12 @@ struct ChunkExprNode : ExprNode {
struct ChunkHiliteStmtNode : StmtNode {
Common::SharedPtr<Node> chunk;
- ChunkHiliteStmtNode(Common::SharedPtr<Node> c) : StmtNode(kChunkHiliteStmtNode) {
+ ChunkHiliteStmtNode(uint32 offset, Common::SharedPtr<Node> c) : StmtNode(kChunkHiliteStmtNode, offset) {
chunk = Common::move(c);
chunk->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ChunkDeleteStmtNode */
@@ -252,11 +268,12 @@ struct ChunkHiliteStmtNode : StmtNode {
struct ChunkDeleteStmtNode : StmtNode {
Common::SharedPtr<Node> chunk;
- ChunkDeleteStmtNode(Common::SharedPtr<Node> c) : StmtNode(kChunkDeleteStmtNode) {
+ ChunkDeleteStmtNode(uint32 offset, Common::SharedPtr<Node> c) : StmtNode(kChunkDeleteStmtNode, offset) {
chunk = Common::move(c);
chunk->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* SpriteIntersectsExprNode */
@@ -265,14 +282,15 @@ struct SpriteIntersectsExprNode : ExprNode {
Common::SharedPtr<Node> firstSprite;
Common::SharedPtr<Node> secondSprite;
- SpriteIntersectsExprNode(Common::SharedPtr<Node> a, Common::SharedPtr<Node> b)
- : ExprNode(kSpriteIntersectsExprNode) {
+ SpriteIntersectsExprNode(uint32 offset, Common::SharedPtr<Node> a, Common::SharedPtr<Node> b)
+ : ExprNode(kSpriteIntersectsExprNode, offset) {
firstSprite = Common::move(a);
firstSprite->parent = this;
secondSprite = Common::move(b);
secondSprite->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* SpriteWithinExprNode */
@@ -281,14 +299,15 @@ struct SpriteWithinExprNode : ExprNode {
Common::SharedPtr<Node> firstSprite;
Common::SharedPtr<Node> secondSprite;
- SpriteWithinExprNode(Common::SharedPtr<Node> a, Common::SharedPtr<Node> b)
- : ExprNode(kSpriteWithinExprNode) {
+ SpriteWithinExprNode(uint32 offset, Common::SharedPtr<Node> a, Common::SharedPtr<Node> b)
+ : ExprNode(kSpriteWithinExprNode, offset) {
firstSprite = Common::move(a);
firstSprite->parent = this;
secondSprite = Common::move(b);
secondSprite->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* MemberExprNode */
@@ -298,8 +317,8 @@ struct MemberExprNode : ExprNode {
Common::SharedPtr<Node> memberID;
Common::SharedPtr<Node> castID;
- MemberExprNode(Common::String type_, Common::SharedPtr<Node> memberID_, Common::SharedPtr<Node> castID_)
- : ExprNode(kMemberExprNode), type(type_) {
+ MemberExprNode(uint32 offset, Common::String type_, Common::SharedPtr<Node> memberID_, Common::SharedPtr<Node> castID_)
+ : ExprNode(kMemberExprNode, offset), type(type_) {
this->memberID = Common::move(memberID_);
this->memberID->parent = this;
if (castID_) {
@@ -307,8 +326,9 @@ struct MemberExprNode : ExprNode {
this->castID->parent = this;
}
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* VarNode */
@@ -316,9 +336,10 @@ struct MemberExprNode : ExprNode {
struct VarNode : ExprNode {
Common::String varName;
- VarNode(Common::String v) : ExprNode(kVarNode), varName(v) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ VarNode(uint32 offset, Common::String v) : ExprNode(kVarNode, offset), varName(v) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* AssignmentStmtNode */
@@ -328,15 +349,16 @@ struct AssignmentStmtNode : StmtNode {
Common::SharedPtr<Node> value;
bool forceVerbose;
- AssignmentStmtNode(Common::SharedPtr<Node> var, Common::SharedPtr<Node> val, bool forceVerbose_ = false)
- : StmtNode(kAssignmentStmtNode), forceVerbose(forceVerbose_) {
+ AssignmentStmtNode(uint32 offset, Common::SharedPtr<Node> var, Common::SharedPtr<Node> val, bool forceVerbose_ = false)
+ : StmtNode(kAssignmentStmtNode, offset), forceVerbose(forceVerbose_) {
variable = Common::move(var);
variable->parent = this;
value = Common::move(val);
value->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* IfStmtNode */
@@ -347,15 +369,16 @@ struct IfStmtNode : StmtNode {
Common::SharedPtr<BlockNode> block1;
Common::SharedPtr<BlockNode> block2;
- IfStmtNode(Common::SharedPtr<Node> c) : StmtNode(kIfStmtNode), hasElse(false) {
+ IfStmtNode(uint32 offset, Common::SharedPtr<Node> c) : StmtNode(kIfStmtNode, offset), hasElse(false) {
condition = Common::move(c);
condition->parent = this;
- block1 = Common::SharedPtr<BlockNode>(new BlockNode());
+ block1 = Common::SharedPtr<BlockNode>(new BlockNode(offset));
block1->parent = this;
- block2 = Common::SharedPtr<BlockNode>(new BlockNode());
+ block2 = Common::SharedPtr<BlockNode>(new BlockNode(offset));
block2->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* RepeatWhileStmtNode */
@@ -364,14 +387,15 @@ struct RepeatWhileStmtNode : LoopNode {
Common::SharedPtr<Node> condition;
Common::SharedPtr<BlockNode> block;
- RepeatWhileStmtNode(uint32 startIndex_, Common::SharedPtr<Node> c)
- : LoopNode(kRepeatWhileStmtNode, startIndex_) {
+ RepeatWhileStmtNode(uint32 startIndex_, Common::SharedPtr<Node> c, uint32 offset)
+ : LoopNode(kRepeatWhileStmtNode, startIndex_, offset) {
condition = Common::move(c);
condition->parent = this;
- block = Common::SharedPtr<BlockNode>(new BlockNode());
+ block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
block->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* RepeatWithInStmtNode */
@@ -381,15 +405,16 @@ struct RepeatWithInStmtNode : LoopNode {
Common::SharedPtr<Node> list;
Common::SharedPtr<BlockNode> block;
- RepeatWithInStmtNode(uint32 startIndex_, Common::String v, Common::SharedPtr<Node> l)
- : LoopNode(kRepeatWithInStmtNode, startIndex_) {
+ RepeatWithInStmtNode(uint32 startIndex_, Common::String v, Common::SharedPtr<Node> l, uint32 offset)
+ : LoopNode(kRepeatWithInStmtNode, startIndex_, offset) {
varName = v;
list = Common::move(l);
list->parent = this;
- block = Common::SharedPtr<BlockNode>(new BlockNode());
+ block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
block->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* RepeatWithToStmtNode */
@@ -401,17 +426,18 @@ struct RepeatWithToStmtNode : LoopNode {
Common::SharedPtr<Node> end;
Common::SharedPtr<BlockNode> block;
- RepeatWithToStmtNode(uint32 startIndex_, Common::String v, Common::SharedPtr<Node> s, bool up_, Common::SharedPtr<Node> e)
- : LoopNode(kRepeatWithToStmtNode, startIndex_), up(up_) {
+ RepeatWithToStmtNode(uint32 startIndex_, Common::String v, Common::SharedPtr<Node> s, bool up, Common::SharedPtr<Node> e, uint32 offset)
+ : LoopNode(kRepeatWithToStmtNode, startIndex_, offset), up(up) {
varName = v;
start = Common::move(s);
start->parent = this;
end = Common::move(e);
end->parent = this;
- block = Common::SharedPtr<BlockNode>(new BlockNode());
+ block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
block->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* CaseLabelNode */
@@ -425,11 +451,12 @@ struct CaseLabelNode : LabelNode {
Common::SharedPtr<CaseLabelNode> nextLabel;
Common::SharedPtr<BlockNode> block;
- CaseLabelNode(Common::SharedPtr<Node> v, CaseExpect e) : LabelNode(kCaseLabelNode), expect(e) {
+ CaseLabelNode(uint32 offset, Common::SharedPtr<Node> v, CaseExpect e) : LabelNode(kCaseLabelNode, offset), expect(e) {
value = Common::move(v);
value->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* OtherwiseNode */
@@ -437,18 +464,20 @@ struct CaseLabelNode : LabelNode {
struct OtherwiseNode : LabelNode {
Common::SharedPtr<BlockNode> block;
- OtherwiseNode() : LabelNode(kOtherwiseNode) {
- block = Common::SharedPtr<BlockNode>(new BlockNode());
+ explicit OtherwiseNode(uint32 offset) : LabelNode(kOtherwiseNode, offset) {
+ block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
block->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* EndCaseNode */
struct EndCaseNode : LabelNode {
- EndCaseNode() : LabelNode(kEndCaseNode) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ explicit EndCaseNode(uint32 offset) : LabelNode(kEndCaseNode, offset) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* CaseStmtNode */
@@ -462,12 +491,13 @@ struct CaseStmtNode : StmtNode {
int32 endPos = -1;
int32 potentialOtherwisePos = -1;
- CaseStmtNode(Common::SharedPtr<Node> v) : StmtNode(kCaseStmtNode) {
+ CaseStmtNode(uint32 offset, Common::SharedPtr<Node> v) : StmtNode(kCaseStmtNode, offset) {
value = Common::move(v);
value->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- void addOtherwise();
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ void addOtherwise(uint32 offset);
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* TellStmtNode */
@@ -476,13 +506,14 @@ struct TellStmtNode : StmtNode {
Common::SharedPtr<Node> window;
Common::SharedPtr<BlockNode> block;
- TellStmtNode(Common::SharedPtr<Node> w) : StmtNode(kTellStmtNode) {
+ TellStmtNode(uint32 offset, Common::SharedPtr<Node> w) : StmtNode(kTellStmtNode, offset) {
window = Common::move(w);
window->parent = this;
- block = Common::SharedPtr<BlockNode>(new BlockNode());
+ block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
block->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* SoundCmdStmtNode */
@@ -491,12 +522,13 @@ struct SoundCmdStmtNode : StmtNode {
Common::String cmd;
Common::SharedPtr<Node> argList;
- SoundCmdStmtNode(Common::String c, Common::SharedPtr<Node> a) : StmtNode(kSoundCmdStmtNode) {
+ SoundCmdStmtNode(uint32 offset, Common::String c, Common::SharedPtr<Node> a) : StmtNode(kSoundCmdStmtNode, offset) {
cmd = c;
argList = Common::move(a);
argList->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* PlayCmdStmtNode */
@@ -504,11 +536,12 @@ struct SoundCmdStmtNode : StmtNode {
struct PlayCmdStmtNode : StmtNode {
Common::SharedPtr<Node> argList;
- PlayCmdStmtNode(Common::SharedPtr<Node> a) : StmtNode(kPlayCmdStmtNode) {
+ PlayCmdStmtNode(uint32 offset, Common::SharedPtr<Node> a) : StmtNode(kPlayCmdStmtNode, offset) {
argList = Common::move(a);
argList->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* CallNode */
@@ -517,7 +550,7 @@ struct CallNode : Node {
Common::String name;
Common::SharedPtr<Node> argList;
- CallNode(Common::String n, Common::SharedPtr<Node> a) : Node(kCallNode) {
+ CallNode(uint32 offset, Common::String n, Common::SharedPtr<Node> a) : Node(kCallNode, offset) {
name = n;
argList = Common::move(a);
argList->parent = this;
@@ -528,8 +561,9 @@ struct CallNode : Node {
}
bool noParens() const;
bool isMemberExpr() const;
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ObjCallNode */
@@ -538,7 +572,7 @@ struct ObjCallNode : Node {
Common::String name;
Common::SharedPtr<Node> argList;
- ObjCallNode(Common::String n, Common::SharedPtr<Node> a) : Node(kObjCallNode) {
+ ObjCallNode(uint32 offset, Common::String n, Common::SharedPtr<Node> a) : Node(kObjCallNode, offset) {
name = n;
argList = Common::move(a);
argList->parent = this;
@@ -547,8 +581,9 @@ struct ObjCallNode : Node {
else
isExpression = true;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ObjCallV4Node */
@@ -557,7 +592,7 @@ struct ObjCallV4Node : Node {
Common::SharedPtr<Node> obj;
Common::SharedPtr<Node> argList;
- ObjCallV4Node(Common::SharedPtr<Node> o, Common::SharedPtr<Node> a) : Node(kObjCallV4Node) {
+ ObjCallV4Node(uint32 offset, Common::SharedPtr<Node> o, Common::SharedPtr<Node> a) : Node(kObjCallV4Node, offset) {
obj = o;
argList = Common::move(a);
argList->parent = this;
@@ -566,8 +601,9 @@ struct ObjCallV4Node : Node {
else
isExpression = true;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* TheExprNode */
@@ -575,8 +611,9 @@ struct ObjCallV4Node : Node {
struct TheExprNode : ExprNode {
Common::String prop;
- TheExprNode(Common::String p) : ExprNode(kTheExprNode), prop(p) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ TheExprNode(uint32 offset, Common::String p) : ExprNode(kTheExprNode, offset), prop(p) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* LastStringChunkExprNode */
@@ -585,12 +622,13 @@ struct LastStringChunkExprNode : ExprNode {
ChunkExprType type;
Common::SharedPtr<Node> obj;
- LastStringChunkExprNode(ChunkExprType t, Common::SharedPtr<Node> o)
- : ExprNode(kLastStringChunkExprNode), type(t) {
+ LastStringChunkExprNode(uint32 offset, ChunkExprType t, Common::SharedPtr<Node> o)
+ : ExprNode(kLastStringChunkExprNode, offset), type(t) {
obj = Common::move(o);
obj->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* StringChunkCountExprNode */
@@ -599,12 +637,13 @@ struct StringChunkCountExprNode : ExprNode {
ChunkExprType type;
Common::SharedPtr<Node> obj;
- StringChunkCountExprNode(ChunkExprType t, Common::SharedPtr<Node> o)
- : ExprNode(kStringChunkCountExprNode), type(t) {
+ StringChunkCountExprNode(uint32 offset, ChunkExprType t, Common::SharedPtr<Node> o)
+ : ExprNode(kStringChunkCountExprNode, offset), type(t) {
obj = Common::move(o);
obj->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* MenuPropExprNode */
@@ -613,12 +652,13 @@ struct MenuPropExprNode : ExprNode {
Common::SharedPtr<Node> menuID;
unsigned int prop;
- MenuPropExprNode(Common::SharedPtr<Node> m, unsigned int p)
- : ExprNode(kMenuPropExprNode), prop(p) {
+ MenuPropExprNode(uint32 offset, Common::SharedPtr<Node> m, unsigned int p)
+ : ExprNode(kMenuPropExprNode, offset), prop(p) {
menuID = Common::move(m);
menuID->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* MenuItemPropExprNode */
@@ -628,14 +668,15 @@ struct MenuItemPropExprNode : ExprNode {
Common::SharedPtr<Node> itemID;
unsigned int prop;
- MenuItemPropExprNode(Common::SharedPtr<Node> m, Common::SharedPtr<Node> i, unsigned int p)
- : ExprNode(kMenuItemPropExprNode), prop(p) {
+ MenuItemPropExprNode(uint32 offset, Common::SharedPtr<Node> m, Common::SharedPtr<Node> i, unsigned int p)
+ : ExprNode(kMenuItemPropExprNode, offset), prop(p) {
menuID = Common::move(m);
menuID->parent = this;
itemID = Common::move(i);
itemID->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* SoundPropExprNode */
@@ -644,12 +685,13 @@ struct SoundPropExprNode : ExprNode {
Common::SharedPtr<Node> soundID;
unsigned int prop;
- SoundPropExprNode(Common::SharedPtr<Node> s, unsigned int p)
- : ExprNode(kSoundPropExprNode), prop(p) {
+ SoundPropExprNode(uint32 offset, Common::SharedPtr<Node> s, unsigned int p)
+ : ExprNode(kSoundPropExprNode, offset), prop(p) {
soundID = Common::move(s);
soundID->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* SpritePropExprNode */
@@ -658,12 +700,13 @@ struct SpritePropExprNode : ExprNode {
Common::SharedPtr<Node> spriteID;
unsigned int prop;
- SpritePropExprNode(Common::SharedPtr<Node> s, unsigned int p)
- : ExprNode(kSpritePropExprNode), prop(p) {
+ SpritePropExprNode(uint32 offset, Common::SharedPtr<Node> s, unsigned int p)
+ : ExprNode(kSpritePropExprNode, offset), prop(p) {
spriteID = Common::move(s);
spriteID->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ThePropExprNode */
@@ -672,12 +715,13 @@ struct ThePropExprNode : ExprNode {
Common::SharedPtr<Node> obj;
Common::String prop;
- ThePropExprNode(Common::SharedPtr<Node> o, Common::String p)
- : ExprNode(kThePropExprNode), prop(p) {
+ ThePropExprNode(uint32 offset, Common::SharedPtr<Node> o, Common::String p)
+ : ExprNode(kThePropExprNode, offset), prop(p) {
obj = Common::move(o);
obj->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ObjPropExprNode */
@@ -686,13 +730,14 @@ struct ObjPropExprNode : ExprNode {
Common::SharedPtr<Node> obj;
Common::String prop;
- ObjPropExprNode(Common::SharedPtr<Node> o, Common::String p)
- : ExprNode(kObjPropExprNode), prop(p) {
+ ObjPropExprNode(uint32 offset, Common::SharedPtr<Node> o, Common::String p)
+ : ExprNode(kObjPropExprNode, offset), prop(p) {
obj = Common::move(o);
obj->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ObjBracketExprNode */
@@ -701,15 +746,16 @@ struct ObjBracketExprNode : ExprNode {
Common::SharedPtr<Node> obj;
Common::SharedPtr<Node> prop;
- ObjBracketExprNode(Common::SharedPtr<Node> o, Common::SharedPtr<Node> p)
- : ExprNode(kObjBracketExprNode) {
+ ObjBracketExprNode(uint32 offset, Common::SharedPtr<Node> o, Common::SharedPtr<Node> p)
+ : ExprNode(kObjBracketExprNode, offset) {
obj = Common::move(o);
obj->parent = this;
prop = Common::move(p);
prop->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ObjPropIndexExprNode */
@@ -720,8 +766,8 @@ struct ObjPropIndexExprNode : ExprNode {
Common::SharedPtr<Node> index;
Common::SharedPtr<Node> index2;
- ObjPropIndexExprNode(Common::SharedPtr<Node> o, Common::String p, Common::SharedPtr<Node> i, Common::SharedPtr<Node> i2)
- : ExprNode(kObjPropIndexExprNode), prop(p) {
+ ObjPropIndexExprNode(uint32 offset, Common::SharedPtr<Node> o, Common::String p, Common::SharedPtr<Node> i, Common::SharedPtr<Node> i2)
+ : ExprNode(kObjPropIndexExprNode, offset), prop(p) {
obj = Common::move(o);
obj->parent = this;
index = Common::move(i);
@@ -731,22 +777,25 @@ struct ObjPropIndexExprNode : ExprNode {
index2->parent = this;
}
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
- virtual bool hasSpaces(bool dot);
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual bool hasSpaces(bool dot) override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* ExitRepeatStmtNode */
struct ExitRepeatStmtNode : StmtNode {
- ExitRepeatStmtNode() : StmtNode(kExitRepeatStmtNode) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ explicit ExitRepeatStmtNode(uint32 offset) : StmtNode(kExitRepeatStmtNode, offset) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* NextRepeatStmtNode */
struct NextRepeatStmtNode : StmtNode {
- NextRepeatStmtNode() : StmtNode(kNextRepeatStmtNode) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ explicit NextRepeatStmtNode(uint32 offset) : StmtNode(kNextRepeatStmtNode, offset) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* PutStmtNode */
@@ -756,14 +805,15 @@ struct PutStmtNode : StmtNode {
Common::SharedPtr<Node> variable;
Common::SharedPtr<Node> value;
- PutStmtNode(PutType t, Common::SharedPtr<Node> var, Common::SharedPtr<Node> val)
- : StmtNode(kPutStmtNode), type(t) {
+ PutStmtNode(uint32 offset, PutType t, Common::SharedPtr<Node> var, Common::SharedPtr<Node> val)
+ : StmtNode(kPutStmtNode, offset), type(t) {
variable = Common::move(var);
variable->parent = this;
value = Common::move(val);
value->parent = this;
}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* WhenStmtNode */
@@ -772,9 +822,10 @@ struct WhenStmtNode : StmtNode {
int event;
Common::String script;
- WhenStmtNode(int e, Common::String s)
- : StmtNode(kWhenStmtNode), event(e), script(s) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ WhenStmtNode(uint32 offset, int e, Common::String s)
+ : StmtNode(kWhenStmtNode, offset), event(e), script(s) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
};
/* NewObjNode */
@@ -783,8 +834,63 @@ struct NewObjNode : ExprNode {
Common::String objType;
Common::SharedPtr<Node> objArgs;
- NewObjNode(Common::String o, Common::SharedPtr<Node> args) : ExprNode(kNewObjNode), objType(o), objArgs(args) {}
- virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const;
+ NewObjNode(uint32 offset, Common::String o, Common::SharedPtr<Node> args) : ExprNode(kNewObjNode, offset), objType(o), objArgs(args) {}
+ virtual void writeScriptText(CodeWriter &code, bool dot, bool sum) const override;
+ virtual void accept(NodeVisitor &visitor) const override;
+};
+
+class NodeVisitor {
+public:
+ virtual ~NodeVisitor() {}
+ virtual void visit(const HandlerNode &node) { defaultVisit(node); }
+ virtual void visit(const ErrorNode &node) { defaultVisit(node); }
+ virtual void visit(const CommentNode &node) { defaultVisit(node); }
+ virtual void visit(const NewObjNode &node) { defaultVisit(node); }
+ virtual void visit(const LiteralNode &node) { defaultVisit(node); }
+ virtual void visit(const IfStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const EndCaseNode &node) { defaultVisit(node); }
+ virtual void visit(const ObjCallNode &node) { defaultVisit(node); }
+ virtual void visit(const PutStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const TheExprNode &node) { defaultVisit(node); }
+ virtual void visit(const BinaryOpNode &node) { defaultVisit(node); }
+ virtual void visit(const CaseStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const ExitStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const TellStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const WhenStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const CaseLabelNode &node) { defaultVisit(node); }
+ virtual void visit(const ChunkExprNode &node) { defaultVisit(node); }
+ virtual void visit(const InverseOpNode &node) { defaultVisit(node); }
+ virtual void visit(const ObjCallV4Node &node) { defaultVisit(node); }
+ virtual void visit(const OtherwiseNode &node) { defaultVisit(node); }
+ virtual void visit(const MemberExprNode &node) { defaultVisit(node); }
+ virtual void visit(const ObjPropExprNode &node) { defaultVisit(node); }
+ virtual void visit(const PlayCmdStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const ThePropExprNode &node) { defaultVisit(node); }
+ virtual void visit(const MenuPropExprNode &node) { defaultVisit(node); }
+ virtual void visit(const SoundCmdStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const SoundPropExprNode &node) { defaultVisit(node); }
+ virtual void visit(const AssignmentStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const ExitRepeatStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const NextRepeatStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const ObjBracketExprNode &node) { defaultVisit(node); }
+ virtual void visit(const SpritePropExprNode &node) { defaultVisit(node); }
+ virtual void visit(const ChunkDeleteStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const ChunkHiliteStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const RepeatWhileStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const MenuItemPropExprNode &node) { defaultVisit(node); }
+ virtual void visit(const ObjPropIndexExprNode &node) { defaultVisit(node); }
+ virtual void visit(const RepeatWithInStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const RepeatWithToStmtNode &node) { defaultVisit(node); }
+ virtual void visit(const SpriteWithinExprNode &node) { defaultVisit(node); }
+ virtual void visit(const LastStringChunkExprNode &node) { defaultVisit(node); }
+ virtual void visit(const SpriteIntersectsExprNode &node) { defaultVisit(node); }
+ virtual void visit(const StringChunkCountExprNode &node) { defaultVisit(node); }
+ virtual void visit(const VarNode &node) { defaultVisit(node); }
+ virtual void visit(const CallNode &node) { defaultVisit(node); }
+ virtual void visit(const BlockNode &node) { defaultVisit(node); }
+ virtual void visit(const NotOpNode &node) { defaultVisit(node); }
+
+ virtual void defaultVisit(const Node &) {}
};
/* AST */
@@ -793,8 +899,8 @@ struct AST {
Common::SharedPtr<HandlerNode> root;
BlockNode *currentBlock;
- AST(Handler *handler){
- root = Common::SharedPtr<HandlerNode>(new HandlerNode(handler));
+ AST(uint32 offset, Handler *handler){
+ root = Common::SharedPtr<HandlerNode>(new HandlerNode(offset, handler));
currentBlock = root->block.get();
}
diff --git a/engines/director/lingo/lingodec/handler.cpp b/engines/director/lingo/lingodec/handler.cpp
index fba36cb4aa5..c8eb821c88d 100644
--- a/engines/director/lingo/lingodec/handler.cpp
+++ b/engines/director/lingo/lingodec/handler.cpp
@@ -128,7 +128,7 @@ Common::String Handler::getLocalName(int id) const {
Common::SharedPtr<Node> Handler::pop() {
if (stack.empty())
- return Common::SharedPtr<Node>(new ErrorNode());
+ return Common::SharedPtr<Node>(new ErrorNode(0));
auto res = stack.back();
stack.pop_back();
@@ -158,21 +158,21 @@ Common::SharedPtr<Node> Handler::readVar(int varType) {
{
Common::String name_ = getArgumentName(id->getValue()->i / variableMultiplier());
auto ref = Common::SharedPtr<Datum>(new Datum(kDatumVarRef, name_));
- return Common::SharedPtr<Node>(new LiteralNode(Common::move(ref)));
+ return Common::SharedPtr<Node>(new LiteralNode(id->_startOffset, Common::move(ref)));
}
case 0x5: // local
{
Common::String name_ = getLocalName(id->getValue()->i / variableMultiplier());
auto ref = Common::SharedPtr<Datum>(new Datum(kDatumVarRef, name_));
- return Common::SharedPtr<Node>(new LiteralNode(Common::move(ref)));
+ return Common::SharedPtr<Node>(new LiteralNode(id->_startOffset, Common::move(ref)));
}
case 0x6: // field
- return Common::SharedPtr<Node>(new MemberExprNode("field", Common::move(id), Common::move(castID)));
+ return Common::SharedPtr<Node>(new MemberExprNode(id->_startOffset, "field", Common::move(id), Common::move(castID)));
default:
warning("%s", Common::String::format("findVar: unhandled var type %d", varType).c_str());
break;
}
- return Common::SharedPtr<Node>(new ErrorNode());
+ return Common::SharedPtr<Node>(new ErrorNode(id->_startOffset));
}
Common::String Handler::getVarNameFromSet(const Bytecode &bytecode) {
@@ -198,64 +198,64 @@ Common::String Handler::getVarNameFromSet(const Bytecode &bytecode) {
return varName;
}
-Common::SharedPtr<Node> Handler::readV4Property(int propertyType, int propertyID) {
+Common::SharedPtr<Node> Handler::readV4Property(uint32 offset, int propertyType, int propertyID) {
switch (propertyType) {
case 0x00:
{
if (propertyID <= 0x0b) { // movie property
auto propName = StandardNames::getName(StandardNames::moviePropertyNames, propertyID);
- return Common::SharedPtr<Node>(new TheExprNode(propName));
+ return Common::SharedPtr<Node>(new TheExprNode(offset, propName));
} else { // last chunk
auto string = pop();
auto chunkType = static_cast<ChunkExprType>(propertyID - 0x0b);
- return Common::SharedPtr<Node>(new LastStringChunkExprNode(chunkType, Common::move(string)));
+ return Common::SharedPtr<Node>(new LastStringChunkExprNode(offset, chunkType, Common::move(string)));
}
}
break;
case 0x01: // number of chunks
{
auto string = pop();
- return Common::SharedPtr<Node>(new StringChunkCountExprNode(static_cast<ChunkExprType>(propertyID), Common::move(string)));
+ return Common::SharedPtr<Node>(new StringChunkCountExprNode(offset, static_cast<ChunkExprType>(propertyID), Common::move(string)));
}
break;
case 0x02: // menu property
{
auto menuID = pop();
- return Common::SharedPtr<Node>(new MenuPropExprNode(Common::move(menuID), propertyID));
+ return Common::SharedPtr<Node>(new MenuPropExprNode(offset, Common::move(menuID), propertyID));
}
break;
case 0x03: // menu item property
{
auto menuID = pop();
auto itemID = pop();
- return Common::SharedPtr<Node>(new MenuItemPropExprNode(Common::move(menuID), Common::move(itemID), propertyID));
+ return Common::SharedPtr<Node>(new MenuItemPropExprNode(offset, Common::move(menuID), Common::move(itemID), propertyID));
}
break;
case 0x04: // sound property
{
auto soundID = pop();
- return Common::SharedPtr<Node>(new SoundPropExprNode(Common::move(soundID), propertyID));
+ return Common::SharedPtr<Node>(new SoundPropExprNode(offset, Common::move(soundID), propertyID));
}
break;
case 0x05: // resource property - unused?
- return Common::SharedPtr<Node>(new CommentNode("ERROR: Resource property"));
+ return Common::SharedPtr<Node>(new CommentNode(offset, "ERROR: Resource property"));
case 0x06: // sprite property
{
auto spriteID = pop();
- return Common::SharedPtr<Node>(new SpritePropExprNode(Common::move(spriteID), propertyID));
+ return Common::SharedPtr<Node>(new SpritePropExprNode(offset, Common::move(spriteID), propertyID));
}
break;
case 0x07: // animation property
- return Common::SharedPtr<Node>(new TheExprNode(StandardNames::getName(StandardNames::animationPropertyNames, propertyID)));
+ return Common::SharedPtr<Node>(new TheExprNode(offset, StandardNames::getName(StandardNames::animationPropertyNames, propertyID)));
case 0x08: // animation 2 property
if (propertyID == 0x02 && script->version >= 500) { // the number of castMembers supports castLib selection from Director 5.0
auto castLib = pop();
if (!(castLib->type == kLiteralNode && castLib->getValue()->type == kDatumInt && castLib->getValue()->toInt() == 0)) {
- auto castLibNode = Common::SharedPtr<Node>(new MemberExprNode("castLib", castLib, nullptr));
- return Common::SharedPtr<Node>(new ThePropExprNode(castLibNode, StandardNames::getName(StandardNames::animation2PropertyNames, propertyID)));
+ auto castLibNode = Common::SharedPtr<Node>(new MemberExprNode(offset, "castLib", castLib, nullptr));
+ return Common::SharedPtr<Node>(new ThePropExprNode(offset, castLibNode, StandardNames::getName(StandardNames::animation2PropertyNames, propertyID)));
}
}
- return Common::SharedPtr<Node>(new TheExprNode(StandardNames::getName(StandardNames::animation2PropertyNames, propertyID)));
+ return Common::SharedPtr<Node>(new TheExprNode(offset, StandardNames::getName(StandardNames::animation2PropertyNames, propertyID)));
case 0x09: // generic cast member
case 0x0a: // chunk of cast member
case 0x0b: // field
@@ -284,23 +284,23 @@ Common::SharedPtr<Node> Handler::readV4Property(int propertyType, int propertyID
} else {
prefix = (script->version >= 500) ? "member" : "cast";
}
- auto member = Common::SharedPtr<Node>(new MemberExprNode(prefix, Common::move(memberID), Common::move(castID)));
+ auto member = Common::SharedPtr<Node>(new MemberExprNode(offset, prefix, Common::move(memberID), Common::move(castID)));
Common::SharedPtr<Node> entity;
if (propertyType == 0x0a || propertyType == 0x0c || propertyType == 0x15) {
- entity = readChunkRef(Common::move(member));
+ entity = readChunkRef(offset, Common::move(member));
} else {
entity = member;
}
- return Common::SharedPtr<Node>(new ThePropExprNode(Common::move(entity), propName));
+ return Common::SharedPtr<Node>(new ThePropExprNode(offset, Common::move(entity), propName));
}
break;
default:
break;
}
- return Common::SharedPtr<Node>(new CommentNode(Common::String::format("ERROR: Unknown property type %d", propertyType)));
+ return Common::SharedPtr<Node>(new CommentNode(offset, Common::String::format("ERROR: Unknown property type %d", propertyType)));
}
-Common::SharedPtr<Node> Handler::readChunkRef(Common::SharedPtr<Node> string) {
+Common::SharedPtr<Node> Handler::readChunkRef(uint32 offset, Common::SharedPtr<Node> string) {
auto lastLine = pop();
auto firstLine = pop();
auto lastItem = pop();
@@ -311,13 +311,13 @@ Common::SharedPtr<Node> Handler::readChunkRef(Common::SharedPtr<Node> string) {
auto firstChar = pop();
if (!(firstLine->type == kLiteralNode && firstLine->getValue()->type == kDatumInt && firstLine->getValue()->toInt() == 0))
- string = Common::SharedPtr<Node>(new ChunkExprNode(kChunkLine, Common::move(firstLine), Common::move(lastLine), Common::move(string)));
+ string = Common::SharedPtr<Node>(new ChunkExprNode(offset, kChunkLine, Common::move(firstLine), Common::move(lastLine), Common::move(string)));
if (!(firstItem->type == kLiteralNode && firstItem->getValue()->type == kDatumInt && firstItem->getValue()->toInt() == 0))
- string = Common::SharedPtr<Node>(new ChunkExprNode(kChunkItem, Common::move(firstItem), Common::move(lastItem), Common::move(string)));
+ string = Common::SharedPtr<Node>(new ChunkExprNode(offset, kChunkItem, Common::move(firstItem), Common::move(lastItem), Common::move(string)));
if (!(firstWord->type == kLiteralNode && firstWord->getValue()->type == kDatumInt && firstWord->getValue()->toInt() == 0))
- string = Common::SharedPtr<Node>(new ChunkExprNode(kChunkWord, Common::move(firstWord), Common::move(lastWord), Common::move(string)));
+ string = Common::SharedPtr<Node>(new ChunkExprNode(offset, kChunkWord, Common::move(firstWord), Common::move(lastWord), Common::move(string)));
if (!(firstChar->type == kLiteralNode && firstChar->getValue()->type == kDatumInt && firstChar->getValue()->toInt() == 0))
- string = Common::SharedPtr<Node>(new ChunkExprNode(kChunkChar, Common::move(firstChar), Common::move(lastChar), Common::move(string)));
+ string = Common::SharedPtr<Node>(new ChunkExprNode(offset, kChunkChar, Common::move(firstChar), Common::move(lastChar), Common::move(string)));
return string;
}
@@ -514,7 +514,7 @@ void Handler::parse() {
if (caseLabel) {
if (caseLabel->expect == kCaseExpectOtherwise) {
ast.currentBlock->currentCaseLabel = nullptr;
- caseStmt->addOtherwise();
+ caseStmt->addOtherwise(i);
size_t otherwiseIndex = bytecodePosMap[caseStmt->potentialOtherwisePos];
bytecodeArray[otherwiseIndex].translation = Common::SharedPtr<Node>(caseStmt->otherwise);
ast.enterBlock(caseStmt->otherwise->block.get());
@@ -543,12 +543,14 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
case kOpRet:
case kOpRetFactory:
if (index == bytecodeArray.size() - 1) {
+ ast.root->_endOffset = bytecode.pos;
+ ast.currentBlock->_endOffset = bytecode.pos;
return 1; // end of handler
}
- translation = Common::SharedPtr<Node>(new ExitStmtNode());
+ translation = Common::SharedPtr<Node>(new ExitStmtNode(index));
break;
case kOpPushZero:
- translation = Common::SharedPtr<Node>(new LiteralNode(Common::SharedPtr<Datum>(new Datum(0))));
+ translation = Common::SharedPtr<Node>(new LiteralNode(index, Common::SharedPtr<Datum>(new Datum(0))));
break;
case kOpMul:
case kOpAdd:
@@ -570,25 +572,25 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
{
auto b = pop();
auto a = pop();
- translation = Common::SharedPtr<Node>(new BinaryOpNode(bytecode.opcode, Common::move(a), Common::move(b)));
+ translation = Common::SharedPtr<Node>(new BinaryOpNode(index, bytecode.opcode, Common::move(a), Common::move(b)));
}
break;
case kOpInv:
{
auto x = pop();
- translation = Common::SharedPtr<Node>(new InverseOpNode(Common::move(x)));
+ translation = Common::SharedPtr<Node>(new InverseOpNode(index, Common::move(x)));
}
break;
case kOpNot:
{
auto x = pop();
- translation = Common::SharedPtr<Node>(new NotOpNode(Common::move(x)));
+ translation = Common::SharedPtr<Node>(new NotOpNode(index, Common::move(x)));
}
break;
case kOpGetChunk:
{
auto string = pop();
- translation = readChunkRef(Common::move(string));
+ translation = readChunkRef(index, Common::move(string));
}
break;
case kOpHiliteChunk:
@@ -597,12 +599,12 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
if (script->version >= 500)
castID = pop();
auto fieldID = pop();
- auto field = Common::SharedPtr<Node>(new MemberExprNode("field", Common::move(fieldID), Common::move(castID)));
- auto chunk = readChunkRef(Common::move(field));
+ auto field = Common::SharedPtr<Node>(new MemberExprNode(index, "field", Common::move(fieldID), Common::move(castID)));
+ auto chunk = readChunkRef(index, Common::move(field));
if (chunk->type == kCommentNode) { // error comment
translation = chunk;
} else {
- translation = Common::SharedPtr<Node>(new ChunkHiliteStmtNode(Common::move(chunk)));
+ translation = Common::SharedPtr<Node>(new ChunkHiliteStmtNode(index, Common::move(chunk)));
}
}
break;
@@ -610,14 +612,14 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
{
auto secondSprite = pop();
auto firstSprite = pop();
- translation = Common::SharedPtr<Node>(new SpriteIntersectsExprNode(Common::move(firstSprite), Common::move(secondSprite)));
+ translation = Common::SharedPtr<Node>(new SpriteIntersectsExprNode(index, Common::move(firstSprite), Common::move(secondSprite)));
}
break;
case kOpIntoSpr:
{
auto secondSprite = pop();
auto firstSprite = pop();
- translation = Common::SharedPtr<Node>(new SpriteWithinExprNode(Common::move(firstSprite), Common::move(secondSprite)));
+ translation = Common::SharedPtr<Node>(new SpriteWithinExprNode(index, Common::move(firstSprite), Common::move(secondSprite)));
}
break;
case kOpGetField:
@@ -626,13 +628,13 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
if (script->version >= 500)
castID = pop();
auto fieldID = pop();
- translation = Common::SharedPtr<Node>(new MemberExprNode("field", Common::move(fieldID), Common::move(castID)));
+ translation = Common::SharedPtr<Node>(new MemberExprNode(index, "field", Common::move(fieldID), Common::move(castID)));
}
break;
case kOpStartTell:
{
auto window = pop();
- auto tellStmt = Common::SharedPtr<TellStmtNode>(new TellStmtNode(Common::move(window)));
+ auto tellStmt = Common::SharedPtr<TellStmtNode>(new TellStmtNode(index, Common::move(window)));
translation = tellStmt;
nextBlock = tellStmt->block.get();
}
@@ -669,13 +671,13 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
case kOpPushInt32:
{
auto i = Common::SharedPtr<Datum>(new Datum((int)bytecode.obj));
- translation = Common::SharedPtr<Node>(new LiteralNode(Common::move(i)));
+ translation = Common::SharedPtr<Node>(new LiteralNode(index, Common::move(i)));
}
break;
case kOpPushFloat32:
{
auto f = Common::SharedPtr<Datum>(new Datum(*(float *)(&bytecode.obj)));
- translation = Common::SharedPtr<Node>(new LiteralNode(Common::move(f)));
+ translation = Common::SharedPtr<Node>(new LiteralNode(index, Common::move(f)));
}
break;
case kOpPushArgListNoRet:
@@ -688,7 +690,7 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
args[argCount] = pop();
}
auto argList = Common::SharedPtr<Datum>(new Datum(kDatumArgListNoRet, args));
- translation = Common::SharedPtr<Node>(new LiteralNode(Common::move(argList)));
+ translation = Common::SharedPtr<Node>(new LiteralNode(bytecode.pos, Common::move(argList)));
}
break;
case kOpPushArgList:
@@ -701,75 +703,75 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
args[argCount] = pop();
}
auto argList = Common::SharedPtr<Datum>(new Datum(kDatumArgList, args));
- translation = Common::SharedPtr<Node>(new LiteralNode(Common::move(argList)));
+ translation = Common::SharedPtr<Node>(new LiteralNode(bytecode.pos, Common::move(argList)));
}
break;
case kOpPushCons:
{
int literalID = bytecode.obj / variableMultiplier();
if (-1 < literalID && (unsigned)literalID < script->literals.size()) {
- translation = Common::SharedPtr<Node>(new LiteralNode(script->literals[literalID].value));
+ translation = Common::SharedPtr<Node>(new LiteralNode(bytecode.pos, script->literals[literalID].value));
} else {
- translation = Common::SharedPtr<Node>(new ErrorNode());
+ translation = Common::SharedPtr<Node>(new ErrorNode(bytecode.pos));
}
break;
}
case kOpPushSymb:
{
auto sym = Common::SharedPtr<Datum>(new Datum(kDatumSymbol, getName(bytecode.obj)));
- translation = Common::SharedPtr<Node>(new LiteralNode(Common::move(sym)));
+ translation = Common::SharedPtr<Node>(new LiteralNode(bytecode.pos, Common::move(sym)));
}
break;
case kOpPushVarRef:
{
auto ref = Common::SharedPtr<Datum>(new Datum(kDatumVarRef, getName(bytecode.obj)));
- translation = Common::SharedPtr<Node>(new LiteralNode(Common::move(ref)));
+ translation = Common::SharedPtr<Node>(new LiteralNode(bytecode.pos, Common::move(ref)));
}
break;
case kOpGetGlobal:
case kOpGetGlobal2:
{
auto name_ = getName(bytecode.obj);
- translation = Common::SharedPtr<Node>(new VarNode(name_));
+ translation = Common::SharedPtr<Node>(new VarNode(bytecode.pos, name_));
}
break;
case kOpGetProp:
- translation = Common::SharedPtr<Node>(new VarNode(getName(bytecode.obj)));
+ translation = Common::SharedPtr<Node>(new VarNode(bytecode.pos, getName(bytecode.obj)));
break;
case kOpGetParam:
- translation = Common::SharedPtr<Node>(new VarNode(getArgumentName(bytecode.obj / variableMultiplier())));
+ translation = Common::SharedPtr<Node>(new VarNode(bytecode.pos, getArgumentName(bytecode.obj / variableMultiplier())));
break;
case kOpGetLocal:
- translation = Common::SharedPtr<Node>(new VarNode(getLocalName(bytecode.obj / variableMultiplier())));
+ translation = Common::SharedPtr<Node>(new VarNode(bytecode.pos, getLocalName(bytecode.obj / variableMultiplier())));
break;
case kOpSetGlobal:
case kOpSetGlobal2:
{
auto varName = getName(bytecode.obj);
- auto var = Common::SharedPtr<Node>(new VarNode(varName));
+ auto var = Common::SharedPtr<Node>(new VarNode(bytecode.pos, varName));
auto value = pop();
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(var), Common::move(value)));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(var), Common::move(value)));
}
break;
case kOpSetProp:
{
- auto var = Common::SharedPtr<Node>(new VarNode(getName(bytecode.obj)));
+ auto var = Common::SharedPtr<Node>(new VarNode(bytecode.pos, getName(bytecode.obj)));
auto value = pop();
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(var), Common::move(value)));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(var), Common::move(value)));
}
break;
case kOpSetParam:
{
- auto var = Common::SharedPtr<Node>(new VarNode(getArgumentName(bytecode.obj / variableMultiplier())));
+ auto var = Common::SharedPtr<Node>(new VarNode(bytecode.pos, getArgumentName(bytecode.obj / variableMultiplier())));
auto value = pop();
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(var), Common::move(value)));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(var), Common::move(value)));
}
break;
case kOpSetLocal:
{
- auto var = Common::SharedPtr<Node>(new VarNode(getLocalName(bytecode.obj / variableMultiplier())));
+ auto var = Common::SharedPtr<Node>(new VarNode(bytecode.pos, getLocalName(bytecode.obj / variableMultiplier())));
auto value = pop();
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(var), Common::move(value)));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(var), Common::move(value)));
}
break;
case kOpJmp:
@@ -780,10 +782,10 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
auto ancestorLoop = ast.currentBlock->ancestorLoop();
if (ancestorLoop) {
if (bytecodeArray[targetIndex - 1].opcode == kOpEndRepeat && bytecodeArray[targetIndex - 1].ownerLoop == ancestorLoop->startIndex) {
- translation = Common::SharedPtr<Node>(new ExitRepeatStmtNode());
+ translation = Common::SharedPtr<Node>(new ExitRepeatStmtNode(bytecode.pos));
break;
} else if (bytecodeArray[targetIndex].tag == kTagNextRepeatTarget && bytecodeArray[targetIndex].ownerLoop == ancestorLoop->startIndex) {
- translation = Common::SharedPtr<Node>(new NextRepeatStmtNode());
+ translation = Common::SharedPtr<Node>(new NextRepeatStmtNode(bytecode.pos));
break;
}
}
@@ -794,13 +796,17 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
auto ifStmt = static_cast<IfStmtNode *>(ancestorStatement);
if (ast.currentBlock == ifStmt->block1.get()) {
ifStmt->hasElse = true;
+ ifStmt->block2->_startOffset = ifStmt->block1->_endOffset;
ifStmt->block2->endPos = targetPos;
+ ifStmt->block2->_endOffset = targetPos;
+ ifStmt->_endOffset = targetPos;
return 1; // if statement amended, nothing to push
}
} else if (ancestorStatement->type == kCaseStmtNode) {
auto caseStmt = static_cast<CaseStmtNode *>(ancestorStatement);
caseStmt->potentialOtherwisePos = bytecode.pos;
caseStmt->endPos = targetPos;
+ caseStmt->_endOffset = targetPos;
targetBytecode.tag = kTagEndCase;
return 1;
}
@@ -808,20 +814,21 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
if (targetBytecode.opcode == kOpPop && targetBytecode.obj == 1) {
// This is a case statement starting with 'otherwise'
auto value = pop();
- auto caseStmt = Common::SharedPtr<CaseStmtNode>(new CaseStmtNode(Common::move(value)));
+ auto caseStmt = Common::SharedPtr<CaseStmtNode>(new CaseStmtNode(bytecode.pos, Common::move(value)));
caseStmt->endPos = targetPos;
+ caseStmt->_endOffset = targetPos;
targetBytecode.tag = kTagEndCase;
- caseStmt->addOtherwise();
+ caseStmt->addOtherwise(bytecode.pos);
translation = caseStmt;
nextBlock = caseStmt->otherwise->block.get();
break;
}
- translation = Common::SharedPtr<Node>(new CommentNode("ERROR: Could not identify jmp"));
+ translation = Common::SharedPtr<Node>(new CommentNode(bytecode.pos, "ERROR: Could not identify jmp"));
}
break;
case kOpEndRepeat:
// This should normally be tagged kTagSkip or kTagNextRepeatTarget and skipped.
- translation = Common::SharedPtr<Node>(new CommentNode("ERROR: Stray endrepeat"));
+ translation = Common::SharedPtr<Node>(new CommentNode(bytecode.pos, "ERROR: Stray endrepeat"));
break;
case kOpJmpIfZ:
{
@@ -831,8 +838,10 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
case kTagRepeatWhile:
{
auto condition = pop();
- auto loop = Common::SharedPtr<RepeatWhileStmtNode>(new RepeatWhileStmtNode(index, Common::move(condition)));
+ auto loop = Common::SharedPtr<RepeatWhileStmtNode>(new RepeatWhileStmtNode(index, Common::move(condition), bytecode.pos));
loop->block->endPos = endPos;
+ loop->block->_endOffset = endPos;
+ loop->_endOffset = endPos;
translation = loop;
nextBlock = loop->block.get();
}
@@ -841,8 +850,10 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
{
auto list = pop();
Common::String varName = getVarNameFromSet(bytecodeArray[index + 5]);
- auto loop = Common::SharedPtr<RepeatWithInStmtNode>(new RepeatWithInStmtNode(index, varName, Common::move(list)));
+ auto loop = Common::SharedPtr<RepeatWithInStmtNode>(new RepeatWithInStmtNode(index, varName, Common::move(list), bytecode.pos));
loop->block->endPos = endPos;
+ loop->block->_endOffset = endPos;
+ loop->_endOffset = endPos;
translation = loop;
nextBlock = loop->block.get();
}
@@ -856,8 +867,10 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
auto endRepeat = bytecodeArray[endIndex - 1];
uint32 conditionStartIndex = bytecodePosMap[endRepeat.pos - endRepeat.obj];
Common::String varName = getVarNameFromSet(bytecodeArray[conditionStartIndex - 1]);
- auto loop = Common::SharedPtr<RepeatWithToStmtNode>(new RepeatWithToStmtNode(index, varName, Common::move(start), up, Common::move(end)));
+ auto loop = Common::SharedPtr<RepeatWithToStmtNode>(new RepeatWithToStmtNode(index, varName, Common::move(start), up, Common::move(end), bytecode.pos));
loop->block->endPos = endPos;
+ loop->block->_endOffset = endPos;
+ loop->_endOffset = endPos;
translation = loop;
nextBlock = loop->block.get();
}
@@ -865,8 +878,10 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
default:
{
auto condition = pop();
- auto ifStmt = Common::SharedPtr<IfStmtNode>(new IfStmtNode(Common::move(condition)));
+ auto ifStmt = Common::SharedPtr<IfStmtNode>(new IfStmtNode(bytecode.pos, Common::move(condition)));
ifStmt->block1->endPos = endPos;
+ ifStmt->block1->_endOffset = endPos;
+ ifStmt->_endOffset = endPos;
translation = ifStmt;
nextBlock = ifStmt->block1.get();
}
@@ -877,7 +892,7 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
case kOpLocalCall:
{
auto argList = pop();
- translation = Common::SharedPtr<Node>(new CallNode(script->handlers[bytecode.obj].name, Common::move(argList)));
+ translation = Common::SharedPtr<Node>(new CallNode(bytecode.pos, script->handlers[bytecode.obj].name, Common::move(argList)));
}
break;
case kOpExtCall:
@@ -891,11 +906,11 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
if (isStatement && name_ == "sound" && nargs > 0 && rawArgList[0]->type == kLiteralNode && rawArgList[0]->getValue()->type == kDatumSymbol) {
Common::String cmd = rawArgList[0]->getValue()->s;
rawArgList.erase(rawArgList.begin());
- translation = Common::SharedPtr<Node>(new SoundCmdStmtNode(cmd, Common::move(argList)));
+ translation = Common::SharedPtr<Node>(new SoundCmdStmtNode(bytecode.pos, cmd, Common::move(argList)));
} else if (isStatement && name_ == "play" && nargs <= 2) {
- translation = Common::SharedPtr<Node>(new PlayCmdStmtNode(Common::move(argList)));
+ translation = Common::SharedPtr<Node>(new PlayCmdStmtNode(bytecode.pos, Common::move(argList)));
} else {
- translation = Common::SharedPtr<Node>(new CallNode(name_, Common::move(argList)));
+ translation = Common::SharedPtr<Node>(new CallNode(bytecode.pos, name_, Common::move(argList)));
}
}
break;
@@ -907,9 +922,9 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
if (rawArgList.size() > 0) {
// first arg is a symbol
// replace it with a variable
- rawArgList[0] = Common::SharedPtr<Node>(new VarNode(rawArgList[0]->getValue()->s));
+ rawArgList[0] = Common::SharedPtr<Node>(new VarNode(bytecode.pos, rawArgList[0]->getValue()->s));
}
- translation = Common::SharedPtr<Node>(new ObjCallV4Node(Common::move(object), Common::move(argList)));
+ translation = Common::SharedPtr<Node>(new ObjCallV4Node(bytecode.pos, Common::move(object), Common::move(argList)));
}
break;
case kOpPut:
@@ -918,7 +933,7 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
uint32 varType = bytecode.obj & 0xF;
auto var = readVar(varType);
auto val = pop();
- translation = Common::SharedPtr<Node>(new PutStmtNode(putType, Common::move(var), Common::move(val)));
+ translation = Common::SharedPtr<Node>(new PutStmtNode(bytecode.pos, putType, Common::move(var), Common::move(val)));
}
break;
case kOpPutChunk:
@@ -926,30 +941,30 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
PutType putType = static_cast<PutType>((bytecode.obj >> 4) & 0xF);
uint32 varType = bytecode.obj & 0xF;
auto var = readVar(varType);
- auto chunk = readChunkRef(Common::move(var));
+ auto chunk = readChunkRef(bytecode.pos, Common::move(var));
auto val = pop();
if (chunk->type == kCommentNode) { // error comment
translation = chunk;
} else {
- translation = Common::SharedPtr<Node>(new PutStmtNode(putType, Common::move(chunk), Common::move(val)));
+ translation = Common::SharedPtr<Node>(new PutStmtNode(bytecode.pos, putType, Common::move(chunk), Common::move(val)));
}
}
break;
case kOpDeleteChunk:
{
auto var = readVar(bytecode.obj);
- auto chunk = readChunkRef(Common::move(var));
+ auto chunk = readChunkRef(bytecode.pos, Common::move(var));
if (chunk->type == kCommentNode) { // error comment
translation = chunk;
} else {
- translation = Common::SharedPtr<Node>(new ChunkDeleteStmtNode(Common::move(chunk)));
+ translation = Common::SharedPtr<Node>(new ChunkDeleteStmtNode(bytecode.pos, Common::move(chunk)));
}
}
break;
case kOpGet:
{
int propertyID = pop()->getValue()->toInt();
- translation = readV4Property(bytecode.obj, propertyID);
+ translation = readV4Property(bytecode.pos, bytecode.obj, propertyID);
}
break;
case kOpSet:
@@ -962,42 +977,42 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
// If the script contains a line break, it's definitely a when statement.
Common::String script_ = value->getValue()->s;
if (script_.size() > 0 && (script_[0] == ' ' || script_.find('\r') != Common::String::npos)) {
- translation = Common::SharedPtr<Node>(new WhenStmtNode(propertyID, script_));
+ translation = Common::SharedPtr<Node>(new WhenStmtNode(bytecode.pos, propertyID, script_));
}
}
if (!translation) {
- auto prop = readV4Property(bytecode.obj, propertyID);
+ auto prop = readV4Property(bytecode.pos, bytecode.obj, propertyID);
if (prop->type == kCommentNode) { // error comment
translation = prop;
} else {
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(prop), Common::move(value), true));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(prop), Common::move(value), true));
}
}
}
break;
case kOpGetMovieProp:
- translation = Common::SharedPtr<Node>(new TheExprNode(getName(bytecode.obj)));
+ translation = Common::SharedPtr<Node>(new TheExprNode(bytecode.pos, getName(bytecode.obj)));
break;
case kOpSetMovieProp:
{
auto value = pop();
- auto prop = Common::SharedPtr<TheExprNode>(new TheExprNode(getName(bytecode.obj)));
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(prop), Common::move(value)));
+ auto prop = Common::SharedPtr<TheExprNode>(new TheExprNode(bytecode.pos, getName(bytecode.obj)));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(prop), Common::move(value)));
}
break;
case kOpGetObjProp:
case kOpGetChainedProp:
{
auto object = pop();
- translation = Common::SharedPtr<Node>(new ObjPropExprNode(Common::move(object), getName(bytecode.obj)));
+ translation = Common::SharedPtr<Node>(new ObjPropExprNode(bytecode.pos, Common::move(object), getName(bytecode.obj)));
}
break;
case kOpSetObjProp:
{
auto value = pop();
auto object = pop();
- auto prop = Common::SharedPtr<ObjPropExprNode>(new ObjPropExprNode(Common::move(object), getName(bytecode.obj)));
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(prop), Common::move(value)));
+ auto prop = Common::SharedPtr<ObjPropExprNode>(new ObjPropExprNode(bytecode.pos, Common::move(object), getName(bytecode.obj)));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(prop), Common::move(value)));
}
break;
case kOpPeek:
@@ -1022,7 +1037,7 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
&& !(stack.size() == originalStackSize + 1 && (currBytecode->opcode == kOpEq || currBytecode->opcode == kOpNtEq))
);
if (currIndex >= bytecodeArray.size()) {
- bytecode.translation = Common::SharedPtr<Node>(new CommentNode("ERROR: Expected eq or nteq!"));
+ bytecode.translation = Common::SharedPtr<Node>(new CommentNode(bytecode.pos, "ERROR: Expected eq or nteq!"));
ast.addStatement(bytecode.translation);
return currIndex - index + 1;
}
@@ -1035,7 +1050,7 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
currIndex += 1;
currBytecode = &bytecodeArray[currIndex];
if (currIndex >= bytecodeArray.size() || currBytecode->opcode != kOpJmpIfZ) {
- bytecode.translation = Common::SharedPtr<Node>(new CommentNode("ERROR: Expected jmpifz!"));
+ bytecode.translation = Common::SharedPtr<Node>(new CommentNode(bytecode.pos, "ERROR: Expected jmpifz!"));
ast.addStatement(bytecode.translation);
return currIndex - index + 1;
}
@@ -1058,13 +1073,13 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
expect = kCaseExpectOtherwise; // Expect an 'otherwise' block.
}
- auto currLabel = Common::SharedPtr<CaseLabelNode>(new CaseLabelNode(Common::move(caseValue), expect));
+ auto currLabel = Common::SharedPtr<CaseLabelNode>(new CaseLabelNode(bytecode.pos, Common::move(caseValue), expect));
jmpifz.translation = currLabel;
ast.currentBlock->currentCaseLabel = currLabel.get();
if (!prevLabel) {
auto peekedValue = pop();
- auto caseStmt = Common::SharedPtr<CaseStmtNode>(new CaseStmtNode(Common::move(peekedValue)));
+ auto caseStmt = Common::SharedPtr<CaseStmtNode>(new CaseStmtNode(bytecode.pos, Common::move(peekedValue)));
caseStmt->firstLabel = currLabel;
currLabel->parent = caseStmt.get();
bytecode.translation = caseStmt;
@@ -1080,9 +1095,11 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
// The block doesn't start until the after last equivalent case,
// so don't create a block yet if we're expecting an equivalent case.
if (currLabel->expect != kCaseExpectOr) {
- currLabel->block = Common::SharedPtr<BlockNode>(new BlockNode());
+ currLabel->block = Common::SharedPtr<BlockNode>(new BlockNode(bytecode.pos));
currLabel->block->parent = currLabel.get();
currLabel->block->endPos = jmpPos;
+ currLabel->block->_endOffset = jmpPos;
+ currLabel->_endOffset = jmpPos;
ast.enterBlock(currLabel->block.get());
}
@@ -1102,7 +1119,7 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
// We have an unused value on the stack, so this must be the end
// of a case statement with no labels.
auto value = pop();
- translation = Common::SharedPtr<Node>(new CaseStmtNode(Common::move(value)));
+ translation = Common::SharedPtr<Node>(new CaseStmtNode(bytecode.pos, Common::move(value)));
break;
}
// Otherwise, this pop instruction occurs before a 'return' within
@@ -1113,7 +1130,7 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
case kOpTheBuiltin:
{
pop(); // empty arglist
- translation = Common::SharedPtr<Node>(new TheExprNode(getName(bytecode.obj)));
+ translation = Common::SharedPtr<Node>(new TheExprNode(bytecode.pos, getName(bytecode.obj)));
}
break;
case kOpObjCall:
@@ -1126,14 +1143,14 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
// obj.getAt(i) => obj[i]
auto obj = rawArgList[0];
auto prop = rawArgList[1];
- translation = Common::SharedPtr<Node>(new ObjBracketExprNode(Common::move(obj), Common::move(prop)));
+ translation = Common::SharedPtr<Node>(new ObjBracketExprNode(bytecode.pos, Common::move(obj), Common::move(prop)));
} else if (method == "setAt" && nargs == 3) {
// obj.setAt(i) => obj[i] = val
auto obj = rawArgList[0];
auto prop = rawArgList[1];
auto val = rawArgList[2];
- Common::SharedPtr<Node> propExpr = Common::SharedPtr<Node>(new ObjBracketExprNode(Common::move(obj), Common::move(prop)));
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(propExpr), Common::move(val)));
+ Common::SharedPtr<Node> propExpr = Common::SharedPtr<Node>(new ObjBracketExprNode(bytecode.pos, Common::move(obj), Common::move(prop)));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(propExpr), Common::move(val)));
} else if ((method == "getProp" || method == "getPropRef") && (nargs == 3 || nargs == 4) && rawArgList[1]->getValue()->type == kDatumSymbol) {
// obj.getProp(#prop, i) => obj.prop[i]
// obj.getProp(#prop, i, i2) => obj.prop[i..i2]
@@ -1141,7 +1158,7 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
Common::String propName = rawArgList[1]->getValue()->s;
auto i = rawArgList[2];
auto i2 = (nargs == 4) ? rawArgList[3] : nullptr;
- translation = Common::SharedPtr<Node>(new ObjPropIndexExprNode(Common::move(obj), propName, Common::move(i), Common::move(i2)));
+ translation = Common::SharedPtr<Node>(new ObjPropIndexExprNode(bytecode.pos, Common::move(obj), propName, Common::move(i), Common::move(i2)));
} else if (method == "setProp" && (nargs == 4 || nargs == 5) && rawArgList[1]->getValue()->type == kDatumSymbol) {
// obj.setProp(#prop, i, val) => obj.prop[i] = val
// obj.setProp(#prop, i, i2, val) => obj.prop[i..i2] = val
@@ -1149,15 +1166,15 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
Common::String propName = rawArgList[1]->getValue()->s;
auto i = rawArgList[2];
auto i2 = (nargs == 5) ? rawArgList[3] : nullptr;
- auto propExpr = Common::SharedPtr<ObjPropIndexExprNode>(new ObjPropIndexExprNode(Common::move(obj), propName, Common::move(i), Common::move(i2)));
+ auto propExpr = Common::SharedPtr<ObjPropIndexExprNode>(new ObjPropIndexExprNode(bytecode.pos, Common::move(obj), propName, Common::move(i), Common::move(i2)));
auto val = rawArgList[nargs - 1];
- translation = Common::SharedPtr<Node>(new AssignmentStmtNode(Common::move(propExpr), Common::move(val)));
+ translation = Common::SharedPtr<Node>(new AssignmentStmtNode(bytecode.pos, Common::move(propExpr), Common::move(val)));
} else if (method == "count" && nargs == 2 && rawArgList[1]->getValue()->type == kDatumSymbol) {
// obj.count(#prop) => obj.prop.count
auto obj = rawArgList[0];
Common::String propName = rawArgList[1]->getValue()->s;
- auto propExpr = Common::SharedPtr<ObjPropExprNode>(new ObjPropExprNode(Common::move(obj), propName));
- translation = Common::SharedPtr<Node>(new ObjPropExprNode(Common::move(propExpr), "count"));
+ auto propExpr = Common::SharedPtr<ObjPropExprNode>(new ObjPropExprNode(bytecode.pos, Common::move(obj), propName));
+ translation = Common::SharedPtr<Node>(new ObjPropExprNode(bytecode.pos, Common::move(propExpr), "count"));
} else if ((method == "setContents" || method == "setContentsAfter" || method == "setContentsBefore") && nargs == 2) {
// var.setContents(val) => put val into var
// var.setContentsAfter(val) => put val after var
@@ -1172,17 +1189,17 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
}
auto var = rawArgList[0];
auto val = rawArgList[1];
- translation = Common::SharedPtr<Node>(new PutStmtNode(putType, Common::move(var), Common::move(val)));
+ translation = Common::SharedPtr<Node>(new PutStmtNode(bytecode.pos, putType, Common::move(var), Common::move(val)));
} else if (method == "hilite" && nargs == 1) {
// chunk.hilite() => hilite chunk
auto chunk = rawArgList[0];
- translation = Common::SharedPtr<Node>(new ChunkHiliteStmtNode(chunk));
+ translation = Common::SharedPtr<Node>(new ChunkHiliteStmtNode(bytecode.pos, chunk));
} else if (method == "delete" && nargs == 1) {
// chunk.delete() => delete chunk
auto chunk = rawArgList[0];
- translation = Common::SharedPtr<Node>(new ChunkDeleteStmtNode(chunk));
+ translation = Common::SharedPtr<Node>(new ChunkDeleteStmtNode(bytecode.pos, chunk));
} else {
- translation = Common::SharedPtr<Node>(new ObjCallNode(method, Common::move(argList)));
+ translation = Common::SharedPtr<Node>(new ObjCallNode(bytecode.pos, method, Common::move(argList)));
}
}
break;
@@ -1192,14 +1209,14 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
case kOpGetTopLevelProp:
{
auto name_ = getName(bytecode.obj);
- translation = Common::SharedPtr<VarNode>(new VarNode(name_));
+ translation = Common::SharedPtr<VarNode>(new VarNode(bytecode.pos, name_));
}
break;
case kOpNewObj:
{
auto objType = getName(bytecode.obj);
auto objArgs = pop();
- translation = Common::SharedPtr<NewObjNode>(new NewObjNode(objType, Common::move(objArgs)));
+ translation = Common::SharedPtr<NewObjNode>(new NewObjNode(bytecode.pos, objType, Common::move(objArgs)));
}
break;
default:
@@ -1207,13 +1224,13 @@ uint32 Handler::translateBytecode(Bytecode &bytecode, uint32 index) {
auto commentText = StandardNames::getOpcodeName(bytecode.opID);
if (bytecode.opcode >= 0x40)
commentText += Common::String::format(" %d", bytecode.obj);
- translation = Common::SharedPtr<CommentNode>(new CommentNode(commentText));
+ translation = Common::SharedPtr<CommentNode>(new CommentNode(bytecode.pos, commentText));
stack.clear(); // Clear stack so later bytecode won't be too screwed up
}
}
if (!translation)
- translation = Common::SharedPtr<ErrorNode>(new ErrorNode());
+ translation = Common::SharedPtr<ErrorNode>(new ErrorNode(bytecode.pos));
bytecode.translation = translation;
if (translation->isExpression) {
diff --git a/engines/director/lingo/lingodec/handler.h b/engines/director/lingo/lingodec/handler.h
index 8fcafcfdad7..ae6ff0034e0 100644
--- a/engines/director/lingo/lingodec/handler.h
+++ b/engines/director/lingo/lingodec/handler.h
@@ -60,7 +60,7 @@ struct Handler {
bool isGenericEvent = false;
- Handler(): ast(this) {}
+ Handler(): ast(0, this) {}
void setScript(Script *s) {
script = s;
@@ -78,8 +78,8 @@ struct Handler {
int variableMultiplier();
Common::SharedPtr<Node> readVar(int varType);
Common::String getVarNameFromSet(const Bytecode &bytecode);
- Common::SharedPtr<Node> readV4Property(int propertyType, int propertyID);
- Common::SharedPtr<Node> readChunkRef(Common::SharedPtr<Node> string);
+ Common::SharedPtr<Node> readV4Property(uint32 offset, int propertyType, int propertyID);
+ Common::SharedPtr<Node> readChunkRef(uint32 offset, Common::SharedPtr<Node> string);
void tagLoops();
bool isRepeatWithIn(uint32 startIndex, uint32 endIndex);
BytecodeTag identifyLoop(uint32 startIndex, uint32 endIndex);
More information about the Scummvm-git-logs
mailing list