|
|
|
@ -44,7 +44,7 @@ enum class ASTZipperType : u32 { |
|
|
|
|
|
|
|
class ASTZipper final { |
|
|
|
public: |
|
|
|
ASTZipper(); |
|
|
|
explicit ASTZipper(); |
|
|
|
|
|
|
|
void Init(ASTNode first, ASTNode parent); |
|
|
|
|
|
|
|
@ -71,74 +71,74 @@ public: |
|
|
|
|
|
|
|
class ASTProgram { |
|
|
|
public: |
|
|
|
ASTProgram() : nodes{} {}; |
|
|
|
ASTZipper nodes; |
|
|
|
explicit ASTProgram() = default; |
|
|
|
ASTZipper nodes{}; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTIfThen { |
|
|
|
public: |
|
|
|
ASTIfThen(Expr condition) : condition(condition), nodes{} {} |
|
|
|
explicit ASTIfThen(Expr condition) : condition(condition) {} |
|
|
|
Expr condition; |
|
|
|
ASTZipper nodes; |
|
|
|
ASTZipper nodes{}; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTIfElse { |
|
|
|
public: |
|
|
|
ASTIfElse() : nodes{} {} |
|
|
|
ASTZipper nodes; |
|
|
|
explicit ASTIfElse() = default; |
|
|
|
ASTZipper nodes{}; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTBlockEncoded { |
|
|
|
public: |
|
|
|
ASTBlockEncoded(u32 start, u32 end) : start{start}, end{end} {} |
|
|
|
explicit ASTBlockEncoded(u32 start, u32 end) : start{start}, end{end} {} |
|
|
|
u32 start; |
|
|
|
u32 end; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTBlockDecoded { |
|
|
|
public: |
|
|
|
ASTBlockDecoded(NodeBlock& new_nodes) : nodes(std::move(new_nodes)) {} |
|
|
|
explicit ASTBlockDecoded(NodeBlock& new_nodes) : nodes(std::move(new_nodes)) {} |
|
|
|
NodeBlock nodes; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTVarSet { |
|
|
|
public: |
|
|
|
ASTVarSet(u32 index, Expr condition) : index{index}, condition{condition} {} |
|
|
|
explicit ASTVarSet(u32 index, Expr condition) : index{index}, condition{condition} {} |
|
|
|
u32 index; |
|
|
|
Expr condition; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTLabel { |
|
|
|
public: |
|
|
|
ASTLabel(u32 index) : index{index} {} |
|
|
|
explicit ASTLabel(u32 index) : index{index} {} |
|
|
|
u32 index; |
|
|
|
bool unused{}; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTGoto { |
|
|
|
public: |
|
|
|
ASTGoto(Expr condition, u32 label) : condition{condition}, label{label} {} |
|
|
|
explicit ASTGoto(Expr condition, u32 label) : condition{condition}, label{label} {} |
|
|
|
Expr condition; |
|
|
|
u32 label; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTDoWhile { |
|
|
|
public: |
|
|
|
ASTDoWhile(Expr condition) : condition(condition), nodes{} {} |
|
|
|
explicit ASTDoWhile(Expr condition) : condition(condition) {} |
|
|
|
Expr condition; |
|
|
|
ASTZipper nodes; |
|
|
|
ASTZipper nodes{}; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTReturn { |
|
|
|
public: |
|
|
|
ASTReturn(Expr condition, bool kills) : condition{condition}, kills{kills} {} |
|
|
|
explicit ASTReturn(Expr condition, bool kills) : condition{condition}, kills{kills} {} |
|
|
|
Expr condition; |
|
|
|
bool kills; |
|
|
|
}; |
|
|
|
|
|
|
|
class ASTBreak { |
|
|
|
public: |
|
|
|
ASTBreak(Expr condition) : condition{condition} {} |
|
|
|
explicit ASTBreak(Expr condition) : condition{condition} {} |
|
|
|
Expr condition; |
|
|
|
}; |
|
|
|
|
|
|
|
@ -177,11 +177,11 @@ public: |
|
|
|
return &data; |
|
|
|
} |
|
|
|
|
|
|
|
ASTNode GetNext() { |
|
|
|
ASTNode GetNext() const { |
|
|
|
return next; |
|
|
|
} |
|
|
|
|
|
|
|
ASTNode GetPrevious() { |
|
|
|
ASTNode GetPrevious() const { |
|
|
|
return previous; |
|
|
|
} |
|
|
|
|
|
|
|
@ -189,12 +189,12 @@ public: |
|
|
|
return *manager; |
|
|
|
} |
|
|
|
|
|
|
|
u32 GetGotoLabel() const { |
|
|
|
std::optional<u32> GetGotoLabel() const { |
|
|
|
auto inner = std::get_if<ASTGoto>(&data); |
|
|
|
if (inner) { |
|
|
|
return inner->label; |
|
|
|
return {inner->label}; |
|
|
|
} |
|
|
|
return -1; |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
Expr GetGotoCondition() const { |
|
|
|
@ -220,12 +220,12 @@ public: |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
u32 GetLabelIndex() const { |
|
|
|
std::optional<u32> GetLabelIndex() const { |
|
|
|
auto inner = std::get_if<ASTLabel>(&data); |
|
|
|
if (inner) { |
|
|
|
return inner->index; |
|
|
|
return {inner->index}; |
|
|
|
} |
|
|
|
return -1; |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
Expr GetIfCondition() const { |
|
|
|
@ -290,7 +290,7 @@ private: |
|
|
|
friend class ASTZipper; |
|
|
|
|
|
|
|
ASTData data; |
|
|
|
ASTNode parent; |
|
|
|
ASTNode parent{}; |
|
|
|
ASTNode next{}; |
|
|
|
ASTNode previous{}; |
|
|
|
ASTZipper* manager{}; |
|
|
|
@ -327,13 +327,18 @@ public: |
|
|
|
|
|
|
|
void SanityCheck(); |
|
|
|
|
|
|
|
void Clear(); |
|
|
|
|
|
|
|
bool IsFullyDecompiled() const { |
|
|
|
if (full_decompile) { |
|
|
|
return gotos.size() == 0; |
|
|
|
} else { |
|
|
|
for (ASTNode goto_node : gotos) { |
|
|
|
u32 label_index = goto_node->GetGotoLabel(); |
|
|
|
ASTNode glabel = labels[label_index]; |
|
|
|
auto label_index = goto_node->GetGotoLabel(); |
|
|
|
if (!label_index) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
ASTNode glabel = labels[*label_index]; |
|
|
|
if (IsBackwardsJump(goto_node, glabel)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
@ -346,8 +351,6 @@ public: |
|
|
|
return main_node; |
|
|
|
} |
|
|
|
|
|
|
|
void Clear(); |
|
|
|
|
|
|
|
u32 GetVariables() const { |
|
|
|
return variables; |
|
|
|
} |
|
|
|
@ -372,9 +375,7 @@ private: |
|
|
|
void MoveOutward(ASTNode goto_node); |
|
|
|
|
|
|
|
u32 NewVariable() { |
|
|
|
u32 new_var = variables; |
|
|
|
variables++; |
|
|
|
return new_var; |
|
|
|
return variables++; |
|
|
|
} |
|
|
|
|
|
|
|
bool full_decompile{}; |
|
|
|
|