mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
* DIRECTOR: Fix warning about usage of ABS() * DIRECTOR: Remove MSVC-specific argument size modifier prefix from imgui The I (uppercase i) modifier is a Microsoft extension, and is not ISO compatible. MSVC supports the z modifier, which is ISO compatible, so use that everywhere inside the ImGui code. The relevant MSVC documentation can be found here: https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-170 * DIRECTOR: Fix assigning negative value to string end position
864 lines
24 KiB
C++
864 lines
24 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#ifndef LINGODEC_AST_H
|
|
#define LINGODEC_AST_H
|
|
|
|
#include "common/array.h"
|
|
#include "common/ptr.h"
|
|
#include "common/str.h"
|
|
#include "common/util.h"
|
|
#include "./enums.h"
|
|
|
|
namespace LingoDec {
|
|
|
|
struct CaseLabelNode;
|
|
struct Handler;
|
|
struct LoopNode;
|
|
struct Node;
|
|
struct RepeatWithInStmtNode;
|
|
|
|
/* Datum */
|
|
|
|
struct Datum {
|
|
DatumType type;
|
|
int i = -1;
|
|
double f = 0.0f;
|
|
Common::String s;
|
|
Common::Array<Common::SharedPtr<Node>> l;
|
|
|
|
Datum() {
|
|
type = kDatumVoid;
|
|
}
|
|
Datum(int val) {
|
|
type = kDatumInt;
|
|
i = val;
|
|
}
|
|
Datum(double val) {
|
|
type = kDatumFloat;
|
|
f = val;
|
|
}
|
|
Datum(DatumType t, Common::String val) {
|
|
type = t;
|
|
s = val;
|
|
}
|
|
Datum(DatumType t, Common::Array<Common::SharedPtr<Node>> val) {
|
|
type = t;
|
|
l = val;
|
|
}
|
|
|
|
int toInt();
|
|
};
|
|
|
|
class NodeVisitor;
|
|
|
|
/* Node */
|
|
|
|
struct Node {
|
|
NodeType type;
|
|
bool isExpression;
|
|
bool isStatement;
|
|
bool isLabel;
|
|
bool isLoop;
|
|
Node *parent;
|
|
uint32 _startOffset;
|
|
uint32 _endOffset;
|
|
|
|
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 accept(NodeVisitor& visitor) const = 0;
|
|
virtual Common::SharedPtr<Datum> getValue();
|
|
Node *ancestorStatement();
|
|
LoopNode *ancestorLoop();
|
|
virtual bool hasSpaces(bool dot);
|
|
};
|
|
|
|
/* ExprNode */
|
|
|
|
struct ExprNode : Node {
|
|
ExprNode(NodeType t, uint32 offset) : Node(t, offset) {
|
|
isExpression = true;
|
|
}
|
|
};
|
|
|
|
/* StmtNode */
|
|
|
|
struct StmtNode : Node {
|
|
StmtNode(NodeType t, uint32 offset) : Node(t, offset) {
|
|
isStatement = true;
|
|
}
|
|
};
|
|
|
|
/* LabelNode */
|
|
|
|
struct LabelNode : Node {
|
|
LabelNode(NodeType t, uint32 offset) : Node(t, offset) {
|
|
isLabel = true;
|
|
}
|
|
};
|
|
|
|
/* LoopNode */
|
|
|
|
struct LoopNode : StmtNode {
|
|
uint32 startIndex;
|
|
|
|
LoopNode(NodeType t, uint32 startIndex_, uint32 offset) : StmtNode(t, offset), startIndex(startIndex_) {
|
|
isLoop = true;
|
|
}
|
|
};
|
|
|
|
/* ErrorNode */
|
|
|
|
struct ErrorNode : ExprNode {
|
|
explicit ErrorNode(uint32 offset) : ExprNode(kErrorNode, offset) {}
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* CommentNode */
|
|
|
|
struct CommentNode : Node {
|
|
Common::String text;
|
|
|
|
CommentNode(uint32 offset, Common::String t) : Node(kCommentNode, offset), text(t) {}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* LiteralNode */
|
|
|
|
struct LiteralNode : ExprNode {
|
|
Common::SharedPtr<Datum> value;
|
|
|
|
LiteralNode(uint32 offset, Common::SharedPtr<Datum> d) : ExprNode(kLiteralNode, offset) {
|
|
value = Common::move(d);
|
|
}
|
|
Common::SharedPtr<Datum> getValue() override;
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* BlockNode */
|
|
|
|
struct BlockNode : Node {
|
|
Common::Array<Common::SharedPtr<Node>> children;
|
|
|
|
// for use during translation:
|
|
uint32 endPos;
|
|
CaseLabelNode *currentCaseLabel = nullptr;
|
|
|
|
explicit BlockNode(uint32 offset) : Node(kBlockNode, offset), endPos(Common::String::npos) {}
|
|
void addChild(Common::SharedPtr<Node> child);
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* HandlerNode */
|
|
|
|
struct HandlerNode : Node {
|
|
Handler *handler;
|
|
Common::SharedPtr<BlockNode> block;
|
|
|
|
HandlerNode(uint32 offset, Handler *h)
|
|
: Node(kHandlerNode, offset), handler(h) {
|
|
block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
|
|
block->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ExitStmtNode */
|
|
|
|
struct ExitStmtNode : StmtNode {
|
|
explicit ExitStmtNode(uint32 offset) : StmtNode(kExitStmtNode, offset) {}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* InverseOpNode */
|
|
|
|
struct InverseOpNode : ExprNode {
|
|
Common::SharedPtr<Node> operand;
|
|
|
|
InverseOpNode(uint32 offset, Common::SharedPtr<Node> o) : ExprNode(kInverseOpNode, offset) {
|
|
operand = Common::move(o);
|
|
operand->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* NotOpNode */
|
|
|
|
struct NotOpNode : ExprNode {
|
|
Common::SharedPtr<Node> operand;
|
|
|
|
NotOpNode(uint32 offset, Common::SharedPtr<Node> o) : ExprNode(kNotOpNode, offset) {
|
|
operand = Common::move(o);
|
|
operand->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* BinaryOpNode */
|
|
|
|
struct BinaryOpNode : ExprNode {
|
|
OpCode opcode;
|
|
Common::SharedPtr<Node> left;
|
|
Common::SharedPtr<Node> right;
|
|
|
|
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 unsigned int getPrecedence() const;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ChunkExprNode */
|
|
|
|
struct ChunkExprNode : ExprNode {
|
|
ChunkExprType type;
|
|
Common::SharedPtr<Node> first;
|
|
Common::SharedPtr<Node> last;
|
|
Common::SharedPtr<Node> string;
|
|
|
|
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);
|
|
last->parent = this;
|
|
string = Common::move(s);
|
|
string->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ChunkHiliteStmtNode */
|
|
|
|
struct ChunkHiliteStmtNode : StmtNode {
|
|
Common::SharedPtr<Node> chunk;
|
|
|
|
ChunkHiliteStmtNode(uint32 offset, Common::SharedPtr<Node> c) : StmtNode(kChunkHiliteStmtNode, offset) {
|
|
chunk = Common::move(c);
|
|
chunk->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ChunkDeleteStmtNode */
|
|
|
|
struct ChunkDeleteStmtNode : StmtNode {
|
|
Common::SharedPtr<Node> chunk;
|
|
|
|
ChunkDeleteStmtNode(uint32 offset, Common::SharedPtr<Node> c) : StmtNode(kChunkDeleteStmtNode, offset) {
|
|
chunk = Common::move(c);
|
|
chunk->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* SpriteIntersectsExprNode */
|
|
|
|
struct SpriteIntersectsExprNode : ExprNode {
|
|
Common::SharedPtr<Node> firstSprite;
|
|
Common::SharedPtr<Node> secondSprite;
|
|
|
|
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;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* SpriteWithinExprNode */
|
|
|
|
struct SpriteWithinExprNode : ExprNode {
|
|
Common::SharedPtr<Node> firstSprite;
|
|
Common::SharedPtr<Node> secondSprite;
|
|
|
|
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;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* MemberExprNode */
|
|
|
|
struct MemberExprNode : ExprNode {
|
|
Common::String type;
|
|
Common::SharedPtr<Node> memberID;
|
|
Common::SharedPtr<Node> castID;
|
|
|
|
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_) {
|
|
this->castID = Common::move(castID_);
|
|
this->castID->parent = this;
|
|
}
|
|
}
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* VarNode */
|
|
|
|
struct VarNode : ExprNode {
|
|
Common::String varName;
|
|
|
|
VarNode(uint32 offset, Common::String v) : ExprNode(kVarNode, offset), varName(v) {}
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* AssignmentStmtNode */
|
|
|
|
struct AssignmentStmtNode : StmtNode {
|
|
Common::SharedPtr<Node> variable;
|
|
Common::SharedPtr<Node> value;
|
|
bool 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;
|
|
}
|
|
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* IfStmtNode */
|
|
|
|
struct IfStmtNode : StmtNode {
|
|
bool hasElse;
|
|
Common::SharedPtr<Node> condition;
|
|
Common::SharedPtr<BlockNode> block1;
|
|
Common::SharedPtr<BlockNode> block2;
|
|
|
|
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(offset));
|
|
block1->parent = this;
|
|
block2 = Common::SharedPtr<BlockNode>(new BlockNode(offset));
|
|
block2->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* RepeatWhileStmtNode */
|
|
|
|
struct RepeatWhileStmtNode : LoopNode {
|
|
Common::SharedPtr<Node> condition;
|
|
Common::SharedPtr<BlockNode> block;
|
|
|
|
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(offset));
|
|
block->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* RepeatWithInStmtNode */
|
|
|
|
struct RepeatWithInStmtNode : LoopNode {
|
|
Common::String varName;
|
|
Common::SharedPtr<Node> list;
|
|
Common::SharedPtr<BlockNode> block;
|
|
|
|
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(offset));
|
|
block->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* RepeatWithToStmtNode */
|
|
|
|
struct RepeatWithToStmtNode : LoopNode {
|
|
Common::String varName;
|
|
Common::SharedPtr<Node> start;
|
|
bool up;
|
|
Common::SharedPtr<Node> end;
|
|
Common::SharedPtr<BlockNode> block;
|
|
|
|
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(offset));
|
|
block->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* CaseLabelNode */
|
|
|
|
struct CaseLabelNode : LabelNode {
|
|
Common::SharedPtr<Node> value;
|
|
CaseExpect expect;
|
|
|
|
Common::SharedPtr<CaseLabelNode> nextOr;
|
|
|
|
Common::SharedPtr<CaseLabelNode> nextLabel;
|
|
Common::SharedPtr<BlockNode> block;
|
|
|
|
CaseLabelNode(uint32 offset, Common::SharedPtr<Node> v, CaseExpect e) : LabelNode(kCaseLabelNode, offset), expect(e) {
|
|
value = Common::move(v);
|
|
value->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* OtherwiseNode */
|
|
|
|
struct OtherwiseNode : LabelNode {
|
|
Common::SharedPtr<BlockNode> block;
|
|
|
|
explicit OtherwiseNode(uint32 offset) : LabelNode(kOtherwiseNode, offset) {
|
|
block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
|
|
block->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* EndCaseNode */
|
|
|
|
struct EndCaseNode : LabelNode {
|
|
explicit EndCaseNode(uint32 offset) : LabelNode(kEndCaseNode, offset) {}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* CaseStmtNode */
|
|
|
|
struct CaseStmtNode : StmtNode {
|
|
Common::SharedPtr<Node> value;
|
|
Common::SharedPtr<CaseLabelNode> firstLabel;
|
|
Common::SharedPtr<OtherwiseNode> otherwise;
|
|
|
|
// for use during translation:
|
|
int32 endPos = -1;
|
|
int32 potentialOtherwisePos = -1;
|
|
|
|
CaseStmtNode(uint32 offset, Common::SharedPtr<Node> v) : StmtNode(kCaseStmtNode, offset) {
|
|
value = Common::move(v);
|
|
value->parent = this;
|
|
}
|
|
void addOtherwise(uint32 offset);
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* TellStmtNode */
|
|
|
|
struct TellStmtNode : StmtNode {
|
|
Common::SharedPtr<Node> window;
|
|
Common::SharedPtr<BlockNode> block;
|
|
|
|
TellStmtNode(uint32 offset, Common::SharedPtr<Node> w) : StmtNode(kTellStmtNode, offset) {
|
|
window = Common::move(w);
|
|
window->parent = this;
|
|
block = Common::SharedPtr<BlockNode>(new BlockNode(offset));
|
|
block->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* SoundCmdStmtNode */
|
|
|
|
struct SoundCmdStmtNode : StmtNode {
|
|
Common::String cmd;
|
|
Common::SharedPtr<Node> argList;
|
|
|
|
SoundCmdStmtNode(uint32 offset, Common::String c, Common::SharedPtr<Node> a) : StmtNode(kSoundCmdStmtNode, offset) {
|
|
cmd = c;
|
|
argList = Common::move(a);
|
|
argList->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* PlayCmdStmtNode */
|
|
|
|
struct PlayCmdStmtNode : StmtNode {
|
|
Common::SharedPtr<Node> argList;
|
|
|
|
PlayCmdStmtNode(uint32 offset, Common::SharedPtr<Node> a) : StmtNode(kPlayCmdStmtNode, offset) {
|
|
argList = Common::move(a);
|
|
argList->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* CallNode */
|
|
|
|
struct CallNode : Node {
|
|
Common::String name;
|
|
Common::SharedPtr<Node> argList;
|
|
|
|
CallNode(uint32 offset, Common::String n, Common::SharedPtr<Node> a) : Node(kCallNode, offset) {
|
|
name = n;
|
|
argList = Common::move(a);
|
|
argList->parent = this;
|
|
if (argList->getValue()->type == kDatumArgListNoRet)
|
|
isStatement = true;
|
|
else
|
|
isExpression = true;
|
|
}
|
|
bool noParens() const;
|
|
bool isMemberExpr() const;
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ObjCallNode */
|
|
|
|
struct ObjCallNode : Node {
|
|
Common::String name;
|
|
Common::SharedPtr<Node> argList;
|
|
|
|
ObjCallNode(uint32 offset, Common::String n, Common::SharedPtr<Node> a) : Node(kObjCallNode, offset) {
|
|
name = n;
|
|
argList = Common::move(a);
|
|
argList->parent = this;
|
|
if (argList->getValue()->type == kDatumArgListNoRet)
|
|
isStatement = true;
|
|
else
|
|
isExpression = true;
|
|
}
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ObjCallV4Node */
|
|
|
|
struct ObjCallV4Node : Node {
|
|
Common::SharedPtr<Node> obj;
|
|
Common::SharedPtr<Node> argList;
|
|
|
|
ObjCallV4Node(uint32 offset, Common::SharedPtr<Node> o, Common::SharedPtr<Node> a) : Node(kObjCallV4Node, offset) {
|
|
obj = o;
|
|
argList = Common::move(a);
|
|
argList->parent = this;
|
|
if (argList->getValue()->type == kDatumArgListNoRet)
|
|
isStatement = true;
|
|
else
|
|
isExpression = true;
|
|
}
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* TheExprNode */
|
|
|
|
struct TheExprNode : ExprNode {
|
|
Common::String prop;
|
|
|
|
TheExprNode(uint32 offset, Common::String p) : ExprNode(kTheExprNode, offset), prop(p) {}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* LastStringChunkExprNode */
|
|
|
|
struct LastStringChunkExprNode : ExprNode {
|
|
ChunkExprType type;
|
|
Common::SharedPtr<Node> obj;
|
|
|
|
LastStringChunkExprNode(uint32 offset, ChunkExprType t, Common::SharedPtr<Node> o)
|
|
: ExprNode(kLastStringChunkExprNode, offset), type(t) {
|
|
obj = Common::move(o);
|
|
obj->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* StringChunkCountExprNode */
|
|
|
|
struct StringChunkCountExprNode : ExprNode {
|
|
ChunkExprType type;
|
|
Common::SharedPtr<Node> obj;
|
|
|
|
StringChunkCountExprNode(uint32 offset, ChunkExprType t, Common::SharedPtr<Node> o)
|
|
: ExprNode(kStringChunkCountExprNode, offset), type(t) {
|
|
obj = Common::move(o);
|
|
obj->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* MenuPropExprNode */
|
|
|
|
struct MenuPropExprNode : ExprNode {
|
|
Common::SharedPtr<Node> menuID;
|
|
unsigned int prop;
|
|
|
|
MenuPropExprNode(uint32 offset, Common::SharedPtr<Node> m, unsigned int p)
|
|
: ExprNode(kMenuPropExprNode, offset), prop(p) {
|
|
menuID = Common::move(m);
|
|
menuID->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* MenuItemPropExprNode */
|
|
|
|
struct MenuItemPropExprNode : ExprNode {
|
|
Common::SharedPtr<Node> menuID;
|
|
Common::SharedPtr<Node> itemID;
|
|
unsigned int prop;
|
|
|
|
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;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* SoundPropExprNode */
|
|
|
|
struct SoundPropExprNode : ExprNode {
|
|
Common::SharedPtr<Node> soundID;
|
|
unsigned int prop;
|
|
|
|
SoundPropExprNode(uint32 offset, Common::SharedPtr<Node> s, unsigned int p)
|
|
: ExprNode(kSoundPropExprNode, offset), prop(p) {
|
|
soundID = Common::move(s);
|
|
soundID->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* SpritePropExprNode */
|
|
|
|
struct SpritePropExprNode : ExprNode {
|
|
Common::SharedPtr<Node> spriteID;
|
|
unsigned int prop;
|
|
|
|
SpritePropExprNode(uint32 offset, Common::SharedPtr<Node> s, unsigned int p)
|
|
: ExprNode(kSpritePropExprNode, offset), prop(p) {
|
|
spriteID = Common::move(s);
|
|
spriteID->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ThePropExprNode */
|
|
|
|
struct ThePropExprNode : ExprNode {
|
|
Common::SharedPtr<Node> obj;
|
|
Common::String prop;
|
|
|
|
ThePropExprNode(uint32 offset, Common::SharedPtr<Node> o, Common::String p)
|
|
: ExprNode(kThePropExprNode, offset), prop(p) {
|
|
obj = Common::move(o);
|
|
obj->parent = this;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ObjPropExprNode */
|
|
|
|
struct ObjPropExprNode : ExprNode {
|
|
Common::SharedPtr<Node> obj;
|
|
Common::String prop;
|
|
|
|
ObjPropExprNode(uint32 offset, Common::SharedPtr<Node> o, Common::String p)
|
|
: ExprNode(kObjPropExprNode, offset), prop(p) {
|
|
obj = Common::move(o);
|
|
obj->parent = this;
|
|
}
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ObjBracketExprNode */
|
|
|
|
struct ObjBracketExprNode : ExprNode {
|
|
Common::SharedPtr<Node> obj;
|
|
Common::SharedPtr<Node> prop;
|
|
|
|
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;
|
|
}
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ObjPropIndexExprNode */
|
|
|
|
struct ObjPropIndexExprNode : ExprNode {
|
|
Common::SharedPtr<Node> obj;
|
|
Common::String prop;
|
|
Common::SharedPtr<Node> index;
|
|
Common::SharedPtr<Node> index2;
|
|
|
|
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);
|
|
index->parent = this;
|
|
if (i2) {
|
|
index2 = Common::move(i2);
|
|
index2->parent = this;
|
|
}
|
|
}
|
|
bool hasSpaces(bool dot) override;
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* ExitRepeatStmtNode */
|
|
|
|
struct ExitRepeatStmtNode : StmtNode {
|
|
explicit ExitRepeatStmtNode(uint32 offset) : StmtNode(kExitRepeatStmtNode, offset) {}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* NextRepeatStmtNode */
|
|
|
|
struct NextRepeatStmtNode : StmtNode {
|
|
explicit NextRepeatStmtNode(uint32 offset) : StmtNode(kNextRepeatStmtNode, offset) {}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* PutStmtNode */
|
|
|
|
struct PutStmtNode : StmtNode {
|
|
PutType type;
|
|
Common::SharedPtr<Node> variable;
|
|
Common::SharedPtr<Node> value;
|
|
|
|
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;
|
|
}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* WhenStmtNode */
|
|
|
|
struct WhenStmtNode : StmtNode {
|
|
int event;
|
|
Common::String script;
|
|
|
|
WhenStmtNode(uint32 offset, int e, Common::String s)
|
|
: StmtNode(kWhenStmtNode, offset), event(e), script(s) {}
|
|
void accept(NodeVisitor &visitor) const override;
|
|
};
|
|
|
|
/* NewObjNode */
|
|
|
|
struct NewObjNode : ExprNode {
|
|
Common::String objType;
|
|
Common::SharedPtr<Node> objArgs;
|
|
|
|
NewObjNode(uint32 offset, Common::String o, Common::SharedPtr<Node> args) : ExprNode(kNewObjNode, offset), objType(o), objArgs(args) {}
|
|
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 */
|
|
|
|
struct AST {
|
|
Common::SharedPtr<HandlerNode> root;
|
|
BlockNode *currentBlock;
|
|
|
|
AST(uint32 offset, Handler *handler){
|
|
root = Common::SharedPtr<HandlerNode>(new HandlerNode(offset, handler));
|
|
currentBlock = root->block.get();
|
|
}
|
|
|
|
void addStatement(Common::SharedPtr<Node> statement);
|
|
void enterBlock(BlockNode *block);
|
|
void exitBlock();
|
|
};
|
|
|
|
} // namespace LingoDec
|
|
|
|
#endif // LINGODEC_AST_H
|