refactor(global): headers & arc module (#86)
This commit is contained in:
208
include/xsk/arc/common/assembly.hpp
Normal file
208
include/xsk/arc/common/assembly.hpp
Normal file
@ -0,0 +1,208 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
constexpr usize opcode_count = 143;
|
||||
|
||||
enum class opcode : u8
|
||||
{
|
||||
OP_Invalid,
|
||||
OP_End,
|
||||
OP_Return,
|
||||
OP_GetUndefined,
|
||||
OP_GetZero,
|
||||
OP_GetByte,
|
||||
OP_GetNegByte,
|
||||
OP_GetUnsignedShort,
|
||||
OP_GetNegUnsignedShort,
|
||||
OP_GetInteger,
|
||||
OP_GetFloat,
|
||||
OP_GetString,
|
||||
OP_GetIString,
|
||||
OP_GetVector,
|
||||
OP_GetLevelObject,
|
||||
OP_GetAnimObject,
|
||||
OP_GetSelf,
|
||||
OP_GetLevel,
|
||||
OP_GetGame,
|
||||
OP_GetAnim,
|
||||
OP_GetAnimation,
|
||||
OP_GetGameRef,
|
||||
OP_GetFunction,
|
||||
OP_CreateLocalVariable,
|
||||
OP_SafeCreateLocalVariables,
|
||||
OP_RemoveLocalVariables,
|
||||
OP_EvalLocalVariableCached,
|
||||
OP_EvalArray,
|
||||
OP_EvalLocalArrayRefCached,
|
||||
OP_EvalArrayRef,
|
||||
OP_ClearArray,
|
||||
OP_EmptyArray,
|
||||
OP_GetSelfObject,
|
||||
OP_EvalFieldVariable,
|
||||
OP_EvalFieldVariableRef,
|
||||
OP_ClearFieldVariable,
|
||||
OP_SafeSetVariableFieldCached,
|
||||
OP_SafeSetWaittillVariableFieldCached,
|
||||
OP_ClearParams,
|
||||
OP_CheckClearParams,
|
||||
OP_EvalLocalVariableRefCached,
|
||||
OP_SetVariableField,
|
||||
OP_CallBuiltin,
|
||||
OP_CallBuiltinMethod,
|
||||
OP_Wait,
|
||||
OP_WaitTillFrameEnd,
|
||||
OP_PreScriptCall,
|
||||
OP_ScriptFunctionCall,
|
||||
OP_ScriptFunctionCallPointer,
|
||||
OP_ScriptMethodCall,
|
||||
OP_ScriptMethodCallPointer,
|
||||
OP_ScriptThreadCall,
|
||||
OP_ScriptThreadCallPointer,
|
||||
OP_ScriptMethodThreadCall,
|
||||
OP_ScriptMethodThreadCallPointer,
|
||||
OP_DecTop,
|
||||
OP_CastFieldObject,
|
||||
OP_CastBool,
|
||||
OP_BoolNot,
|
||||
OP_BoolComplement,
|
||||
OP_JumpOnFalse,
|
||||
OP_JumpOnTrue,
|
||||
OP_JumpOnFalseExpr,
|
||||
OP_JumpOnTrueExpr,
|
||||
OP_Jump,
|
||||
OP_JumpBack,
|
||||
OP_Inc,
|
||||
OP_Dec,
|
||||
OP_Bit_Or,
|
||||
OP_Bit_Xor,
|
||||
OP_Bit_And,
|
||||
OP_Equal,
|
||||
OP_NotEqual,
|
||||
OP_LessThan,
|
||||
OP_GreaterThan,
|
||||
OP_LessThanOrEqualTo,
|
||||
OP_GreaterThanOrEqualTo,
|
||||
OP_ShiftLeft,
|
||||
OP_ShiftRight,
|
||||
OP_Plus,
|
||||
OP_Minus,
|
||||
OP_Multiply,
|
||||
OP_Divide,
|
||||
OP_Modulus,
|
||||
OP_SizeOf,
|
||||
OP_WaitTillMatch,
|
||||
OP_WaitTill,
|
||||
OP_Notify,
|
||||
OP_EndOn,
|
||||
OP_VoidCodePos,
|
||||
OP_Switch,
|
||||
OP_EndSwitch,
|
||||
OP_Vector,
|
||||
OP_GetHash,
|
||||
OP_RealWait,
|
||||
OP_VectorConstant,
|
||||
OP_IsDefined,
|
||||
OP_VectorScale,
|
||||
OP_AnglesToUp,
|
||||
OP_AnglesToRight,
|
||||
OP_AnglesToForward,
|
||||
OP_AngleClamp180,
|
||||
OP_VectorToAngles,
|
||||
OP_Abs,
|
||||
OP_GetTime,
|
||||
OP_GetDvar,
|
||||
OP_GetDvarInt,
|
||||
OP_GetDvarFloat,
|
||||
OP_GetDvarVector,
|
||||
OP_GetDvarColorRed,
|
||||
OP_GetDvarColorGreen,
|
||||
OP_GetDvarColorBlue,
|
||||
OP_GetDvarColorAlpha,
|
||||
OP_FirstArrayKey,
|
||||
OP_NextArrayKey,
|
||||
OP_ProfileStart,
|
||||
OP_ProfileStop,
|
||||
OP_SafeDecTop,
|
||||
OP_Nop,
|
||||
OP_Abort,
|
||||
OP_Object,
|
||||
OP_ThreadObject,
|
||||
OP_EvalLocalVariable,
|
||||
OP_EvalLocalVariableRef,
|
||||
OP_DevblockBegin,
|
||||
OP_DevblockEnd,
|
||||
OP_EvalLocalVariableCachedDebug,
|
||||
OP_EvalLocalVariableRefCachedDebug,
|
||||
OP_LevelEvalFieldVariable,
|
||||
OP_LevelEvalFieldVariableRef,
|
||||
OP_SelfEvalFieldVariable,
|
||||
OP_SelfEvalFieldVariableRef,
|
||||
OP_GetWorld,
|
||||
OP_GetWorldObject,
|
||||
OP_GetClasses,
|
||||
OP_GetClassesObject,
|
||||
OP_New,
|
||||
OP_ScriptFunctionCallClass,
|
||||
OP_ScriptThreadCallClass,
|
||||
OP_GetUintptr,
|
||||
OP_SuperEqual,
|
||||
OP_SuperNotEqual,
|
||||
OP_GetAPIFunction,
|
||||
OP_Count,
|
||||
};
|
||||
|
||||
struct instruction
|
||||
{
|
||||
using ptr = std::unique_ptr<instruction>;
|
||||
|
||||
u32 index;
|
||||
u32 size;
|
||||
opcode opcode;
|
||||
std::vector<std::string> data;
|
||||
};
|
||||
|
||||
struct function
|
||||
{
|
||||
using ptr = std::unique_ptr<function>;
|
||||
|
||||
u32 index;
|
||||
u32 size;
|
||||
u8 params;
|
||||
u8 flags;
|
||||
std::string name;
|
||||
std::string space;
|
||||
std::vector<instruction::ptr> instructions;
|
||||
std::unordered_map<u32, std::string> labels;
|
||||
};
|
||||
|
||||
struct assembly
|
||||
{
|
||||
using ptr = std::unique_ptr<assembly>;
|
||||
|
||||
std::vector<std::string> includes;
|
||||
std::vector<function::ptr> functions;
|
||||
};
|
||||
|
||||
inline auto make_instruction() -> std::unique_ptr<instruction>
|
||||
{
|
||||
return std::unique_ptr<instruction>(new instruction);
|
||||
}
|
||||
|
||||
inline auto make_function() -> std::unique_ptr<function>
|
||||
{
|
||||
return std::unique_ptr<function>(new function);
|
||||
}
|
||||
|
||||
inline auto make_assembly() -> std::unique_ptr<assembly>
|
||||
{
|
||||
return std::unique_ptr<assembly>(new assembly);
|
||||
}
|
||||
|
||||
} // namespace xsk::arc
|
119
include/xsk/arc/common/asset.hpp
Normal file
119
include/xsk/arc/common/asset.hpp
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
constexpr usize header_size_32 = 64;
|
||||
constexpr usize header_size_64 = 72;
|
||||
|
||||
struct header
|
||||
{
|
||||
u64 magic;
|
||||
u32 source_crc;
|
||||
u32 include_offset;
|
||||
u32 animtree_offset;
|
||||
u32 cseg_offset;
|
||||
u32 stringtablefixup_offset;
|
||||
u32 devblock_stringtablefixup_offset;
|
||||
u32 exports_offset;
|
||||
u32 imports_offset;
|
||||
u32 fixup_offset;
|
||||
u32 profile_offset;
|
||||
u32 cseg_size;
|
||||
u32 name;
|
||||
u16 stringtablefixup_count;
|
||||
u16 exports_count;
|
||||
u16 imports_count;
|
||||
u16 fixup_count;
|
||||
u16 profile_count;
|
||||
u16 devblock_stringtablefixup_count;
|
||||
u8 include_count;
|
||||
u8 animtree_count;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
enum class import_flags : u8
|
||||
{
|
||||
none = 0,
|
||||
func_reference = 1,
|
||||
func_call = 2,
|
||||
func_call_thread = 3,
|
||||
meth_call = 4,
|
||||
meth_call_thread = 5,
|
||||
developer = 0x10,
|
||||
unk = 0x20, // T7, T8, T9
|
||||
};
|
||||
|
||||
struct import_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<import_ref>;
|
||||
|
||||
std::string space;
|
||||
std::string name;
|
||||
u8 params;
|
||||
u8 flags;
|
||||
std::vector<u32> refs;
|
||||
};
|
||||
|
||||
enum class export_flags : u8
|
||||
{
|
||||
export_none = 0x00,
|
||||
export_public = 0x01,
|
||||
export_autoexec = 0x02,
|
||||
export_private = 0x04,
|
||||
export_codecall = 0x08,
|
||||
export_private2 = 0x10,
|
||||
export_varargs = 0x20,
|
||||
};
|
||||
|
||||
struct export_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<export_ref>;
|
||||
|
||||
std::string space;
|
||||
std::string name;
|
||||
u32 checksum;
|
||||
u32 offset;
|
||||
u32 size;
|
||||
u8 params;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
enum class string_type : u8
|
||||
{
|
||||
literal = 0,
|
||||
canonical = 1,
|
||||
};
|
||||
|
||||
struct string_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<string_ref>;
|
||||
|
||||
std::string name;
|
||||
u8 type;
|
||||
std::vector<u32> refs;
|
||||
};
|
||||
|
||||
struct animation_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<animation_ref>;
|
||||
|
||||
std::string name;
|
||||
u32 ref;
|
||||
};
|
||||
|
||||
struct animtree_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<animtree_ref>;
|
||||
|
||||
std::string name;
|
||||
std::vector<u32> refs;
|
||||
std::vector<animation_ref> anims;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
1897
include/xsk/arc/common/ast.hpp
Normal file
1897
include/xsk/arc/common/ast.hpp
Normal file
File diff suppressed because it is too large
Load Diff
20
include/xsk/arc/common/buffer.hpp
Normal file
20
include/xsk/arc/common/buffer.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
struct buffer
|
||||
{
|
||||
u8 const* data;
|
||||
usize const size;
|
||||
|
||||
buffer() : data{ nullptr }, size{ 0 } {}
|
||||
buffer(u8 const* data, usize size) : data{ data }, size{ size } {}
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
47
include/xsk/arc/common/exception.hpp
Normal file
47
include/xsk/arc/common/exception.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
error(std::string const& what);
|
||||
};
|
||||
|
||||
class asm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
asm_error(std::string const& what);
|
||||
};
|
||||
|
||||
class disasm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
disasm_error(std::string const& what);
|
||||
};
|
||||
|
||||
class ppr_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
ppr_error(location const& loc, std::string const& what);
|
||||
};
|
||||
|
||||
class comp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
comp_error(location const& loc, std::string const& what);
|
||||
};
|
||||
|
||||
class decomp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
decomp_error(std::string const& what);
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
177
include/xsk/arc/common/location.hpp
Normal file
177
include/xsk/arc/common/location.hpp
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class position
|
||||
{
|
||||
public:
|
||||
typedef const std::string filename_type;
|
||||
typedef int counter_type;
|
||||
|
||||
filename_type *filename;
|
||||
counter_type line;
|
||||
counter_type column;
|
||||
|
||||
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
: filename(f), line(l), column(c) {}
|
||||
|
||||
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
filename = fn;
|
||||
line = l;
|
||||
column = c;
|
||||
}
|
||||
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
column = 1;
|
||||
line = add_(line, count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
column = add_(column, count, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
||||
{
|
||||
return lhs + rhs < min ? min : lhs + rhs;
|
||||
}
|
||||
};
|
||||
|
||||
inline position& operator+=(position &res, position::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline position operator+(position res, position::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
inline position& operator-=(position &res, position::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
inline position operator-(position res, position::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const position &pos)
|
||||
{
|
||||
if (pos.filename)
|
||||
ostr << *pos.filename << ':';
|
||||
return ostr << pos.line << '.' << pos.column;
|
||||
}
|
||||
|
||||
class location
|
||||
{
|
||||
public:
|
||||
typedef position::filename_type filename_type;
|
||||
typedef position::counter_type counter_type;
|
||||
|
||||
position begin;
|
||||
position end;
|
||||
|
||||
location(const position &b, const position &e)
|
||||
: begin(b), end(e) {}
|
||||
|
||||
explicit location(const position &p = position())
|
||||
: begin(p), end(p) {}
|
||||
|
||||
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
||||
: begin(f, l, c), end(f, l, c) {}
|
||||
|
||||
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
begin.initialize(f, l, c);
|
||||
end = begin;
|
||||
}
|
||||
|
||||
void step()
|
||||
{
|
||||
begin = end;
|
||||
}
|
||||
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
end.lines(count);
|
||||
}
|
||||
|
||||
auto print() const -> std::string
|
||||
{
|
||||
return fmt::format("{}:{}:{}", *begin.filename, begin.line, begin.column);
|
||||
}
|
||||
|
||||
auto label() const -> std::string
|
||||
{
|
||||
return fmt::format("loc_{:X}", begin.line);
|
||||
}
|
||||
};
|
||||
|
||||
inline location& operator+=(location &res, const location &end)
|
||||
{
|
||||
res.end = end.end;
|
||||
return res;
|
||||
}
|
||||
|
||||
inline location operator+(location res, const location &end)
|
||||
{
|
||||
return res += end;
|
||||
}
|
||||
|
||||
inline location& operator+=(location &res, location::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline location operator+(location res, location::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
inline location& operator-=(location &res, location::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
inline location operator-(location res, location::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const location &loc)
|
||||
{
|
||||
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
||||
ostr << loc.begin;
|
||||
if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename))
|
||||
ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.line < loc.end.line)
|
||||
ostr << '-' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.column < end_col)
|
||||
ostr << '-' << end_col;
|
||||
return ostr;
|
||||
}
|
||||
|
||||
} // namespace xsk::arc
|
97
include/xsk/arc/common/types.hpp
Normal file
97
include/xsk/arc/common/types.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "asset.hpp"
|
||||
#include "assembly.hpp"
|
||||
#include "buffer.hpp"
|
||||
#include "location.hpp"
|
||||
#include "exception.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
enum class instance : u8
|
||||
{
|
||||
server,
|
||||
client,
|
||||
};
|
||||
|
||||
enum class build : u8
|
||||
{
|
||||
dev,
|
||||
prod,
|
||||
};
|
||||
|
||||
enum class endian : u8
|
||||
{
|
||||
little,
|
||||
big,
|
||||
};
|
||||
|
||||
enum class system : u8
|
||||
{
|
||||
pc,
|
||||
ps3,
|
||||
xb2,
|
||||
};
|
||||
|
||||
enum class engine : u8
|
||||
{
|
||||
t6,
|
||||
t7,
|
||||
t8,
|
||||
t9,
|
||||
};
|
||||
|
||||
struct props
|
||||
{
|
||||
enum values : u32
|
||||
{
|
||||
none = 0 << 0,
|
||||
version2 = 1 << 0,
|
||||
};
|
||||
|
||||
props(values value) : value_(value) {}
|
||||
operator values() { return value_; }
|
||||
operator bool() { return value_ != values::none; }
|
||||
props::values operator|(props::values rhs) const { return static_cast<props::values>(value_ | rhs); }
|
||||
props::values operator&(props::values rhs) const { return static_cast<props::values>(value_ & rhs); }
|
||||
|
||||
friend props::values operator|(props::values lhs, props::values rhs)
|
||||
{
|
||||
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) | static_cast<std::underlying_type<props::values>::type>(rhs));
|
||||
}
|
||||
|
||||
friend props::values operator&(props::values lhs, props::values rhs)
|
||||
{
|
||||
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) & static_cast<std::underlying_type<props::values>::type>(rhs));
|
||||
}
|
||||
|
||||
private:
|
||||
values value_;
|
||||
};
|
||||
|
||||
enum class switch_type
|
||||
{
|
||||
none,
|
||||
integer,
|
||||
string,
|
||||
};
|
||||
|
||||
struct locjmp
|
||||
{
|
||||
std::string end;
|
||||
std::string cnt;
|
||||
std::string brk;
|
||||
bool is_dev;
|
||||
};
|
||||
|
||||
// fordward decl for modules ref
|
||||
class context;
|
||||
|
||||
} // namespace xsk::arc
|
69
include/xsk/arc/context.hpp
Normal file
69
include/xsk/arc/context.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
#include "source.hpp"
|
||||
#include "disassembler.hpp"
|
||||
#include "decompiler.hpp"
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class context
|
||||
{
|
||||
public:
|
||||
using fs_callback = std::function<std::vector<u8>(std::string const&)>;
|
||||
|
||||
context(props props, engine engine, endian endian, system system, u64 magic);
|
||||
|
||||
auto props() const -> props { return props_; }
|
||||
auto build() const -> build { return build_; }
|
||||
auto engine() const -> engine { return engine_; }
|
||||
auto endian() const -> endian { return endian_; }
|
||||
auto system() const -> system { return system_; }
|
||||
auto instance() const -> instance { return instance_; }
|
||||
auto magic() const -> u64 { return magic_; }
|
||||
auto source() -> source& { return source_; }
|
||||
auto disassembler() -> disassembler& { return disassembler_; }
|
||||
auto decompiler() -> decompiler& { return decompiler_; }
|
||||
|
||||
auto init(arc::build build, fs_callback callback) -> void;
|
||||
auto cleanup() -> void;
|
||||
auto engine_name() const -> std::string_view;
|
||||
|
||||
auto opcode_size(opcode op) const -> u32;
|
||||
auto opcode_id(opcode op) const -> u8;
|
||||
auto opcode_name(opcode op) const -> std::string;
|
||||
auto opcode_enum(std::string const& name) const -> opcode;
|
||||
auto opcode_enum(u16 id) const -> opcode;
|
||||
auto dvar_id(std::string const& name) const -> u32;
|
||||
auto dvar_name(u32 id) const -> std::string;
|
||||
auto hash_id(std::string const& name) const -> u32;
|
||||
auto hash_name(u32 id) const -> std::string;
|
||||
|
||||
protected:
|
||||
arc::props props_;
|
||||
arc::build build_;
|
||||
arc::engine engine_;
|
||||
arc::endian endian_;
|
||||
arc::system system_;
|
||||
arc::instance instance_;
|
||||
u64 magic_;
|
||||
arc::source source_;
|
||||
arc::disassembler disassembler_;
|
||||
arc::decompiler decompiler_;
|
||||
|
||||
fs_callback fs_callback_;
|
||||
std::unordered_map<opcode, std::string_view> opcode_map_;
|
||||
std::unordered_map<std::string_view, opcode> opcode_map_rev_;
|
||||
std::unordered_map<u16, opcode> code_map_;
|
||||
std::unordered_map<opcode, u8> code_map_rev_;
|
||||
std::unordered_map<u32, std::string_view> dvar_map_;
|
||||
std::unordered_map<u32, std::string_view> hash_map_;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
107
include/xsk/arc/decompiler.hpp
Normal file
107
include/xsk/arc/decompiler.hpp
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class decompiler
|
||||
{
|
||||
context const* ctx_;
|
||||
program::ptr program_;
|
||||
decl_function::ptr func_;
|
||||
std::unordered_set<std::string> vars_;
|
||||
std::unordered_map<u32, std::string> labels_;
|
||||
std::vector<std::string> expr_labels_;
|
||||
std::vector<std::string> tern_labels_;
|
||||
std::vector<std::string> locals_;
|
||||
std::stack<node::ptr> stack_;
|
||||
locjmp locs_;
|
||||
bool in_waittill_;
|
||||
bool retbool_;
|
||||
|
||||
public:
|
||||
decompiler(context const* ctx);
|
||||
auto decompile(assembly const& data) -> program::ptr;
|
||||
|
||||
private:
|
||||
auto decompile_function(function const& func) -> void;
|
||||
auto decompile_instruction(instruction const& inst, bool last) -> void;
|
||||
auto decompile_expressions(instruction const& inst) -> void;
|
||||
auto decompile_statements(stmt_list& stm) -> void;
|
||||
auto decompile_infinites(stmt_list& stm) -> void;
|
||||
auto decompile_loops(stmt_list& stm) -> void;
|
||||
auto decompile_switches(stmt_list& stm) -> void;
|
||||
auto decompile_ifelses(stmt_list& stm) -> void;
|
||||
auto decompile_aborts(stmt_list& stm) -> void;
|
||||
auto decompile_devblocks(stmt_list& stm) -> void;
|
||||
auto decompile_if(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_ifelse(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_inf(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_loop(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_while(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_dowhile(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_for(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_foreach(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_switch(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto find_location_reference(stmt_list const& stm, usize begin, usize end, std::string const& loc) -> bool;
|
||||
auto find_location_index(stmt_list const& stm, std::string const& loc) -> usize;
|
||||
auto last_location_index(stmt_list const& stm, usize index) -> bool;
|
||||
auto lvalues_match(stmt_assign const& stm1, stmt_assign const& stm2) -> bool;
|
||||
auto resolve_label(std::string const& name) -> u32;
|
||||
auto process_function(decl_function& func) -> void;
|
||||
auto process_stmt(stmt& stm) -> void;
|
||||
auto process_stmt_list(stmt_list& stm) -> void;
|
||||
auto process_stmt_comp(stmt_comp& stm) -> void;
|
||||
auto process_stmt_dev(stmt_dev& stm) -> void;
|
||||
auto process_stmt_expr(stmt_expr& stm) -> void;
|
||||
auto process_stmt_call(stmt_call& stm) -> void;
|
||||
auto process_stmt_assign(stmt_assign& stm) -> void;
|
||||
auto process_stmt_endon(stmt_endon& stm) -> void;
|
||||
auto process_stmt_notify(stmt_notify& stm) -> void;
|
||||
auto process_stmt_realwait(stmt_realwait& stm) -> void;
|
||||
auto process_stmt_wait(stmt_wait& stm) -> void;
|
||||
auto process_stmt_waittill(stmt_waittill& stm) -> void;
|
||||
auto process_stmt_waittillmatch(stmt_waittillmatch& stm) -> void;
|
||||
auto process_stmt_if(stmt_if& stm) -> void;
|
||||
auto process_stmt_ifelse(stmt_ifelse& stm) -> void;
|
||||
auto process_stmt_while(stmt_while& stm) -> void;
|
||||
auto process_stmt_dowhile(stmt_dowhile& stm) -> void;
|
||||
auto process_stmt_for(stmt_for& stm) -> void;
|
||||
auto process_stmt_foreach(stmt_foreach& stm) -> void;
|
||||
auto process_stmt_switch(stmt_switch& stm) -> void;
|
||||
auto process_stmt_break(stmt_break& stm) -> void;
|
||||
auto process_stmt_continue(stmt_continue& stm) -> void;
|
||||
auto process_stmt_return(stmt_return& stm) -> void;
|
||||
auto process_expr(expr& exp) -> void;
|
||||
auto process_expr_assign(expr_assign::ptr& exp) -> void;
|
||||
auto process_expr_increment(expr_increment& exp) -> void;
|
||||
auto process_expr_decrement(expr_decrement& exp) -> void;
|
||||
auto process_expr_ternary(expr_ternary& exp) -> void;
|
||||
auto process_expr_binary(expr_binary& exp) -> void;
|
||||
auto process_expr_and(expr_and& exp) -> void;
|
||||
auto process_expr_or(expr_or& exp) -> void;
|
||||
auto process_expr_complement(expr_complement& exp) -> void;
|
||||
auto process_expr_not(expr_not& exp) -> void;
|
||||
auto process_expr_call(expr_call& exp) -> void;
|
||||
auto process_expr_method(expr_method& exp) -> void;
|
||||
auto process_expr_call_member(expr_member& exp) -> void;
|
||||
auto process_expr_call_pointer(expr_pointer& exp) -> void;
|
||||
auto process_expr_call_function(expr_function& exp) -> void;
|
||||
auto process_expr_method_pointer(expr_pointer& exp, expr& obj) -> void;
|
||||
auto process_expr_method_function(expr_function& exp, expr& obj) -> void;
|
||||
auto process_expr_parameters(expr_parameters& exp) -> void;
|
||||
auto process_expr_arguments(expr_arguments& exp) -> void;
|
||||
auto process_expr_size(expr_size& exp) -> void;
|
||||
auto process_expr_array(expr_array& exp) -> void;
|
||||
auto process_expr_field(expr_field& exp) -> void;
|
||||
auto process_expr_vector(expr_vector& exp) -> void;
|
||||
auto process_expr_identifier(expr_identifier& exp) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
44
include/xsk/arc/disassembler.hpp
Normal file
44
include/xsk/arc/disassembler.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
#include "xsk/utils/reader.hpp"
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class disassembler
|
||||
{
|
||||
context const* ctx_;
|
||||
function::ptr func_;
|
||||
assembly::ptr assembly_;
|
||||
utils::reader script_;
|
||||
std::map<u32, import_ref::ptr> import_refs_;
|
||||
std::map<u32, string_ref::ptr> string_refs_;
|
||||
std::map<u32, animtree_ref::ptr> anim_refs_;
|
||||
|
||||
public:
|
||||
disassembler(context const* ctx);
|
||||
auto disassemble(buffer const& data) -> assembly::ptr;
|
||||
auto disassemble(std::vector<u8> const& data) -> assembly::ptr;
|
||||
auto disassemble(u8 const* data, usize data_size) -> assembly::ptr;
|
||||
|
||||
private:
|
||||
auto disassemble_function(function& func) -> void;
|
||||
auto disassemble_instruction(instruction& inst) -> void;
|
||||
auto disassemble_name(instruction& inst) -> void;
|
||||
auto disassemble_params(instruction& inst) -> void;
|
||||
auto disassemble_import(instruction& inst) -> void;
|
||||
auto disassemble_string(instruction& inst) -> void;
|
||||
auto disassemble_animtree(instruction& inst) -> void;
|
||||
auto disassemble_animation(instruction& inst) -> void;
|
||||
auto disassemble_jump(instruction& inst) -> void;
|
||||
auto disassemble_switch(instruction& inst) -> void;
|
||||
auto disassemble_end_switch(instruction& inst) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
24
include/xsk/arc/engine/t6.hpp
Normal file
24
include/xsk/arc/engine/t6.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/arc/context.hpp"
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
constexpr usize code_count = 125;
|
||||
constexpr usize dvar_count = 3326;
|
||||
constexpr u64 header_magic = 0x06000A0D43534780;
|
||||
|
||||
class context : public arc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::t6
|
25
include/xsk/arc/engine/t7.hpp
Normal file
25
include/xsk/arc/engine/t7.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/arc/context.hpp"
|
||||
|
||||
namespace xsk::arc::t7
|
||||
{
|
||||
|
||||
constexpr usize code_count = 8192;
|
||||
constexpr usize dvar_count = 0;
|
||||
constexpr usize hash_count = 178717;
|
||||
constexpr u64 header_magic = 0x1C000A0D43534780;
|
||||
|
||||
class context : public arc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t7
|
25
include/xsk/arc/engine/t8.hpp
Normal file
25
include/xsk/arc/engine/t8.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/arc/context.hpp"
|
||||
|
||||
namespace xsk::arc::t8
|
||||
{
|
||||
|
||||
constexpr usize code_count = 0;
|
||||
constexpr usize dvar_count = 0;
|
||||
constexpr usize hash_count = 0;
|
||||
constexpr u64 header_magic = 0;
|
||||
|
||||
class context : public arc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t8
|
25
include/xsk/arc/engine/t9.hpp
Normal file
25
include/xsk/arc/engine/t9.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/arc/context.hpp"
|
||||
|
||||
namespace xsk::arc::t9
|
||||
{
|
||||
|
||||
constexpr usize code_count = 0;
|
||||
constexpr usize dvar_count = 0;
|
||||
constexpr usize hash_count = 0;
|
||||
constexpr u64 header_magic = 0;
|
||||
|
||||
class context : public arc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t9
|
170
include/xsk/arc/source.hpp
Normal file
170
include/xsk/arc/source.hpp
Normal file
@ -0,0 +1,170 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class source
|
||||
{
|
||||
context* ctx_;
|
||||
std::vector<u8> buf_;
|
||||
u32 indent_;
|
||||
|
||||
public:
|
||||
source(context* ctx);
|
||||
auto dump(assembly const& data) -> std::vector<u8>;
|
||||
auto dump(program const& data) -> std::vector<u8>;
|
||||
|
||||
private:
|
||||
auto dump_assembly(assembly const& data) -> void;
|
||||
auto dump_function(function const& func) -> void;
|
||||
auto dump_instruction(instruction const& inst) -> void;
|
||||
auto dump_program(program const& data) -> void;
|
||||
auto dump_include(include const& inc) -> void;
|
||||
auto dump_decl(decl const& dec) -> void;
|
||||
auto dump_decl_dev_begin(decl_dev_begin const& dec) -> void;
|
||||
auto dump_decl_dev_end(decl_dev_end const& dec) -> void;
|
||||
auto dump_decl_namespace(decl_namespace const& dec) -> void;
|
||||
auto dump_decl_usingtree(decl_usingtree const& dec) -> void;
|
||||
auto dump_decl_function(decl_function const& dec) -> void;
|
||||
auto dump_stmt(stmt const& stm) -> void;
|
||||
auto dump_stmt_list(stmt_list const& stm) -> void;
|
||||
auto dump_stmt_comp(stmt_comp const& stm) -> void;
|
||||
auto dump_stmt_dev(stmt_dev const& stm) -> void;
|
||||
auto dump_stmt_expr(stmt_expr const& stm) -> void;
|
||||
auto dump_stmt_call(stmt_call const& stm) -> void;
|
||||
auto dump_stmt_const(stmt_const const& stm) -> void;
|
||||
auto dump_stmt_assign(stmt_assign const& stm) -> void;
|
||||
auto dump_stmt_endon(stmt_endon const& stm) -> void;
|
||||
auto dump_stmt_notify(stmt_notify const& stm) -> void;
|
||||
auto dump_stmt_realwait(stmt_realwait const& stm) -> void;
|
||||
auto dump_stmt_wait(stmt_wait const& stm) -> void;
|
||||
auto dump_stmt_waittill(stmt_waittill const& stm) -> void;
|
||||
auto dump_stmt_waittillmatch(stmt_waittillmatch const& stm) -> void;
|
||||
auto dump_stmt_waittillframeend(stmt_waittillframeend const& stm) -> void;
|
||||
auto dump_stmt_if(stmt_if const& stm) -> void;
|
||||
auto dump_stmt_ifelse(stmt_ifelse const& stm) -> void;
|
||||
auto dump_stmt_while(stmt_while const& stm) -> void;
|
||||
auto dump_stmt_dowhile(stmt_dowhile const& stm) -> void;
|
||||
auto dump_stmt_for(stmt_for const& stm) -> void;
|
||||
auto dump_stmt_foreach(stmt_foreach const& stm) -> void;
|
||||
auto dump_stmt_switch(stmt_switch const& stm) -> void;
|
||||
auto dump_stmt_case(stmt_case const& stm) -> void;
|
||||
auto dump_stmt_default(stmt_default const& stm) -> void;
|
||||
auto dump_stmt_break(stmt_break const& stm) -> void;
|
||||
auto dump_stmt_continue(stmt_continue const& stm) -> void;
|
||||
auto dump_stmt_return(stmt_return const& stm) -> void;
|
||||
auto dump_stmt_breakpoint(stmt_breakpoint const& stm) -> void;
|
||||
auto dump_stmt_prof_begin(stmt_prof_begin const& stm) -> void;
|
||||
auto dump_stmt_prof_end(stmt_prof_end const& stm) -> void;
|
||||
auto dump_expr(expr const& exp) -> void;
|
||||
auto dump_expr_increment(expr_increment const& exp) -> void;
|
||||
auto dump_expr_decrement(expr_decrement const& exp) -> void;
|
||||
auto dump_expr_assign_equal(expr_assign_equal const& exp) -> void;
|
||||
auto dump_expr_assign_add(expr_assign_add const& exp) -> void;
|
||||
auto dump_expr_assign_sub(expr_assign_sub const& exp) -> void;
|
||||
auto dump_expr_assign_mul(expr_assign_mul const& exp) -> void;
|
||||
auto dump_expr_assign_div(expr_assign_div const& exp) -> void;
|
||||
auto dump_expr_assign_mod(expr_assign_mod const& exp) -> void;
|
||||
auto dump_expr_assign_shift_left(expr_assign_shift_left const& exp) -> void;
|
||||
auto dump_expr_assign_shift_right(expr_assign_shift_right const& exp) -> void;
|
||||
auto dump_expr_assign_bitwise_or(expr_assign_bitwise_or const& exp) -> void;
|
||||
auto dump_expr_assign_bitwise_and(expr_assign_bitwise_and const& exp) -> void;
|
||||
auto dump_expr_assign_bitwise_exor(expr_assign_bitwise_exor const& exp) -> void;
|
||||
auto dump_expr_ternary(expr_ternary const& exp) -> void;
|
||||
auto dump_expr_or(expr_or const& exp) -> void;
|
||||
auto dump_expr_and(expr_and const& exp) -> void;
|
||||
auto dump_expr_super_equal(expr_super_equal const& exp) -> void;
|
||||
auto dump_expr_super_not_equal(expr_super_not_equal const& exp) -> void;
|
||||
auto dump_expr_equality(expr_equality const& exp) -> void;
|
||||
auto dump_expr_inequality(expr_inequality const& exp) -> void;
|
||||
auto dump_expr_less_equal(expr_less_equal const& exp) -> void;
|
||||
auto dump_expr_greater_equal(expr_greater_equal const& exp) -> void;
|
||||
auto dump_expr_less(expr_less const& exp) -> void;
|
||||
auto dump_expr_greater(expr_greater const& exp) -> void;
|
||||
auto dump_expr_add(expr_add const& exp) -> void;
|
||||
auto dump_expr_sub(expr_sub const& exp) -> void;
|
||||
auto dump_expr_mul(expr_mul const& exp) -> void;
|
||||
auto dump_expr_div(expr_div const& exp) -> void;
|
||||
auto dump_expr_mod(expr_mod const& exp) -> void;
|
||||
auto dump_expr_shift_left(expr_shift_left const& exp) -> void;
|
||||
auto dump_expr_shift_right(expr_shift_right const& exp) -> void;
|
||||
auto dump_expr_bitwise_or(expr_bitwise_or const& exp) -> void;
|
||||
auto dump_expr_bitwise_and(expr_bitwise_and const& exp) -> void;
|
||||
auto dump_expr_bitwise_exor(expr_bitwise_exor const& exp) -> void;
|
||||
auto dump_expr_not(expr_not const& exp) -> void;
|
||||
auto dump_expr_negate(expr_negate const& exp) -> void;
|
||||
auto dump_expr_complement(expr_complement const& exp) -> void;
|
||||
auto dump_expr_new(expr_new const& exp) -> void;
|
||||
auto dump_expr_call(expr_call const& exp) -> void;
|
||||
auto dump_expr_method(expr_method const& exp) -> void;
|
||||
auto dump_call(call const& exp) -> void;
|
||||
auto dump_expr_function(expr_function const& exp) -> void;
|
||||
auto dump_expr_pointer(expr_pointer const& exp) -> void;
|
||||
auto dump_expr_member(expr_member const& exp) -> void;
|
||||
auto dump_expr_parameters(expr_parameters const& exp) -> void;
|
||||
auto dump_expr_arguments(expr_arguments const& exp) -> void;
|
||||
auto dump_expr_isdefined(expr_isdefined const& exp) -> void;
|
||||
auto dump_expr_vectorscale(expr_vectorscale const& exp) -> void;
|
||||
auto dump_expr_anglestoup(expr_anglestoup const& exp) -> void;
|
||||
auto dump_expr_anglestoright(expr_anglestoright const& exp) -> void;
|
||||
auto dump_expr_anglestoforward(expr_anglestoforward const& exp) -> void;
|
||||
auto dump_expr_angleclamp180(expr_angleclamp180 const& exp) -> void;
|
||||
auto dump_expr_vectortoangles(expr_vectortoangles const& exp) -> void;
|
||||
auto dump_expr_abs(expr_abs const& exp) -> void;
|
||||
auto dump_expr_gettime(expr_gettime const& exp) -> void;
|
||||
auto dump_expr_getdvar(expr_getdvar const& exp) -> void;
|
||||
auto dump_expr_getdvarint(expr_getdvarint const& exp) -> void;
|
||||
auto dump_expr_getdvarfloat(expr_getdvarfloat const& exp) -> void;
|
||||
auto dump_expr_getdvarvector(expr_getdvarvector const& exp) -> void;
|
||||
auto dump_expr_getdvarcolorred(expr_getdvarcolorred const& exp) -> void;
|
||||
auto dump_expr_getdvarcolorgreen(expr_getdvarcolorgreen const& exp) -> void;
|
||||
auto dump_expr_getdvarcolorblue(expr_getdvarcolorblue const& exp) -> void;
|
||||
auto dump_expr_getdvarcoloralpha(expr_getdvarcoloralpha const& exp) -> void;
|
||||
auto dump_expr_getfirstarraykey(expr_getfirstarraykey const& exp) -> void;
|
||||
auto dump_expr_getnextarraykey(expr_getnextarraykey const& exp) -> void;
|
||||
auto dump_expr_reference(expr_reference const& exp) -> void;
|
||||
auto dump_expr_array(expr_array const& exp) -> void;
|
||||
auto dump_expr_field(expr_field const& exp) -> void;
|
||||
auto dump_expr_size(expr_size const& exp) -> void;
|
||||
auto dump_expr_paren(expr_paren const& exp) -> void;
|
||||
auto dump_expr_empty_array(expr_empty_array const& exp) -> void;
|
||||
auto dump_expr_undefined(expr_undefined const& exp) -> void;
|
||||
auto dump_expr_game(expr_game const& exp) -> void;
|
||||
auto dump_expr_self(expr_self const& exp) -> void;
|
||||
auto dump_expr_anim(expr_anim const& exp) -> void;
|
||||
auto dump_expr_level(expr_level const& exp) -> void;
|
||||
auto dump_expr_world(expr_world const& exp) -> void;
|
||||
auto dump_expr_classes(expr_classes const& exp) -> void;
|
||||
auto dump_expr_animation(expr_animation const& exp) -> void;
|
||||
auto dump_expr_animtree(expr_animtree const& exp) -> void;
|
||||
auto dump_expr_identifier(expr_identifier const& exp) -> void;
|
||||
auto dump_expr_path(expr_path const& exp) -> void;
|
||||
auto dump_expr_istring(expr_istring const& exp) -> void;
|
||||
auto dump_expr_string(expr_string const& exp) -> void;
|
||||
auto dump_expr_hash(expr_hash const& exp) -> void;
|
||||
auto dump_expr_vector(expr_vector const& exp) -> void;
|
||||
auto dump_expr_float(expr_float const& exp) -> void;
|
||||
auto dump_expr_integer(expr_integer const& exp) -> void;
|
||||
auto dump_expr_false(expr_false const& exp) -> void;
|
||||
auto dump_expr_true(expr_true const& exp) -> void;
|
||||
auto dump_asm_loc(asm_loc const& exp) -> void;
|
||||
auto dump_asm_jmp(asm_jmp const& exp) -> void;
|
||||
auto dump_asm_jmp_back(asm_jmp_back const& exp) -> void;
|
||||
auto dump_asm_jmp_cond(asm_jmp_cond const& exp) -> void;
|
||||
auto dump_asm_jmp_true(asm_jmp_true const& exp) -> void;
|
||||
auto dump_asm_jmp_false(asm_jmp_false const& exp) -> void;
|
||||
auto dump_asm_switch(asm_switch const& exp) -> void;
|
||||
auto dump_asm_endswitch(asm_endswitch const& exp) -> void;
|
||||
auto dump_asm_prescriptcall(asm_prescriptcall const& exp) -> void;
|
||||
auto dump_asm_voidcodepos(asm_voidcodepos const& exp) -> void;
|
||||
auto dump_asm_dev(asm_dev const& exp) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
43
include/xsk/gsc/assembler.hpp
Normal file
43
include/xsk/gsc/assembler.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/utils/writer.hpp"
|
||||
#include "common/types.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class assembler
|
||||
{
|
||||
context const* ctx_;
|
||||
function const* func_;
|
||||
assembly const* assembly_;
|
||||
utils::writer script_;
|
||||
utils::writer stack_;
|
||||
|
||||
public:
|
||||
assembler(context const* ctx);
|
||||
auto assemble(assembly const& data) -> std::pair<buffer, buffer>;
|
||||
|
||||
private:
|
||||
auto assemble_function(function const& func) -> void;
|
||||
auto assemble_instruction(instruction const& inst) -> void;
|
||||
auto assemble_builtin_call(instruction const& inst, bool method, bool args) -> void;
|
||||
auto assemble_local_call(instruction const& inst, bool thread) -> void;
|
||||
auto assemble_far_call(instruction const& inst, bool thread) -> void;
|
||||
auto assemble_switch(instruction const& inst) -> void;
|
||||
auto assemble_end_switch(instruction const& inst) -> void;
|
||||
auto assemble_field_variable(instruction const& inst) -> void;
|
||||
auto assemble_formal_params(instruction const& inst) -> void;
|
||||
auto assemble_jump(instruction const& inst, bool expr, bool back) -> void;
|
||||
auto assemble_offset(i32 offs) -> void;
|
||||
auto resolve_function(std::string const& name) -> i32;
|
||||
auto resolve_label(std::string const& name) -> i32;
|
||||
auto encrypt_string(std::string const& str) -> std::string;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
267
include/xsk/gsc/common/assembly.hpp
Normal file
267
include/xsk/gsc/common/assembly.hpp
Normal file
@ -0,0 +1,267 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
constexpr usize opcode_count = 205;
|
||||
|
||||
enum class opcode : u8
|
||||
{
|
||||
vm_invalid,
|
||||
OP_CastFieldObject,
|
||||
OP_SetLocalVariableFieldCached,
|
||||
OP_plus,
|
||||
OP_RemoveLocalVariables,
|
||||
OP_EvalSelfFieldVariableRef,
|
||||
OP_ScriptFarMethodChildThreadCall,
|
||||
OP_GetGameRef,
|
||||
OP_EvalAnimFieldVariable,
|
||||
OP_EvalLevelFieldVariableRef,
|
||||
OP_GetThisthread,
|
||||
OP_greater,
|
||||
OP_waittillmatch,
|
||||
OP_shift_right,
|
||||
OP_dec,
|
||||
OP_JumpOnTrue,
|
||||
OP_bit_or,
|
||||
OP_equality,
|
||||
OP_ClearLocalVariableFieldCached0,
|
||||
OP_notify,
|
||||
OP_GetVector,
|
||||
OP_ScriptMethodChildThreadCallPointer,
|
||||
OP_PreScriptCall,
|
||||
OP_GetByte,
|
||||
OP_ScriptFarThreadCall,
|
||||
OP_SetSelfFieldVariableField,
|
||||
OP_JumpOnFalseExpr,
|
||||
OP_GetUndefined,
|
||||
OP_jumpback,
|
||||
OP_JumpOnTrueExpr,
|
||||
OP_CallBuiltin0,
|
||||
OP_CallBuiltin1,
|
||||
OP_CallBuiltin2,
|
||||
OP_CallBuiltin3,
|
||||
OP_CallBuiltin4,
|
||||
OP_CallBuiltin5,
|
||||
OP_CallBuiltin,
|
||||
OP_SetLocalVariableFieldCached0,
|
||||
OP_ClearFieldVariable,
|
||||
OP_GetLevel,
|
||||
OP_size,
|
||||
OP_SafeSetWaittillVariableFieldCached,
|
||||
OP_ScriptLocalMethodThreadCall,
|
||||
OP_AddArray,
|
||||
OP_endon,
|
||||
OP_EvalFieldVariable,
|
||||
OP_shift_left,
|
||||
OP_EvalLocalArrayRefCached0,
|
||||
OP_Return,
|
||||
OP_CreateLocalVariable,
|
||||
OP_SafeSetVariableFieldCached0,
|
||||
OP_GetBuiltinFunction,
|
||||
OP_ScriptLocalMethodCall,
|
||||
OP_CallBuiltinMethodPointer,
|
||||
OP_ScriptLocalChildThreadCall,
|
||||
OP_GetSelfObject,
|
||||
OP_GetGame,
|
||||
OP_SetLevelFieldVariableField,
|
||||
OP_EvalArray,
|
||||
OP_GetSelf,
|
||||
OP_End,
|
||||
OP_EvalSelfFieldVariable,
|
||||
OP_less_equal,
|
||||
OP_EvalLocalVariableCached0,
|
||||
OP_EvalLocalVariableCached1,
|
||||
OP_EvalLocalVariableCached2,
|
||||
OP_EvalLocalVariableCached3,
|
||||
OP_EvalLocalVariableCached4,
|
||||
OP_EvalLocalVariableCached5,
|
||||
OP_EvalLocalVariableCached,
|
||||
OP_EvalNewLocalArrayRefCached0,
|
||||
OP_ScriptChildThreadCallPointer,
|
||||
OP_EvalLocalVariableObjectCached,
|
||||
OP_ScriptLocalThreadCall,
|
||||
OP_GetInteger,
|
||||
OP_ScriptMethodCallPointer,
|
||||
OP_checkclearparams,
|
||||
OP_SetAnimFieldVariableField,
|
||||
OP_waittillmatch2,
|
||||
OP_minus,
|
||||
OP_ScriptLocalFunctionCall2,
|
||||
OP_GetNegUnsignedShort,
|
||||
OP_GetNegByte,
|
||||
OP_SafeCreateVariableFieldCached,
|
||||
OP_greater_equal,
|
||||
OP_vector,
|
||||
OP_GetBuiltinMethod,
|
||||
OP_endswitch,
|
||||
OP_ClearArray,
|
||||
OP_DecTop,
|
||||
OP_CastBool,
|
||||
OP_EvalArrayRef,
|
||||
OP_SetNewLocalVariableFieldCached0,
|
||||
OP_GetZero,
|
||||
OP_wait,
|
||||
OP_waittill,
|
||||
OP_GetIString,
|
||||
OP_ScriptFarFunctionCall,
|
||||
OP_GetAnimObject,
|
||||
OP_GetAnimTree,
|
||||
OP_EvalLocalArrayCached,
|
||||
OP_mod,
|
||||
OP_ScriptFarMethodThreadCall,
|
||||
OP_GetUnsignedShort,
|
||||
OP_clearparams,
|
||||
OP_ScriptMethodThreadCallPointer,
|
||||
OP_ScriptFunctionCallPointer,
|
||||
OP_EmptyArray,
|
||||
OP_SafeSetVariableFieldCached,
|
||||
OP_ClearVariableField,
|
||||
OP_EvalFieldVariableRef,
|
||||
OP_ScriptLocalMethodChildThreadCall,
|
||||
OP_EvalNewLocalVariableRefCached0,
|
||||
OP_GetFloat,
|
||||
OP_EvalLocalVariableRefCached,
|
||||
OP_JumpOnFalse,
|
||||
OP_BoolComplement,
|
||||
OP_ScriptThreadCallPointer,
|
||||
OP_ScriptFarFunctionCall2,
|
||||
OP_less,
|
||||
OP_BoolNot,
|
||||
OP_waittillFrameEnd,
|
||||
OP_waitframe,
|
||||
OP_GetString,
|
||||
OP_EvalLevelFieldVariable,
|
||||
OP_GetLevelObject,
|
||||
OP_inc,
|
||||
OP_CallBuiltinMethod0,
|
||||
OP_CallBuiltinMethod1,
|
||||
OP_CallBuiltinMethod2,
|
||||
OP_CallBuiltinMethod3,
|
||||
OP_CallBuiltinMethod4,
|
||||
OP_CallBuiltinMethod5,
|
||||
OP_CallBuiltinMethod,
|
||||
OP_GetAnim,
|
||||
OP_switch,
|
||||
OP_SetVariableField,
|
||||
OP_divide,
|
||||
OP_GetLocalFunction,
|
||||
OP_ScriptFarChildThreadCall,
|
||||
OP_multiply,
|
||||
OP_ClearLocalVariableFieldCached,
|
||||
OP_EvalAnimFieldVariableRef,
|
||||
OP_EvalLocalArrayRefCached,
|
||||
OP_EvalLocalVariableRefCached0,
|
||||
OP_bit_and,
|
||||
OP_GetAnimation,
|
||||
OP_GetFarFunction,
|
||||
OP_CallBuiltinPointer,
|
||||
OP_jump,
|
||||
OP_voidCodepos,
|
||||
OP_ScriptFarMethodCall,
|
||||
OP_inequality,
|
||||
OP_ScriptLocalFunctionCall,
|
||||
OP_bit_ex_or,
|
||||
OP_NOP,
|
||||
OP_abort,
|
||||
OP_object,
|
||||
OP_thread_object,
|
||||
OP_EvalLocalVariable,
|
||||
OP_EvalLocalVariableRef,
|
||||
OP_prof_begin,
|
||||
OP_prof_end,
|
||||
OP_breakpoint,
|
||||
OP_assignmentBreakpoint,
|
||||
OP_manualAndAssignmentBreakpoint,
|
||||
OP_BoolNotAfterAnd,
|
||||
OP_FormalParams,
|
||||
OP_IsDefined,
|
||||
OP_IsTrue,
|
||||
OP_NativeGetLocalFunction,
|
||||
OP_NativeLocalFunctionCall,
|
||||
OP_NativeLocalFunctionCall2,
|
||||
OP_NativeLocalMethodCall,
|
||||
OP_NativeLocalFunctionThreadCall,
|
||||
OP_NativeLocalMethodThreadCall,
|
||||
OP_NativeLocalFunctionChildThreadCall,
|
||||
OP_NativeLocalMethodChildThreadCall,
|
||||
OP_NativeGetFarFunction,
|
||||
OP_NativeFarFunctionCall,
|
||||
OP_NativeFarFunctionCall2,
|
||||
OP_NativeFarMethodCall,
|
||||
OP_NativeFarFunctionThreadCall,
|
||||
OP_NativeFarMethodThreadCall,
|
||||
OP_NativeFarFunctionChildThreadCall,
|
||||
OP_NativeFarMethodChildThreadCall,
|
||||
OP_EvalNewLocalArrayRefCached0_Precompiled,
|
||||
OP_SetNewLocalVariableFieldCached0_Precompiled,
|
||||
OP_CreateLocalVariable_Precompiled,
|
||||
OP_SafeCreateVariableFieldCached_Precompiled,
|
||||
OP_FormalParams_Precompiled,
|
||||
OP_GetStatHash,
|
||||
OP_GetUnkxHash,
|
||||
OP_GetEnumHash,
|
||||
OP_GetDvarHash,
|
||||
OP_GetUnsignedInt,
|
||||
OP_GetNegUnsignedInt,
|
||||
OP_GetInteger64,
|
||||
OP_iw9_139,
|
||||
OP_iw9_140,
|
||||
OP_iw9_141,
|
||||
OP_iw9_142,
|
||||
OP_iw9_143,
|
||||
OP_iw9_144,
|
||||
OP_iw9_166,
|
||||
OP_count,
|
||||
};
|
||||
|
||||
struct instruction
|
||||
{
|
||||
using ptr = std::unique_ptr<instruction>;
|
||||
|
||||
u32 index;
|
||||
u32 size;
|
||||
opcode opcode;
|
||||
std::vector<std::string> data;
|
||||
};
|
||||
|
||||
struct function
|
||||
{
|
||||
using ptr = std::unique_ptr<function>;
|
||||
|
||||
u32 index;
|
||||
u32 size;
|
||||
u32 id;
|
||||
std::string name;
|
||||
std::vector<instruction::ptr> instructions;
|
||||
std::unordered_map<u32, std::string> labels;
|
||||
};
|
||||
|
||||
struct assembly
|
||||
{
|
||||
using ptr = std::unique_ptr<assembly>;
|
||||
|
||||
std::vector<function::ptr> functions;
|
||||
};
|
||||
|
||||
inline auto make_instruction() -> std::unique_ptr<instruction>
|
||||
{
|
||||
return std::unique_ptr<instruction>(new instruction);
|
||||
}
|
||||
|
||||
inline auto make_function() -> std::unique_ptr<function>
|
||||
{
|
||||
return std::unique_ptr<function>(new function);
|
||||
}
|
||||
|
||||
inline auto make_assembly() -> std::unique_ptr<assembly>
|
||||
{
|
||||
return std::unique_ptr<assembly>(new assembly);
|
||||
}
|
||||
|
||||
} // namespace xsk::gsc
|
26
include/xsk/gsc/common/asset.hpp
Normal file
26
include/xsk/gsc/common/asset.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct asset
|
||||
{
|
||||
using ptr = std::unique_ptr<asset>;
|
||||
|
||||
std::string name;
|
||||
u32 compressedLen;
|
||||
u32 len;
|
||||
u32 bytecodeLen;
|
||||
std::vector<u8> buffer;
|
||||
std::vector<u8> bytecode;
|
||||
|
||||
auto serialize() -> std::vector<u8>;
|
||||
auto deserialize(std::vector<u8> const& data) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
1677
include/xsk/gsc/common/ast.hpp
Normal file
1677
include/xsk/gsc/common/ast.hpp
Normal file
File diff suppressed because it is too large
Load Diff
20
include/xsk/gsc/common/buffer.hpp
Normal file
20
include/xsk/gsc/common/buffer.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct buffer
|
||||
{
|
||||
u8 const* data;
|
||||
usize const size;
|
||||
|
||||
buffer() : data{ nullptr }, size{ 0 } {}
|
||||
buffer(u8 const* data, usize size) : data{ data }, size{ size } {}
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
21
include/xsk/gsc/common/define.hpp
Normal file
21
include/xsk/gsc/common/define.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct define
|
||||
{
|
||||
enum kind : u8 { PLAIN, BUILTIN, OBJECT, FUNCTION };
|
||||
|
||||
kind type;
|
||||
// bool vararg;
|
||||
std::vector<token> args;
|
||||
std::vector<token> exp;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
19
include/xsk/gsc/common/directive.hpp
Normal file
19
include/xsk/gsc/common/directive.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct directive
|
||||
{
|
||||
enum kind : u8 { IF, IFDEF, IFNDEF, ELIF, ELIFDEF, ELIFNDEF, ELSE, ENDIF, DEFINE, UNDEF, PRAGMA, WARNING, ERROR, LINE, INCLUDE, INLINE, INSERT, USINGTREE };
|
||||
|
||||
kind type;
|
||||
bool skip;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
47
include/xsk/gsc/common/exception.hpp
Normal file
47
include/xsk/gsc/common/exception.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
error(std::string const& what);
|
||||
};
|
||||
|
||||
class asm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
asm_error(std::string const& what);
|
||||
};
|
||||
|
||||
class disasm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
disasm_error(std::string const& what);
|
||||
};
|
||||
|
||||
class ppr_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
ppr_error(location const& loc, std::string const& what);
|
||||
};
|
||||
|
||||
class comp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
comp_error(location const& loc, std::string const& what);
|
||||
};
|
||||
|
||||
class decomp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
decomp_error(std::string const& what);
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
177
include/xsk/gsc/common/location.hpp
Normal file
177
include/xsk/gsc/common/location.hpp
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class position
|
||||
{
|
||||
public:
|
||||
typedef const std::string filename_type;
|
||||
typedef int counter_type;
|
||||
|
||||
filename_type *filename;
|
||||
counter_type line;
|
||||
counter_type column;
|
||||
|
||||
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
: filename(f), line(l), column(c) {}
|
||||
|
||||
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
filename = fn;
|
||||
line = l;
|
||||
column = c;
|
||||
}
|
||||
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
column = 1;
|
||||
line = add_(line, count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
column = add_(column, count, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
||||
{
|
||||
return lhs + rhs < min ? min : lhs + rhs;
|
||||
}
|
||||
};
|
||||
|
||||
inline position& operator+=(position &res, position::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline position operator+(position res, position::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
inline position& operator-=(position &res, position::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
inline position operator-(position res, position::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const position &pos)
|
||||
{
|
||||
if (pos.filename)
|
||||
ostr << *pos.filename << ':';
|
||||
return ostr << pos.line << '.' << pos.column;
|
||||
}
|
||||
|
||||
class location
|
||||
{
|
||||
public:
|
||||
typedef position::filename_type filename_type;
|
||||
typedef position::counter_type counter_type;
|
||||
|
||||
position begin;
|
||||
position end;
|
||||
|
||||
location(const position &b, const position &e)
|
||||
: begin(b), end(e) {}
|
||||
|
||||
explicit location(const position &p = position())
|
||||
: begin(p), end(p) {}
|
||||
|
||||
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
||||
: begin(f, l, c), end(f, l, c) {}
|
||||
|
||||
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
begin.initialize(f, l, c);
|
||||
end = begin;
|
||||
}
|
||||
|
||||
void step()
|
||||
{
|
||||
begin = end;
|
||||
}
|
||||
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
end.lines(count);
|
||||
}
|
||||
|
||||
auto print() const -> std::string
|
||||
{
|
||||
return fmt::format("{}:{}:{}", *begin.filename, begin.line, begin.column);
|
||||
}
|
||||
|
||||
auto label() const -> std::string
|
||||
{
|
||||
return fmt::format("loc_{:X}", begin.line);
|
||||
}
|
||||
};
|
||||
|
||||
inline location& operator+=(location &res, const location &end)
|
||||
{
|
||||
res.end = end.end;
|
||||
return res;
|
||||
}
|
||||
|
||||
inline location operator+(location res, const location &end)
|
||||
{
|
||||
return res += end;
|
||||
}
|
||||
|
||||
inline location& operator+=(location &res, location::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline location operator+(location res, location::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
inline location& operator-=(location &res, location::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
inline location operator-(location res, location::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const location &loc)
|
||||
{
|
||||
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
||||
ostr << loc.begin;
|
||||
if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename))
|
||||
ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.line < loc.end.line)
|
||||
ostr << '-' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.column < end_col)
|
||||
ostr << '-' << end_col;
|
||||
return ostr;
|
||||
}
|
||||
|
||||
} // namespace xsk::gsc
|
23
include/xsk/gsc/common/lookahead.hpp
Normal file
23
include/xsk/gsc/common/lookahead.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct lookahead
|
||||
{
|
||||
char const* buffer_pos;
|
||||
usize available;
|
||||
char last_byte;
|
||||
char curr_byte;
|
||||
|
||||
lookahead(char const* data, usize size);
|
||||
auto advance() -> void;
|
||||
auto ended() { return available == 0; };
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
64
include/xsk/gsc/common/scope.hpp
Normal file
64
include/xsk/gsc/common/scope.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct locjmp
|
||||
{
|
||||
std::string end;
|
||||
std::string cnt;
|
||||
std::string brk;
|
||||
bool last;
|
||||
};
|
||||
|
||||
struct scope
|
||||
{
|
||||
using ptr = std::unique_ptr<scope>;
|
||||
|
||||
enum abort_type
|
||||
{
|
||||
abort_none = 0,
|
||||
abort_continue = 1,
|
||||
abort_break = 2,
|
||||
abort_return = 3,
|
||||
};
|
||||
|
||||
struct var
|
||||
{
|
||||
std::string name;
|
||||
u8 create;
|
||||
bool init;
|
||||
};
|
||||
|
||||
abort_type abort;
|
||||
std::string loc_end;
|
||||
std::string loc_cont;
|
||||
std::string loc_break;
|
||||
u32 create_count;
|
||||
u32 public_count;
|
||||
std::vector<var> vars;
|
||||
bool is_last;
|
||||
|
||||
scope();
|
||||
auto transfer_dec(scope::ptr const& child) -> void;
|
||||
auto transfer(scope::ptr const& child) -> void;
|
||||
auto copy(scope::ptr const& child) -> void;
|
||||
auto append_dec(scope::ptr const& child) -> void;
|
||||
auto append(std::vector<scope*> const& childs) -> void;
|
||||
auto merge(std::vector<scope*> const& childs) -> void;
|
||||
auto init(scope::ptr const& child) -> void;
|
||||
auto init(std::vector<scope*> const& childs) -> void;
|
||||
auto find(usize start, std::string const& name) -> i32;
|
||||
};
|
||||
|
||||
inline auto make_scope() -> std::unique_ptr<scope>
|
||||
{
|
||||
return std::unique_ptr<scope>(new scope);
|
||||
}
|
||||
|
||||
} // namespace xsk::gsc
|
19
include/xsk/gsc/common/space.hpp
Normal file
19
include/xsk/gsc/common/space.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
enum class spacing : u8
|
||||
{
|
||||
none = 0, // no space between tokens
|
||||
null = 1, // token just after new line
|
||||
back = 2, // token after space
|
||||
empty = 4, // token after new line + space
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
41
include/xsk/gsc/common/token.hpp
Normal file
41
include/xsk/gsc/common/token.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct token
|
||||
{
|
||||
enum kind : u8
|
||||
{
|
||||
PLUS, MINUS, STAR, DIV, MOD, BITOR, BITAND, BITEXOR, SHL, SHR,
|
||||
ASSIGN, PLUSEQ, MINUSEQ, STAREQ, DIVEQ, MODEQ, BITOREQ, BITANDEQ, BITEXOREQ, SHLEQ, SHREQ,
|
||||
INC, DEC, GT, LT, GE, LE, NE, EQ, OR, AND, TILDE, BANG, QMARK, COLON, SHARP, COMMA, DOT,
|
||||
DOUBLEDOT, ELLIPSIS, SEMICOLON, DOUBLECOLON, LBRACKET, RBRACKET, LBRACE, RBRACE, LPAREN, RPAREN,
|
||||
|
||||
NAME, PATH, STRING, ISTRING, INT, FLT,
|
||||
|
||||
DEVBEGIN, DEVEND, INLINE, INCLUDE, USINGTREE, ANIMTREE, ENDON, NOTIFY, WAIT,
|
||||
WAITTILL, WAITTILLMATCH, WAITTILLFRAMEEND, WAITFRAME, IF, ELSE, DO, WHILE,
|
||||
FOR, FOREACH, IN, SWITCH, CASE, DEFAULT, BREAK, CONTINUE, RETURN, BREAKPOINT,
|
||||
PROFBEGIN, PROFEND, ASSERT, ASSERTEX, ASSERTMSG, THREAD, CHILDTHREAD, THISTHREAD,
|
||||
CALL, TRUE, FALSE, UNDEFINED, SIZE, GAME, SELF, ANIM, LEVEL, ISDEFINED, ISTRUE,
|
||||
|
||||
HASH, NEWLINE, EOS, DEFINED, MACROBEGIN, MACROEND, MACROARG, MACROVAOPT, MACROVAARGS, STRINGIZE, PASTE
|
||||
};
|
||||
|
||||
kind type;
|
||||
spacing space;
|
||||
location pos;
|
||||
std::string data;
|
||||
|
||||
token(kind type, spacing space, location pos) : type{ type }, space{ space }, pos{ pos }, data{} {}
|
||||
token(kind type, spacing space, location pos, std::string data) : type{ type }, space{ space }, pos{ pos }, data{ std::move(data) } {}
|
||||
auto to_string() -> std::string;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
111
include/xsk/gsc/common/types.hpp
Normal file
111
include/xsk/gsc/common/types.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "asset.hpp"
|
||||
#include "scope.hpp"
|
||||
#include "buffer.hpp"
|
||||
#include "assembly.hpp"
|
||||
#include "location.hpp"
|
||||
#include "exception.hpp"
|
||||
#include "lookahead.hpp"
|
||||
#include "directive.hpp"
|
||||
#include "space.hpp"
|
||||
#include "token.hpp"
|
||||
#include "define.hpp"
|
||||
#include "ast.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
enum class instance : u8
|
||||
{
|
||||
server,
|
||||
client,
|
||||
};
|
||||
|
||||
enum class build : u8
|
||||
{
|
||||
dev,
|
||||
prod,
|
||||
};
|
||||
|
||||
enum class endian : u8
|
||||
{
|
||||
little,
|
||||
big,
|
||||
};
|
||||
|
||||
enum class system : u8
|
||||
{
|
||||
pc,
|
||||
ps3,
|
||||
xb2,
|
||||
};
|
||||
|
||||
enum class engine : u8
|
||||
{
|
||||
iw5,
|
||||
iw6,
|
||||
iw7,
|
||||
iw8,
|
||||
iw9,
|
||||
s1,
|
||||
s2,
|
||||
s4,
|
||||
h1,
|
||||
h2,
|
||||
};
|
||||
|
||||
struct props
|
||||
{
|
||||
enum values : u32
|
||||
{
|
||||
none = 0 << 0,
|
||||
str4 = 1 << 0, // strings size 4
|
||||
tok4 = 1 << 1, // tokenid size 4
|
||||
waitframe = 1 << 2, // waitframe opcode
|
||||
params = 1 << 3, // packed func params
|
||||
boolfuncs = 1 << 4, // isdefined, istrue
|
||||
boolnotand = 1 << 5, // !&& expr opcode
|
||||
offs8 = 1 << 6, // offset shift by 8
|
||||
offs9 = 1 << 7, // offset shift by 9
|
||||
hash = 1 << 9, // iw9 identifiers
|
||||
farcall = 1 << 9, // iw9 new call system
|
||||
foreach = 1 << 10, // iw9 foreach
|
||||
};
|
||||
|
||||
props(values value) : value_(value) {}
|
||||
operator values() { return value_; }
|
||||
operator bool() { return value_ != values::none; }
|
||||
props::values operator|(props::values rhs) const { return static_cast<props::values>(value_ | rhs); }
|
||||
props::values operator&(props::values rhs) const { return static_cast<props::values>(value_ & rhs); }
|
||||
|
||||
friend props::values operator|(props::values lhs, props::values rhs)
|
||||
{
|
||||
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) | static_cast<std::underlying_type<props::values>::type>(rhs));
|
||||
}
|
||||
|
||||
friend props::values operator&(props::values lhs, props::values rhs)
|
||||
{
|
||||
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) & static_cast<std::underlying_type<props::values>::type>(rhs));
|
||||
}
|
||||
|
||||
private:
|
||||
values value_;
|
||||
};
|
||||
|
||||
enum class switch_type
|
||||
{
|
||||
none,
|
||||
integer,
|
||||
string,
|
||||
};
|
||||
|
||||
// fordward decl for modules ref
|
||||
class context;
|
||||
|
||||
} // namespace xsk::gsc
|
159
include/xsk/gsc/compiler.hpp
Normal file
159
include/xsk/gsc/compiler.hpp
Normal file
@ -0,0 +1,159 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class compiler
|
||||
{
|
||||
context* ctx_;
|
||||
assembly::ptr assembly_;
|
||||
function::ptr function_;
|
||||
std::vector<std::string> stackframe_;
|
||||
std::vector<std::string> localfuncs_;
|
||||
std::unordered_map<std::string, expr const*> constants_;
|
||||
std::unordered_map<node*, scope::ptr> scopes_;
|
||||
std::vector<scope*> break_blks_;
|
||||
std::vector<scope*> continue_blks_;
|
||||
std::string animname_;
|
||||
u32 index_;
|
||||
u32 label_idx_;
|
||||
bool can_break_;
|
||||
bool can_continue_;
|
||||
bool developer_thread_;
|
||||
bool animload_;
|
||||
|
||||
public:
|
||||
compiler(context* ctx);
|
||||
auto compile(program const& data) -> assembly::ptr;
|
||||
auto compile(std::string const& file, std::vector<u8>& data) -> assembly::ptr;
|
||||
|
||||
private:
|
||||
auto emit_program(program const& prog) -> void;
|
||||
auto emit_decl(decl const& dec) -> void;
|
||||
auto emit_decl_usingtree(decl_usingtree const& animtree) -> void;
|
||||
auto emit_decl_constant(decl_constant const& constant) -> void;
|
||||
auto emit_decl_function(decl_function const& func) -> void;
|
||||
auto emit_stmt(stmt const& stm, scope& scp, bool last) -> void;
|
||||
auto emit_stmt_list(stmt_list const& stm, scope& scp, bool last) -> void;
|
||||
auto emit_stmt_comp(stmt_comp const& stm, scope& scp, bool last) -> void;
|
||||
auto emit_stmt_dev(stmt_dev const& stm, scope& scp, bool last) -> void;
|
||||
auto emit_stmt_expr(stmt_expr const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_call(stmt_call const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_assign(stmt_assign const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_endon(stmt_endon const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_notify(stmt_notify const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_wait(stmt_wait const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_waittill(stmt_waittill const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_waittillmatch(stmt_waittillmatch const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_waittillframeend(stmt_waittillframeend const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_waitframe(stmt_waitframe const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_if(stmt_if const& stm, scope& scp, bool last) -> void;
|
||||
auto emit_stmt_ifelse(stmt_ifelse const& stm, scope& scp, bool last) -> void;
|
||||
auto emit_stmt_while(stmt_while const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_dowhile(stmt_dowhile const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_for(stmt_for const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_switch(stmt_switch const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_case(stmt_case const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_default(stmt_default const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_break(stmt_break const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_continue(stmt_continue const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_return(stmt_return const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_breakpoint(stmt_breakpoint const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_prof_begin(stmt_prof_begin const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_prof_end(stmt_prof_end const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_assert(stmt_assert const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_assertex(stmt_assertex const& stm, scope& scp) -> void;
|
||||
auto emit_stmt_assertmsg(stmt_assertmsg const& stm, scope& scp) -> void;
|
||||
auto emit_expr(expr const& exp, scope& scp) -> void;
|
||||
auto emit_expr_assign(expr_assign const& exp, scope& scp) -> void;
|
||||
auto emit_expr_clear(expr const& exp, scope& scp) -> void;
|
||||
auto emit_expr_clear_local(expr_identifier const& exp, scope& scp) -> void;
|
||||
auto emit_expr_increment(expr_increment const& exp, scope& scp, bool is_stmt) -> void;
|
||||
auto emit_expr_decrement(expr_decrement const& exp, scope& scp, bool is_stmt) -> void;
|
||||
auto emit_expr_ternary(expr_ternary const& exp, scope& scp) -> void;
|
||||
auto emit_expr_binary(expr_binary const& exp, scope& scp) -> void;
|
||||
auto emit_expr_and(expr_and const& exp, scope& scp) -> void;
|
||||
auto emit_expr_or(expr_or const& exp, scope& scp) -> void;
|
||||
auto emit_expr_complement(expr_complement const& exp, scope& scp) -> void;
|
||||
auto emit_expr_negate(expr_negate const& exp, scope& scp) -> void;
|
||||
auto emit_expr_not(expr_not const& exp, scope& scp) -> void;
|
||||
auto emit_expr_call(expr_call const& exp, scope& scp, bool is_stmt) -> void;
|
||||
auto emit_expr_call_pointer(expr_pointer const& exp, scope& scp, bool is_stmt) -> void;
|
||||
auto emit_expr_call_function(expr_function const& exp, scope& scp, bool is_stmt) -> void;
|
||||
auto emit_expr_method(expr_method const& exp, scope& scp, bool is_stmt) -> void;
|
||||
auto emit_expr_method_pointer(expr_pointer const& exp, expr const& obj, scope& scp, bool is_stmt) -> void;
|
||||
auto emit_expr_method_function(expr_function const& exp, expr const& obj, scope& scp, bool is_stmt) -> void;
|
||||
auto emit_expr_add_array(expr_add_array const& exp, scope& scp) -> void;
|
||||
auto emit_expr_parameters(expr_parameters const& exp, scope& scp) -> void;
|
||||
auto emit_expr_arguments(expr_arguments const& exp, scope& scp) -> void;
|
||||
auto emit_expr_isdefined(expr_isdefined const& exp, scope& scp) -> void;
|
||||
auto emit_expr_istrue(expr_istrue const& exp, scope& scp) -> void;
|
||||
auto emit_expr_reference(expr_reference const& exp, scope& scp) -> void;
|
||||
auto emit_expr_size(expr_size const& exp, scope& scp) -> void;
|
||||
auto emit_expr_tuple(expr_tuple const& exp, scope& scp) -> void;
|
||||
auto emit_expr_variable_ref(expr const& exp, scope& scp, bool set) -> void;
|
||||
auto emit_expr_array_ref(expr_array const& exp, scope& scp, bool set) -> void;
|
||||
auto emit_expr_field_ref(expr_field const& exp, scope& scp, bool set) -> void;
|
||||
auto emit_expr_local_ref(expr_identifier const& exp, scope& scp, bool set) -> void;
|
||||
auto emit_expr_variable(expr const& exp, scope& scp) -> void;
|
||||
auto emit_expr_array(expr_array const& exp, scope& scp) -> void;
|
||||
auto emit_expr_field(expr_field const& exp, scope& scp) -> void;
|
||||
auto emit_expr_local(expr_identifier const& exp, scope& scp) -> void;
|
||||
auto emit_expr_object(expr const& exp, scope& scp) -> void;
|
||||
auto emit_expr_vector(expr_vector const& exp, scope& scp) -> void;
|
||||
auto emit_expr_animation(expr_animation const& exp) -> void;
|
||||
auto emit_expr_animtree(expr_animtree const& exp) -> void;
|
||||
auto emit_expr_istring(expr_istring const& exp) -> void;
|
||||
auto emit_expr_string(expr_string const& exp) -> void;
|
||||
auto emit_expr_float(expr_float const& exp) -> void;
|
||||
auto emit_expr_integer(expr_integer const& exp) -> void;
|
||||
auto emit_expr_false(expr_false const& exp) -> void;
|
||||
auto emit_expr_true(expr_true const& exp) -> void;
|
||||
auto emit_create_local_vars(scope& scp) -> void;
|
||||
auto emit_remove_local_vars(scope& scp) -> void;
|
||||
auto emit_opcode(opcode op) -> void;
|
||||
auto emit_opcode(opcode op, std::string const& data) -> void;
|
||||
auto emit_opcode(opcode op, std::vector<std::string> const& data) -> void;
|
||||
auto process_function(decl_function const& func) -> void;
|
||||
auto process_stmt(stmt const& stm, scope& scp) -> void;
|
||||
auto process_stmt_list(stmt_list const& stm, scope& scp) -> void;
|
||||
auto process_stmt_comp(stmt_comp const& stm, scope& scp) -> void;
|
||||
auto process_stmt_dev(stmt_dev const& stm, scope& scp) -> void;
|
||||
auto process_stmt_expr(stmt_expr const& stm, scope& scp) -> void;
|
||||
auto process_stmt_assign(stmt_assign const& stm, scope& scp) -> void;
|
||||
auto process_stmt_waittill(stmt_waittill const& stm, scope& scp) -> void;
|
||||
auto process_stmt_if(stmt_if const& stm, scope& scp) -> void;
|
||||
auto process_stmt_ifelse(stmt_ifelse const& stm, scope& scp) -> void;
|
||||
auto process_stmt_while(stmt_while const& stm, scope& scp) -> void;
|
||||
auto process_stmt_dowhile(stmt_dowhile const& stm, scope& scp) -> void;
|
||||
auto process_stmt_for(stmt_for const& stm, scope& scp) -> void;
|
||||
auto process_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void;
|
||||
auto process_stmt_switch(stmt_switch const& stm, scope& scp) -> void;
|
||||
auto process_stmt_break(stmt_break const& stm, scope& scp) -> void;
|
||||
auto process_stmt_continue(stmt_continue const& stm, scope& scp) -> void;
|
||||
auto process_stmt_return(stmt_return const& stm, scope& scp) -> void;
|
||||
auto process_expr(expr const& exp, scope& scp) -> void;
|
||||
auto process_expr_tuple(expr_tuple const& exp, scope& scp) -> void;
|
||||
auto process_expr_parameters(expr_parameters const& exp, scope& scp) -> void;
|
||||
auto variable_register(expr_identifier const& exp, scope& scp) -> void;
|
||||
auto variable_initialized(expr_identifier const& exp, scope& scp) -> bool;
|
||||
auto variable_initialize(expr_identifier const& exp, scope& scp) -> u8;
|
||||
auto variable_create(expr_identifier const& exp, scope& scp) -> u8;
|
||||
auto variable_access(expr_identifier const& exp, scope& scp) -> u8;
|
||||
auto resolve_function_type(expr_function const& exp, std::string& path) -> call::type;
|
||||
auto resolve_reference_type(expr_reference const& exp, std::string& path, bool& method) -> call::type;
|
||||
auto is_constant_condition(expr const& exp) -> bool;
|
||||
auto insert_label(std::string const& label) -> void;
|
||||
auto create_label() -> std::string;
|
||||
auto insert_label() -> std::string;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
149
include/xsk/gsc/context.hpp
Normal file
149
include/xsk/gsc/context.hpp
Normal file
@ -0,0 +1,149 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
#include "source.hpp"
|
||||
#include "assembler.hpp"
|
||||
#include "disassembler.hpp"
|
||||
#include "compiler.hpp"
|
||||
#include "decompiler.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class context
|
||||
{
|
||||
public:
|
||||
using fs_callback = std::function<std::pair<buffer, std::vector<u8>>(std::string const&)>;
|
||||
|
||||
context(props props, engine engine, endian endian, system system, u32 str_count);
|
||||
|
||||
auto props() const -> props { return props_; }
|
||||
|
||||
auto build() const -> build { return build_; }
|
||||
|
||||
auto engine() const -> engine { return engine_; }
|
||||
|
||||
auto endian() const -> endian { return endian_; }
|
||||
|
||||
auto system() const -> system { return system_; }
|
||||
|
||||
auto instance() const -> instance { return instance_; }
|
||||
|
||||
auto str_count() const -> u32 { return str_count_; }
|
||||
|
||||
auto source() -> source& { return source_; }
|
||||
|
||||
auto assembler() -> assembler& { return assembler_; }
|
||||
|
||||
auto disassembler() -> disassembler& { return disassembler_; }
|
||||
|
||||
auto compiler() -> compiler& { return compiler_; }
|
||||
|
||||
auto decompiler() -> decompiler& { return decompiler_; }
|
||||
|
||||
auto func_map() const -> std::unordered_map<std::string_view, u16> const& { return func_map_rev_; }
|
||||
auto meth_map() const -> std::unordered_map<std::string_view, u16> const& { return meth_map_rev_; }
|
||||
|
||||
auto init(gsc::build build, fs_callback callback) -> void;
|
||||
|
||||
auto cleanup() -> void;
|
||||
|
||||
auto engine_name() const -> std::string_view;
|
||||
|
||||
auto opcode_size(opcode op) const -> u32;
|
||||
|
||||
auto opcode_id(opcode op) const -> u8;
|
||||
|
||||
auto opcode_name(opcode op) const -> std::string;
|
||||
|
||||
auto opcode_enum(std::string const& name) const -> opcode;
|
||||
|
||||
auto opcode_enum(u8 id) const -> opcode;
|
||||
|
||||
auto func_id(std::string const& name) const -> u16;
|
||||
|
||||
auto func_name(u16 id) const -> std::string;
|
||||
|
||||
auto func2_id(std::string const& name) const -> u64;
|
||||
|
||||
auto func2_name(u64 id) const -> std::string;
|
||||
|
||||
auto func_exists(std::string const& name) const -> bool;
|
||||
|
||||
auto func_add(std::string const& name, u16 id) -> void;
|
||||
|
||||
auto meth_id(std::string const& name) const -> u16;
|
||||
|
||||
auto meth_name(u16 id) const -> std::string;
|
||||
|
||||
auto meth2_id(std::string const& name) const -> u64;
|
||||
|
||||
auto meth2_name(u64 id) const -> std::string;
|
||||
|
||||
auto meth_exists(std::string const& name) const -> bool;
|
||||
|
||||
auto meth_add(std::string const& name, u16 id) -> void;
|
||||
|
||||
auto token_id(std::string const& name) const -> u32;
|
||||
|
||||
auto token_name(u32 id) const -> std::string;
|
||||
|
||||
auto path_id(std::string const& name) const -> u64;
|
||||
|
||||
auto path_name(u64 id) const -> std::string;
|
||||
|
||||
auto hash_id(std::string const& name) const -> u64;
|
||||
|
||||
auto hash_name(u64 id) const -> std::string;
|
||||
|
||||
auto make_token(std::string_view str) const -> std::string;
|
||||
|
||||
auto load_header(std::string const& name) -> std::tuple<std::string const*, char const*, usize>;
|
||||
|
||||
auto load_include(std::string const& name) -> bool;
|
||||
|
||||
auto init_includes() -> void;
|
||||
|
||||
auto is_includecall(std::string const& name, std::string& path) -> bool;
|
||||
|
||||
protected:
|
||||
gsc::props props_;
|
||||
gsc::build build_;
|
||||
gsc::engine engine_;
|
||||
gsc::endian endian_;
|
||||
gsc::system system_;
|
||||
gsc::instance instance_;
|
||||
u32 str_count_;
|
||||
gsc::source source_;
|
||||
gsc::assembler assembler_;
|
||||
gsc::disassembler disassembler_;
|
||||
gsc::compiler compiler_;
|
||||
gsc::decompiler decompiler_;
|
||||
fs_callback fs_callback_;
|
||||
std::unordered_map<opcode, std::string_view> opcode_map_;
|
||||
std::unordered_map<std::string_view, opcode> opcode_map_rev_;
|
||||
std::unordered_map<u8, opcode> code_map_;
|
||||
std::unordered_map<opcode, u8> code_map_rev_;
|
||||
std::unordered_map<u16, std::string_view> func_map_;
|
||||
std::unordered_map<std::string_view, u16> func_map_rev_;
|
||||
std::unordered_map<u16, std::string_view> meth_map_;
|
||||
std::unordered_map<std::string_view, u16> meth_map_rev_;
|
||||
std::unordered_map<u32, std::string_view> token_map_;
|
||||
std::unordered_map<std::string_view, u32> token_map_rev_;
|
||||
std::unordered_map<u64, std::string_view> func_map2_;
|
||||
std::unordered_map<u64, std::string_view> meth_map2_;
|
||||
std::unordered_map<u64, std::string_view> path_map_;
|
||||
std::unordered_map<u64, std::string_view> hash_map_;
|
||||
std::unordered_map<std::string, std::vector<u8>> header_files_;
|
||||
std::unordered_set<std::string_view> includes_;
|
||||
std::unordered_map<std::string, std::vector<std::string>> include_cache_;
|
||||
std::unordered_set<std::string> new_func_map_;
|
||||
std::unordered_set<std::string> new_meth_map_;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
104
include/xsk/gsc/decompiler.hpp
Normal file
104
include/xsk/gsc/decompiler.hpp
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class decompiler
|
||||
{
|
||||
context const* ctx_;
|
||||
program::ptr program_;
|
||||
decl_function::ptr func_;
|
||||
std::unordered_map<u32, std::string> labels_;
|
||||
std::vector<std::string> expr_labels_;
|
||||
std::vector<std::string> tern_labels_;
|
||||
std::stack<node::ptr> stack_;
|
||||
bool in_waittill_;
|
||||
locjmp locs_;
|
||||
|
||||
public:
|
||||
decompiler(context const* ctx);
|
||||
auto decompile(assembly const& data) -> program::ptr;
|
||||
|
||||
private:
|
||||
auto decompile_function(function const& func) -> void;
|
||||
auto decompile_instruction(instruction const& inst) -> void;
|
||||
auto decompile_expressions(instruction const& inst) -> void;
|
||||
auto decompile_statements(stmt_list& stm) -> void;
|
||||
auto decompile_loops(stmt_list& stm) -> void;
|
||||
auto decompile_switches(stmt_list& stm) -> void;
|
||||
auto decompile_ifelses(stmt_list& stm) -> void;
|
||||
auto decompile_aborts(stmt_list& stm) -> void;
|
||||
auto decompile_tuples(stmt_list& stm) -> void;
|
||||
auto decompile_if(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_ifelse(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_ifelse_end(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_inf(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_loop(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_while(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_dowhile(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_for(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_foreach(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto decompile_switch(stmt_list& stm, usize begin, usize end) -> void;
|
||||
auto find_location_reference(stmt_list const& stm, usize begin, usize end, std::string const& loc) -> bool;
|
||||
auto find_location_index(stmt_list const& stm, std::string const& loc) -> usize;
|
||||
auto last_location_index(stmt_list const& stm, usize index) -> bool;
|
||||
auto process_function(decl_function& func) -> void;
|
||||
auto process_stmt(stmt& stm, scope& scp) -> void;
|
||||
auto process_stmt_list(stmt_list& stm, scope& scp) -> void;
|
||||
auto process_stmt_comp(stmt_comp& stm, scope& scp) -> void;
|
||||
auto process_stmt_dev(stmt_dev& stm, scope& scp) -> void;
|
||||
auto process_stmt_expr(stmt_expr& stm, scope& scp) -> void;
|
||||
auto process_stmt_call(stmt_call& stm, scope& scp) -> void;
|
||||
auto process_stmt_assign(stmt_assign& stm, scope& scp) -> void;
|
||||
auto process_stmt_endon(stmt_endon& stm, scope& scp) -> void;
|
||||
auto process_stmt_notify(stmt_notify& stm, scope& scp) -> void;
|
||||
auto process_stmt_wait(stmt_wait& stm, scope& scp) -> void;
|
||||
auto process_stmt_waittill(stmt_waittill& stm, scope& scp) -> void;
|
||||
auto process_stmt_waittillmatch(stmt_waittillmatch& stm, scope& scp) -> void;
|
||||
auto process_stmt_if(stmt_if& stm, scope& scp) -> void;
|
||||
auto process_stmt_ifelse(stmt_ifelse& stm, scope& scp) -> void;
|
||||
auto process_stmt_while(stmt_while& stm, scope& scp) -> void;
|
||||
auto process_stmt_dowhile(stmt_dowhile& stm, scope& scp) -> void;
|
||||
auto process_stmt_for(stmt_for& stm, scope& scp) -> void;
|
||||
auto process_stmt_foreach(stmt_foreach& stm, scope& scp) -> void;
|
||||
auto process_stmt_switch(stmt_switch& stm, scope& scp) -> void;
|
||||
auto process_stmt_break(stmt_break& stm, scope& scp) -> void;
|
||||
auto process_stmt_continue(stmt_continue& stm, scope& scp) -> void;
|
||||
auto process_stmt_return(stmt_return& stm, scope& scp) -> void;
|
||||
auto process_stmt_asm_create(asm_create& stm, scope& scp) -> void;
|
||||
auto process_stmt_asm_remove(asm_remove& stm, scope& scp) -> void;
|
||||
auto process_expr(expr& exp, scope& scp) -> void;
|
||||
auto process_expr_assign(expr_assign::ptr& exp, scope& scp) -> void;
|
||||
auto process_expr_increment(expr_increment& exp, scope& scp) -> void;
|
||||
auto process_expr_decrement(expr_decrement& exp, scope& scp) -> void;
|
||||
auto process_expr_ternary(expr_ternary& exp, scope& scp) -> void;
|
||||
auto process_expr_binary(expr_binary& exp, scope& scp) -> void;
|
||||
auto process_expr_and(expr_and& exp, scope& scp) -> void;
|
||||
auto process_expr_or(expr_or& exp, scope& scp) -> void;
|
||||
auto process_expr_complement(expr_complement& exp, scope& scp) -> void;
|
||||
auto process_expr_not(expr_not& exp, scope& scp) -> void;
|
||||
auto process_expr_call(expr_call& exp, scope& scp) -> void;
|
||||
auto process_expr_method(expr_method& exp, scope& scp) -> void;
|
||||
auto process_expr_call_pointer(expr_pointer& exp, scope& scp) -> void;
|
||||
auto process_expr_call_function(expr_function& exp, scope& scp) -> void;
|
||||
auto process_expr_method_pointer(expr_pointer& exp, expr& obj, scope& scp) -> void;
|
||||
auto process_expr_method_function(expr_function& exp, expr& obj, scope& scp) -> void;
|
||||
auto process_expr_arguments(expr_arguments& exp, scope& scp) -> void;
|
||||
auto process_expr_add_array(expr_add_array& exp, scope& scp) -> void;
|
||||
auto process_expr_size(expr_size& exp, scope& scp) -> void;
|
||||
auto process_expr_tuple(expr_tuple& exp, scope& scp) -> void;
|
||||
auto process_expr_array(expr_array& exp, scope& scp) -> void;
|
||||
auto process_expr_field(expr_field& exp, scope& scp) -> void;
|
||||
auto process_expr_vector(expr_vector& exp, scope& scp) -> void;
|
||||
auto process_expr_asm_create(expr& exp, scope& scp) -> void;
|
||||
auto process_expr_asm_access(expr& exp, scope& scp) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
45
include/xsk/gsc/disassembler.hpp
Normal file
45
include/xsk/gsc/disassembler.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/utils/reader.hpp"
|
||||
#include "common/types.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class disassembler
|
||||
{
|
||||
context const* ctx_;
|
||||
function::ptr func_;
|
||||
assembly::ptr assembly_;
|
||||
utils::reader script_;
|
||||
utils::reader stack_;
|
||||
|
||||
public:
|
||||
disassembler(context const* ctx);
|
||||
auto disassemble(buffer const& script, buffer const& stack) -> assembly::ptr;
|
||||
auto disassemble(std::vector<u8> const& script, std::vector<u8> const& stack) -> assembly::ptr;
|
||||
auto disassemble(u8 const* script, usize script_size, u8 const* stack, usize stack_size) -> assembly::ptr;
|
||||
|
||||
private:
|
||||
auto dissasemble_function(function& func) -> void;
|
||||
auto dissasemble_instruction(instruction& inst) -> void;
|
||||
auto disassemble_builtin_call(instruction& inst, bool method, bool args) -> void;
|
||||
auto disassemble_local_call(instruction& inst, bool thread) -> void;
|
||||
auto disassemble_far_call(instruction& inst, bool thread) -> void;
|
||||
auto disassemble_switch(instruction& inst) -> void;
|
||||
auto disassemble_end_switch(instruction& inst) -> void;
|
||||
auto disassemble_field_variable(instruction& inst) -> void;
|
||||
auto disassemble_formal_params(instruction& inst) -> void;
|
||||
auto disassemble_jump(instruction& inst, bool expr, bool back) -> void;
|
||||
auto disassemble_offset() -> i32;
|
||||
auto resolve_functions() -> void;
|
||||
auto resolve_function(std::string const& index) -> std::string;
|
||||
auto decrypt_string(std::string const& str) -> std::string;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
26
include/xsk/gsc/engine/h1.hpp
Normal file
26
include/xsk/gsc/engine/h1.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::h1
|
||||
{
|
||||
// H1 PC 1.15.1251288
|
||||
constexpr usize code_count = 154;
|
||||
constexpr usize func_count = 778;
|
||||
constexpr usize meth_count = 1415;
|
||||
constexpr usize token_count = 42947;
|
||||
constexpr u32 max_string_id = 42989;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::h1
|
26
include/xsk/gsc/engine/h2.hpp
Normal file
26
include/xsk/gsc/engine/h2.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::h2
|
||||
{
|
||||
// H2 PC 1.0.1280159
|
||||
constexpr usize code_count = 154;
|
||||
constexpr usize func_count = 800;
|
||||
constexpr usize meth_count = 1491;
|
||||
constexpr usize token_count = 42524;
|
||||
constexpr u32 max_string_id = 54743;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::h2
|
26
include/xsk/gsc/engine/iw5_pc.hpp
Normal file
26
include/xsk/gsc/engine/iw5_pc.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw5_pc
|
||||
{
|
||||
// IW5 PC 1.9.388110
|
||||
constexpr usize code_count = 153;
|
||||
constexpr usize func_count = 455;
|
||||
constexpr usize meth_count = 780;
|
||||
constexpr usize token_count = 6306;
|
||||
constexpr u32 max_string_id = 33386;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw5_pc
|
26
include/xsk/gsc/engine/iw5_ps.hpp
Normal file
26
include/xsk/gsc/engine/iw5_ps.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw5_ps
|
||||
{
|
||||
// IW5 PS
|
||||
constexpr usize code_count = 153;
|
||||
constexpr usize func_count = 452;
|
||||
constexpr usize meth_count = 777;
|
||||
constexpr usize token_count = 14221;
|
||||
constexpr u32 max_string_id = 33360;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw5_ps
|
26
include/xsk/gsc/engine/iw5_xb.hpp
Normal file
26
include/xsk/gsc/engine/iw5_xb.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw5_xb
|
||||
{
|
||||
// IW5 XB 1.8.388110
|
||||
constexpr usize code_count = 153;
|
||||
constexpr usize func_count = 455;
|
||||
constexpr usize meth_count = 779;
|
||||
constexpr usize token_count = 14221;
|
||||
constexpr u32 max_string_id = 33386;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw5_xb
|
26
include/xsk/gsc/engine/iw6_pc.hpp
Normal file
26
include/xsk/gsc/engine/iw6_pc.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw6_pc
|
||||
{
|
||||
// IW6 PC 3.15.146
|
||||
constexpr usize code_count = 153;
|
||||
constexpr usize func_count = 605;
|
||||
constexpr usize meth_count = 1066;
|
||||
constexpr usize token_count = 17657;
|
||||
constexpr u32 max_string_id = 38305;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw6_pc
|
26
include/xsk/gsc/engine/iw6_ps.hpp
Normal file
26
include/xsk/gsc/engine/iw6_ps.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw6_ps
|
||||
{
|
||||
|
||||
constexpr usize code_count = 153;
|
||||
constexpr usize func_count = 3;
|
||||
constexpr usize meth_count = 0;
|
||||
constexpr usize token_count = 0;
|
||||
constexpr u32 max_string_id = 0x95A1;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw6_ps
|
26
include/xsk/gsc/engine/iw6_xb.hpp
Normal file
26
include/xsk/gsc/engine/iw6_xb.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw6_xb
|
||||
{
|
||||
|
||||
constexpr usize code_count = 153;
|
||||
constexpr usize func_count = 3;
|
||||
constexpr usize meth_count = 0;
|
||||
constexpr usize token_count = 0;
|
||||
constexpr u32 max_string_id = 0x8EFA;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw6_xb
|
26
include/xsk/gsc/engine/iw7.hpp
Normal file
26
include/xsk/gsc/engine/iw7.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw7
|
||||
{
|
||||
|
||||
constexpr usize code_count = 153;
|
||||
constexpr usize func_count = 807;
|
||||
constexpr usize meth_count = 1500;
|
||||
constexpr usize token_count = 682;
|
||||
constexpr u32 max_string_id = 0x13FCC;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw7
|
26
include/xsk/gsc/engine/iw8.hpp
Normal file
26
include/xsk/gsc/engine/iw8.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw8
|
||||
{
|
||||
|
||||
constexpr usize code_count = 190;
|
||||
constexpr usize func_count = 1065;
|
||||
constexpr usize meth_count = 2032;
|
||||
constexpr usize token_count = 72014;
|
||||
constexpr u32 max_string_id = 0x1472F;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw8
|
26
include/xsk/gsc/engine/iw9.hpp
Normal file
26
include/xsk/gsc/engine/iw9.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::iw9
|
||||
{
|
||||
|
||||
constexpr usize code_count = 167;
|
||||
constexpr usize func_count = 905;
|
||||
constexpr usize meth_count = 1469;
|
||||
constexpr usize path_count = 1467;
|
||||
constexpr usize hash_count = 73500;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::iw9
|
26
include/xsk/gsc/engine/s1_pc.hpp
Normal file
26
include/xsk/gsc/engine/s1_pc.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::s1_pc
|
||||
{
|
||||
|
||||
constexpr usize code_count = 154;
|
||||
constexpr usize func_count = 735;
|
||||
constexpr usize meth_count = 1389;
|
||||
constexpr usize token_count = 42942;
|
||||
constexpr u32 max_string_id = 0xA7DC;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::s1_pc
|
26
include/xsk/gsc/engine/s1_ps.hpp
Normal file
26
include/xsk/gsc/engine/s1_ps.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::s1_ps
|
||||
{
|
||||
|
||||
constexpr usize code_count = 154;
|
||||
constexpr usize func_count = 3;
|
||||
constexpr usize meth_count = 0;
|
||||
constexpr usize token_count = 0;
|
||||
constexpr u32 max_string_id = 0xA51D; // TODO
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::s1_ps
|
26
include/xsk/gsc/engine/s1_xb.hpp
Normal file
26
include/xsk/gsc/engine/s1_xb.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::s1_xb
|
||||
{
|
||||
|
||||
constexpr usize code_count = 154;
|
||||
constexpr usize func_count = 3;
|
||||
constexpr usize meth_count = 0;
|
||||
constexpr usize token_count = 0;
|
||||
constexpr u32 max_string_id = 0xA51D;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::s1_xb
|
26
include/xsk/gsc/engine/s2.hpp
Normal file
26
include/xsk/gsc/engine/s2.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::s2
|
||||
{
|
||||
|
||||
constexpr usize code_count = 155;
|
||||
constexpr usize func_count = 1000;
|
||||
constexpr usize meth_count = 1700;
|
||||
constexpr usize token_count = 5;
|
||||
constexpr u32 max_string_id = 0xACEE;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::s2
|
26
include/xsk/gsc/engine/s4.hpp
Normal file
26
include/xsk/gsc/engine/s4.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::s4
|
||||
{
|
||||
|
||||
constexpr usize code_count = 190;
|
||||
constexpr usize func_count = 4;
|
||||
constexpr usize meth_count = 0;
|
||||
constexpr usize token_count = 0;
|
||||
constexpr u32 max_string_id = 0x110F3;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::s4
|
157
include/xsk/gsc/engine/t4.hpp
Normal file
157
include/xsk/gsc/engine/t4.hpp
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::t4
|
||||
{
|
||||
|
||||
enum class opcode : std::uint8_t
|
||||
{
|
||||
OP_End = 0x0,
|
||||
OP_Return = 0x1,
|
||||
OP_GetUndefined = 0x2,
|
||||
OP_GetZero = 0x3,
|
||||
OP_GetByte = 0x4,
|
||||
OP_GetNegByte = 0x5,
|
||||
OP_GetUnsignedShort = 0x6,
|
||||
OP_GetNegUnsignedShort = 0x7,
|
||||
OP_GetInteger = 0x8,
|
||||
OP_GetFloat = 0x9,
|
||||
OP_GetString = 0xA,
|
||||
OP_GetIString = 0xB,
|
||||
OP_GetVector = 0xC,
|
||||
OP_GetLevelObject = 0xD,
|
||||
OP_GetAnimObject = 0xE,
|
||||
OP_GetSelf = 0xF,
|
||||
OP_GetLevel = 0x10,
|
||||
OP_GetGame = 0x11,
|
||||
OP_GetAnim = 0x12,
|
||||
OP_GetAnimation = 0x13,
|
||||
OP_GetGameRef = 0x14,
|
||||
OP_GetFunction = 0x15,
|
||||
OP_CreateLocalVariable = 0x16,
|
||||
OP_RemoveLocalVariables = 0x17,
|
||||
OP_EvalLocalVariableCached0 = 0x18,
|
||||
OP_EvalLocalVariableCached1 = 0x19,
|
||||
OP_EvalLocalVariableCached2 = 0x1A,
|
||||
OP_EvalLocalVariableCached3 = 0x1B,
|
||||
OP_EvalLocalVariableCached4 = 0x1C,
|
||||
OP_EvalLocalVariableCached5 = 0x1D,
|
||||
OP_EvalLocalVariableCached = 0x1E,
|
||||
OP_EvalLocalArrayCached = 0x1F,
|
||||
OP_EvalArray = 0x20,
|
||||
OP_EvalLocalArrayRefCached0 = 0x21,
|
||||
OP_EvalLocalArrayRefCached = 0x22,
|
||||
OP_EvalArrayRef = 0x23,
|
||||
OP_ClearArray = 0x24,
|
||||
OP_EmptyArray = 0x25,
|
||||
OP_GetSelfObject = 0x26,
|
||||
OP_EvalLevelFieldVariable = 0x27,
|
||||
OP_EvalAnimFieldVariable = 0x28,
|
||||
OP_EvalSelfFieldVariable = 0x29,
|
||||
OP_EvalFieldVariable = 0x2A,
|
||||
OP_EvalLevelFieldVariableRef = 0x2B,
|
||||
OP_EvalAnimFieldVariableRef = 0x2C,
|
||||
OP_EvalSelfFieldVariableRef = 0x2D,
|
||||
OP_EvalFieldVariableRef = 0x2E,
|
||||
OP_ClearFieldVariable = 0x2F,
|
||||
OP_SafeCreateVariableFieldCached = 0x30,
|
||||
OP_SafeSetVariableFieldCached0 = 0x31,
|
||||
OP_SafeSetVariableFieldCached = 0x32,
|
||||
OP_SafeSetWaittillVariableFieldCached = 0x33,
|
||||
OP_clearparams = 0x34,
|
||||
OP_checkclearparams = 0x35,
|
||||
OP_EvalLocalVariableRefCached0 = 0x36,
|
||||
OP_EvalLocalVariableRefCached = 0x37,
|
||||
OP_SetLevelFieldVariableField = 0x38,
|
||||
OP_SetVariableField = 0x39,
|
||||
OP_SetAnimFieldVariableField = 0x3A,
|
||||
OP_SetSelfFieldVariableField = 0x3B,
|
||||
OP_SetLocalVariableFieldCached0 = 0x3C,
|
||||
OP_SetLocalVariableFieldCached = 0x3D,
|
||||
OP_CallBuiltin0 = 0x3E,
|
||||
OP_CallBuiltin1 = 0x3F,
|
||||
OP_CallBuiltin2 = 0x40,
|
||||
OP_CallBuiltin3 = 0x41,
|
||||
OP_CallBuiltin4 = 0x42,
|
||||
OP_CallBuiltin5 = 0x43,
|
||||
OP_CallBuiltin = 0x44,
|
||||
OP_CallBuiltinMethod0 = 0x45,
|
||||
OP_CallBuiltinMethod1 = 0x46,
|
||||
OP_CallBuiltinMethod2 = 0x47,
|
||||
OP_CallBuiltinMethod3 = 0x48,
|
||||
OP_CallBuiltinMethod4 = 0x49,
|
||||
OP_CallBuiltinMethod5 = 0x4A,
|
||||
OP_CallBuiltinMethod = 0x4B,
|
||||
OP_wait = 0x4C,
|
||||
OP_waittillFrameEnd = 0x4D,
|
||||
OP_PreScriptCall = 0x4E,
|
||||
OP_ScriptFunctionCall2 = 0x4F,
|
||||
OP_ScriptFunctionCall = 0x50,
|
||||
OP_ScriptFunctionCallPointer = 0x51,
|
||||
OP_ScriptMethodCall = 0x52,
|
||||
OP_ScriptMethodCallPointer = 0x53,
|
||||
OP_ScriptThreadCall = 0x54,
|
||||
OP_ScriptThreadCallPointer = 0x55,
|
||||
OP_ScriptMethodThreadCall = 0x56,
|
||||
OP_ScriptMethodThreadCallPointer = 0x57,
|
||||
OP_DecTop = 0x58,
|
||||
OP_CastFieldObject = 0x59,
|
||||
OP_EvalLocalVariableObjectCached = 0x5A,
|
||||
OP_CastBool = 0x5B,
|
||||
OP_BoolNot = 0x5C,
|
||||
OP_BoolComplement = 0x5D,
|
||||
OP_JumpOnFalse = 0x5E,
|
||||
OP_JumpOnTrue = 0x5F,
|
||||
OP_JumpOnFalseExpr = 0x60,
|
||||
OP_JumpOnTrueExpr = 0x61,
|
||||
OP_jump = 0x62,
|
||||
OP_jumpback = 0x63,
|
||||
OP_inc = 0x64,
|
||||
OP_dec = 0x65,
|
||||
OP_bit_or = 0x66,
|
||||
OP_bit_ex_or = 0x67,
|
||||
OP_bit_and = 0x68,
|
||||
OP_equality = 0x69,
|
||||
OP_inequality = 0x6A,
|
||||
OP_less = 0x6B,
|
||||
OP_greater = 0x6C,
|
||||
OP_less_equal = 0x6D,
|
||||
OP_greater_equal = 0x6E,
|
||||
OP_shift_left = 0x6F,
|
||||
OP_shift_right = 0x70,
|
||||
OP_plus = 0x71,
|
||||
OP_minus = 0x72,
|
||||
OP_multiply = 0x73,
|
||||
OP_divide = 0x74,
|
||||
OP_mod = 0x75,
|
||||
OP_size = 0x76,
|
||||
OP_waittillmatch = 0x77,
|
||||
OP_waittill = 0x78,
|
||||
OP_notify = 0x79,
|
||||
OP_endon = 0x7A,
|
||||
OP_voidCodepos = 0x7B,
|
||||
OP_switch = 0x7C,
|
||||
OP_endswitch = 0x7D,
|
||||
OP_vector = 0x7E,
|
||||
OP_NOP = 0x7F,
|
||||
OP_abort = 0x80,
|
||||
OP_object = 0x81,
|
||||
OP_thread_object = 0x82,
|
||||
OP_EvalLocalVariable = 0x83,
|
||||
OP_EvalLocalVariableRef = 0x84,
|
||||
OP_prof_begin = 0x85,
|
||||
OP_prof_end = 0x86,
|
||||
OP_breakpoint = 0x87,
|
||||
OP_assignmentBreakpoint = 0x88,
|
||||
OP_manualAndAssignmentBreakpoint = 0x89,
|
||||
OP_count = 0x8A,
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::t4
|
157
include/xsk/gsc/engine/t5.hpp
Normal file
157
include/xsk/gsc/engine/t5.hpp
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/gsc/context.hpp"
|
||||
|
||||
namespace xsk::gsc::t5
|
||||
{
|
||||
|
||||
enum class opcode : std::uint8_t
|
||||
{
|
||||
OP_End = 0x0,
|
||||
OP_Return = 0x1,
|
||||
OP_GetUndefined = 0x2,
|
||||
OP_GetZero = 0x3,
|
||||
OP_GetByte = 0x4,
|
||||
OP_GetNegByte = 0x5,
|
||||
OP_GetUnsignedShort = 0x6,
|
||||
OP_GetNegUnsignedShort = 0x7,
|
||||
OP_GetInteger = 0x8,
|
||||
OP_GetFloat = 0x9,
|
||||
OP_GetString = 0xA,
|
||||
OP_GetIString = 0xB,
|
||||
OP_GetVector = 0xC,
|
||||
OP_GetLevelObject = 0xD,
|
||||
OP_GetAnimObject = 0xE,
|
||||
OP_GetSelf = 0xF,
|
||||
OP_GetLevel = 0x10,
|
||||
OP_GetGame = 0x11,
|
||||
OP_GetAnim = 0x12,
|
||||
OP_GetAnimation = 0x13,
|
||||
OP_GetGameRef = 0x14,
|
||||
OP_GetFunction = 0x15,
|
||||
OP_CreateLocalVariable = 0x16,
|
||||
OP_RemoveLocalVariables = 0x17,
|
||||
OP_EvalLocalVariableCached0 = 0x18,
|
||||
OP_EvalLocalVariableCached1 = 0x19,
|
||||
OP_EvalLocalVariableCached2 = 0x1A,
|
||||
OP_EvalLocalVariableCached3 = 0x1B,
|
||||
OP_EvalLocalVariableCached4 = 0x1C,
|
||||
OP_EvalLocalVariableCached5 = 0x1D,
|
||||
OP_EvalLocalVariableCached = 0x1E,
|
||||
OP_EvalLocalArrayCached = 0x1F,
|
||||
OP_EvalArray = 0x20,
|
||||
OP_EvalLocalArrayRefCached0 = 0x21,
|
||||
OP_EvalLocalArrayRefCached = 0x22,
|
||||
OP_EvalArrayRef = 0x23,
|
||||
OP_ClearArray = 0x24,
|
||||
OP_EmptyArray = 0x25,
|
||||
OP_GetSelfObject = 0x26,
|
||||
OP_EvalLevelFieldVariable = 0x27,
|
||||
OP_EvalAnimFieldVariable = 0x28,
|
||||
OP_EvalSelfFieldVariable = 0x29,
|
||||
OP_EvalFieldVariable = 0x2A,
|
||||
OP_EvalLevelFieldVariableRef = 0x2B,
|
||||
OP_EvalAnimFieldVariableRef = 0x2C,
|
||||
OP_EvalSelfFieldVariableRef = 0x2D,
|
||||
OP_EvalFieldVariableRef = 0x2E,
|
||||
OP_ClearFieldVariable = 0x2F,
|
||||
OP_SafeCreateVariableFieldCached = 0x30,
|
||||
OP_SafeSetVariableFieldCached0 = 0x31,
|
||||
OP_SafeSetVariableFieldCached = 0x32,
|
||||
OP_SafeSetWaittillVariableFieldCached = 0x33,
|
||||
OP_clearparams = 0x34,
|
||||
OP_checkclearparams = 0x35,
|
||||
OP_EvalLocalVariableRefCached0 = 0x36,
|
||||
OP_EvalLocalVariableRefCached = 0x37,
|
||||
OP_SetLevelFieldVariableField = 0x38,
|
||||
OP_SetVariableField = 0x39,
|
||||
OP_SetAnimFieldVariableField = 0x3A,
|
||||
OP_SetSelfFieldVariableField = 0x3B,
|
||||
OP_SetLocalVariableFieldCached0 = 0x3C,
|
||||
OP_SetLocalVariableFieldCached = 0x3D,
|
||||
OP_CallBuiltin0 = 0x3E,
|
||||
OP_CallBuiltin1 = 0x3F,
|
||||
OP_CallBuiltin2 = 0x40,
|
||||
OP_CallBuiltin3 = 0x41,
|
||||
OP_CallBuiltin4 = 0x42,
|
||||
OP_CallBuiltin5 = 0x43,
|
||||
OP_CallBuiltin = 0x44,
|
||||
OP_CallBuiltinMethod0 = 0x45,
|
||||
OP_CallBuiltinMethod1 = 0x46,
|
||||
OP_CallBuiltinMethod2 = 0x47,
|
||||
OP_CallBuiltinMethod3 = 0x48,
|
||||
OP_CallBuiltinMethod4 = 0x49,
|
||||
OP_CallBuiltinMethod5 = 0x4A,
|
||||
OP_CallBuiltinMethod = 0x4B,
|
||||
OP_wait = 0x4C,
|
||||
OP_waittillFrameEnd = 0x4D,
|
||||
OP_PreScriptCall = 0x4E,
|
||||
OP_ScriptFunctionCall2 = 0x4F,
|
||||
OP_ScriptFunctionCall = 0x50,
|
||||
OP_ScriptFunctionCallPointer = 0x51,
|
||||
OP_ScriptMethodCall = 0x52,
|
||||
OP_ScriptMethodCallPointer = 0x53,
|
||||
OP_ScriptThreadCall = 0x54,
|
||||
OP_ScriptThreadCallPointer = 0x55,
|
||||
OP_ScriptMethodThreadCall = 0x56,
|
||||
OP_ScriptMethodThreadCallPointer = 0x57,
|
||||
OP_DecTop = 0x58,
|
||||
OP_CastFieldObject = 0x59,
|
||||
OP_EvalLocalVariableObjectCached = 0x5A,
|
||||
OP_CastBool = 0x5B,
|
||||
OP_BoolNot = 0x5C,
|
||||
OP_BoolComplement = 0x5D,
|
||||
OP_JumpOnFalse = 0x5E,
|
||||
OP_JumpOnTrue = 0x5F,
|
||||
OP_JumpOnFalseExpr = 0x60,
|
||||
OP_JumpOnTrueExpr = 0x61,
|
||||
OP_jump = 0x62,
|
||||
OP_jumpback = 0x63,
|
||||
OP_inc = 0x64,
|
||||
OP_dec = 0x65,
|
||||
OP_bit_or = 0x66,
|
||||
OP_bit_ex_or = 0x67,
|
||||
OP_bit_and = 0x68,
|
||||
OP_equality = 0x69,
|
||||
OP_inequality = 0x6A,
|
||||
OP_less = 0x6B,
|
||||
OP_greater = 0x6C,
|
||||
OP_less_equal = 0x6D,
|
||||
OP_greater_equal = 0x6E,
|
||||
OP_shift_left = 0x6F,
|
||||
OP_shift_right = 0x70,
|
||||
OP_plus = 0x71,
|
||||
OP_minus = 0x72,
|
||||
OP_multiply = 0x73,
|
||||
OP_divide = 0x74,
|
||||
OP_mod = 0x75,
|
||||
OP_size = 0x76,
|
||||
OP_waittillmatch = 0x77,
|
||||
OP_waittill = 0x78,
|
||||
OP_notify = 0x79,
|
||||
OP_endon = 0x7A,
|
||||
OP_voidCodepos = 0x7B,
|
||||
OP_switch = 0x7C,
|
||||
OP_endswitch = 0x7D,
|
||||
OP_vector = 0x7E,
|
||||
OP_NOP = 0x7F,
|
||||
OP_abort = 0x80,
|
||||
OP_object = 0x81,
|
||||
OP_thread_object = 0x82,
|
||||
OP_EvalLocalVariable = 0x83,
|
||||
OP_EvalLocalVariableRef = 0x84,
|
||||
OP_prof_begin = 0x85,
|
||||
OP_prof_end = 0x86,
|
||||
OP_breakpoint = 0x87,
|
||||
OP_assignmentBreakpoint = 0x88,
|
||||
OP_manualAndAssignmentBreakpoint = 0x89,
|
||||
OP_count = 0x8A,
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::t5
|
33
include/xsk/gsc/lexer.hpp
Normal file
33
include/xsk/gsc/lexer.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class lexer
|
||||
{
|
||||
context const* ctx_;
|
||||
lookahead reader_;
|
||||
location loc_;
|
||||
usize buflen_;
|
||||
spacing spacing_;
|
||||
bool indev_;
|
||||
std::array<char, 0x1000> buffer_;
|
||||
|
||||
public:
|
||||
lexer(context const* ctx, std::string const& name, char const* data, usize size);
|
||||
auto lex() -> token;
|
||||
|
||||
private:
|
||||
auto push(char c) -> void;
|
||||
auto advance() -> void;
|
||||
auto linewrap() -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
5801
include/xsk/gsc/parser.hpp
Normal file
5801
include/xsk/gsc/parser.hpp
Normal file
File diff suppressed because it is too large
Load Diff
86
include/xsk/gsc/preprocessor.hpp
Normal file
86
include/xsk/gsc/preprocessor.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
#include "lexer.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class preprocessor
|
||||
{
|
||||
context* ctx_;
|
||||
std::stack<lexer> lexer_;
|
||||
std::stack<directive> indents_;
|
||||
std::vector<std::string> includes_;
|
||||
std::unordered_map<std::string_view, directive::kind> directives_;
|
||||
std::unordered_map<std::string, define> defines_;
|
||||
std::set<std::string> reject_;
|
||||
std::deque<token> tokens_;
|
||||
std::vector<token> expr_;
|
||||
usize curr_expr_;
|
||||
u32 expand_;
|
||||
u32 skip_;
|
||||
|
||||
public:
|
||||
preprocessor(context* ctx, std::string const& name, char const* data, usize size);
|
||||
auto process() -> token;
|
||||
auto push_header(std::string const& file) -> void;
|
||||
auto pop_header() -> void;
|
||||
auto ban_header(location const& loc) -> void;
|
||||
|
||||
private:
|
||||
auto skip_line() -> void;
|
||||
auto next_token() -> token;
|
||||
auto read_token() -> token;
|
||||
auto read_directive(token& tok) -> void;
|
||||
auto read_directive_if(token& tok) -> void;
|
||||
auto read_directive_ifdef(token& tok) -> void;
|
||||
auto read_directive_ifndef(token& tok) -> void;
|
||||
auto read_directive_elif(token& tok) -> void;
|
||||
auto read_directive_elifdef(token& tok) -> void;
|
||||
auto read_directive_elifndef(token& tok) -> void;
|
||||
auto read_directive_else(token& tok) -> void;
|
||||
auto read_directive_endif(token& tok) -> void;
|
||||
auto read_directive_define(token& tok) -> void;
|
||||
auto read_directive_undef(token& tok) -> void;
|
||||
auto read_directive_pragma(token& tok) -> void;
|
||||
auto read_directive_warning(token& tok) -> void;
|
||||
auto read_directive_error(token& tok) -> void;
|
||||
auto read_directive_line(token& tok) -> void;
|
||||
auto read_directive_include(token& hash, token& name) -> void;
|
||||
auto read_directive_inline(token& hash, token& name) -> void;
|
||||
auto read_directive_usingtree(token& hash, token& name) -> void;
|
||||
auto read_hashtoken(token& hash) -> void;
|
||||
auto read_hashtoken_animtree(token& hash, token& name) -> void;
|
||||
auto expand(token& tok, define& def) -> void;
|
||||
auto expand_params(token& tok, define& def) -> std::vector<std::vector<token>>;
|
||||
auto expect(token& tok, token::kind expected, spacing space = spacing::none) -> void;
|
||||
auto evaluate() -> bool;
|
||||
auto eval_next() -> token&;
|
||||
auto eval_peek() -> token&;
|
||||
auto eval_prev() -> token&;
|
||||
auto eval_atend() -> bool;
|
||||
auto eval_check(token::kind type) -> bool;
|
||||
auto eval_match(token::kind type) -> bool;
|
||||
auto eval_consume(token::kind type, std::string_view msg);
|
||||
auto eval_expr() -> i32;
|
||||
auto eval_expr_or() -> i32;
|
||||
auto eval_expr_and() -> i32;
|
||||
auto eval_expr_bwor() -> i32;
|
||||
auto eval_expr_bwexor() -> i32;
|
||||
auto eval_expr_bwand() -> i32;
|
||||
auto eval_expr_eq() -> i32;
|
||||
auto eval_expr_lge() -> i32;
|
||||
auto eval_expr_shift() -> i32;
|
||||
auto eval_expr_add() -> i32;
|
||||
auto eval_expr_factor() -> i32;
|
||||
auto eval_expr_unary() -> i32;
|
||||
auto eval_expr_primary() -> i32;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
159
include/xsk/gsc/source.hpp
Normal file
159
include/xsk/gsc/source.hpp
Normal file
@ -0,0 +1,159 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class source
|
||||
{
|
||||
context* ctx_;
|
||||
std::vector<u8> buf_;
|
||||
u32 indent_;
|
||||
|
||||
public:
|
||||
source(context* ctx);
|
||||
auto parse_assembly(buffer const& data) -> assembly::ptr;
|
||||
auto parse_assembly(std::vector<u8> const& data) -> assembly::ptr;
|
||||
auto parse_assembly(u8 const* data, usize size) -> assembly::ptr;
|
||||
auto parse_program(std::string const& name, buffer const& data) -> program::ptr;
|
||||
auto parse_program(std::string const& name, std::vector<u8> const& data) -> program::ptr;
|
||||
auto parse_program(std::string const& name, u8 const* data, usize size) -> program::ptr;
|
||||
auto dump(assembly const& data) -> std::vector<u8>;
|
||||
auto dump(program const& data) -> std::vector<u8>;
|
||||
|
||||
private:
|
||||
auto dump_assembly(assembly const& data) -> void;
|
||||
auto dump_function(function const& func) -> void;
|
||||
auto dump_instruction(instruction const& inst) -> void;
|
||||
auto dump_program(program const& data) -> void;
|
||||
auto dump_include(include const& inc) -> void;
|
||||
auto dump_decl(decl const& dec) -> void;
|
||||
auto dump_decl_dev_begin(decl_dev_begin const& dec) -> void;
|
||||
auto dump_decl_dev_end(decl_dev_end const& dec) -> void;
|
||||
auto dump_decl_usingtree(decl_usingtree const& dec) -> void;
|
||||
auto dump_decl_constant(decl_constant const& dec) -> void;
|
||||
auto dump_decl_function(decl_function const& dec) -> void;
|
||||
auto dump_stmt(stmt const& stm) -> void;
|
||||
auto dump_stmt_list(stmt_list const& stm) -> void;
|
||||
auto dump_stmt_comp(stmt_comp const& stm) -> void;
|
||||
auto dump_stmt_dev(stmt_dev const& stm) -> void;
|
||||
auto dump_stmt_expr(stmt_expr const& stm) -> void;
|
||||
auto dump_stmt_call(stmt_call const& stm) -> void;
|
||||
auto dump_stmt_assign(stmt_assign const& stm) -> void;
|
||||
auto dump_stmt_endon(stmt_endon const& stm) -> void;
|
||||
auto dump_stmt_notify(stmt_notify const& stm) -> void;
|
||||
auto dump_stmt_wait(stmt_wait const& stm) -> void;
|
||||
auto dump_stmt_waittill(stmt_waittill const& stm) -> void;
|
||||
auto dump_stmt_waittillmatch(stmt_waittillmatch const& stm) -> void;
|
||||
auto dump_stmt_waittillframeend(stmt_waittillframeend const& stm) -> void;
|
||||
auto dump_stmt_waitframe(stmt_waitframe const& stm) -> void;
|
||||
auto dump_stmt_if(stmt_if const& stm) -> void;
|
||||
auto dump_stmt_ifelse(stmt_ifelse const& stm) -> void;
|
||||
auto dump_stmt_while(stmt_while const& stm) -> void;
|
||||
auto dump_stmt_dowhile(stmt_dowhile const& stm) -> void;
|
||||
auto dump_stmt_for(stmt_for const& stm) -> void;
|
||||
auto dump_stmt_foreach(stmt_foreach const& stm) -> void;
|
||||
auto dump_stmt_switch(stmt_switch const& stm) -> void;
|
||||
auto dump_stmt_case(stmt_case const& stm) -> void;
|
||||
auto dump_stmt_default(stmt_default const& stm) -> void;
|
||||
auto dump_stmt_break(stmt_break const& stm) -> void;
|
||||
auto dump_stmt_continue(stmt_continue const& stm) -> void;
|
||||
auto dump_stmt_return(stmt_return const& stm) -> void;
|
||||
auto dump_stmt_breakpoint(stmt_breakpoint const& stm) -> void;
|
||||
auto dump_stmt_prof_begin(stmt_prof_begin const& stm) -> void;
|
||||
auto dump_stmt_prof_end(stmt_prof_end const& stm) -> void;
|
||||
auto dump_stmt_assert(stmt_assert const& stm) -> void;
|
||||
auto dump_stmt_assertex(stmt_assertex const& stm) -> void;
|
||||
auto dump_stmt_assertmsg(stmt_assertmsg const& stm) -> void;
|
||||
auto dump_expr(expr const& exp) -> void;
|
||||
auto dump_expr_increment(expr_increment const& exp) -> void;
|
||||
auto dump_expr_decrement(expr_decrement const& exp) -> void;
|
||||
auto dump_expr_assign_equal(expr_assign_equal const& exp) -> void;
|
||||
auto dump_expr_assign_add(expr_assign_add const& exp) -> void;
|
||||
auto dump_expr_assign_sub(expr_assign_sub const& exp) -> void;
|
||||
auto dump_expr_assign_mul(expr_assign_mul const& exp) -> void;
|
||||
auto dump_expr_assign_div(expr_assign_div const& exp) -> void;
|
||||
auto dump_expr_assign_mod(expr_assign_mod const& exp) -> void;
|
||||
auto dump_expr_assign_shift_left(expr_assign_shift_left const& exp) -> void;
|
||||
auto dump_expr_assign_shift_right(expr_assign_shift_right const& exp) -> void;
|
||||
auto dump_expr_assign_bitwise_or(expr_assign_bitwise_or const& exp) -> void;
|
||||
auto dump_expr_assign_bitwise_and(expr_assign_bitwise_and const& exp) -> void;
|
||||
auto dump_expr_assign_bitwise_exor(expr_assign_bitwise_exor const& exp) -> void;
|
||||
auto dump_expr_ternary(expr_ternary const& exp) -> void;
|
||||
auto dump_expr_or(expr_or const& exp) -> void;
|
||||
auto dump_expr_and(expr_and const& exp) -> void;
|
||||
auto dump_expr_equality(expr_equality const& exp) -> void;
|
||||
auto dump_expr_inequality(expr_inequality const& exp) -> void;
|
||||
auto dump_expr_less_equal(expr_less_equal const& exp) -> void;
|
||||
auto dump_expr_greater_equal(expr_greater_equal const& exp) -> void;
|
||||
auto dump_expr_less(expr_less const& exp) -> void;
|
||||
auto dump_expr_greater(expr_greater const& exp) -> void;
|
||||
auto dump_expr_add(expr_add const& exp) -> void;
|
||||
auto dump_expr_sub(expr_sub const& exp) -> void;
|
||||
auto dump_expr_mul(expr_mul const& exp) -> void;
|
||||
auto dump_expr_div(expr_div const& exp) -> void;
|
||||
auto dump_expr_mod(expr_mod const& exp) -> void;
|
||||
auto dump_expr_shift_left(expr_shift_left const& exp) -> void;
|
||||
auto dump_expr_shift_right(expr_shift_right const& exp) -> void;
|
||||
auto dump_expr_bitwise_or(expr_bitwise_or const& exp) -> void;
|
||||
auto dump_expr_bitwise_and(expr_bitwise_and const& exp) -> void;
|
||||
auto dump_expr_bitwise_exor(expr_bitwise_exor const& exp) -> void;
|
||||
auto dump_expr_not(expr_not const& exp) -> void;
|
||||
auto dump_expr_negate(expr_negate const& exp) -> void;
|
||||
auto dump_expr_complement(expr_complement const& exp) -> void;
|
||||
auto dump_expr_call(expr_call const& exp) -> void;
|
||||
auto dump_expr_method(expr_method const& exp) -> void;
|
||||
auto dump_call(call const& exp) -> void;
|
||||
auto dump_expr_function(expr_function const& exp) -> void;
|
||||
auto dump_expr_pointer(expr_pointer const& exp) -> void;
|
||||
auto dump_expr_add_array(expr_add_array const& exp) -> void;
|
||||
auto dump_expr_parameters(expr_parameters const& exp) -> void;
|
||||
auto dump_expr_arguments(expr_arguments const& exp) -> void;
|
||||
auto dump_expr_isdefined(expr_isdefined const& exp) -> void;
|
||||
auto dump_expr_istrue(expr_istrue const& exp) -> void;
|
||||
auto dump_expr_reference(expr_reference const& exp) -> void;
|
||||
auto dump_expr_tuple(expr_tuple const& exp) -> void;
|
||||
auto dump_expr_array(expr_array const& exp) -> void;
|
||||
auto dump_expr_field(expr_field const& exp) -> void;
|
||||
auto dump_expr_size(expr_size const& exp) -> void;
|
||||
auto dump_expr_paren(expr_paren const& exp) -> void;
|
||||
auto dump_expr_thisthread(expr_thisthread const& exp) -> void;
|
||||
auto dump_expr_empty_array(expr_empty_array const& exp) -> void;
|
||||
auto dump_expr_undefined(expr_undefined const& exp) -> void;
|
||||
auto dump_expr_game(expr_game const& exp) -> void;
|
||||
auto dump_expr_self(expr_self const& exp) -> void;
|
||||
auto dump_expr_anim(expr_anim const& exp) -> void;
|
||||
auto dump_expr_level(expr_level const& exp) -> void;
|
||||
auto dump_expr_animation(expr_animation const& exp) -> void;
|
||||
auto dump_expr_animtree(expr_animtree const& exp) -> void;
|
||||
auto dump_expr_identifier(expr_identifier const& exp) -> void;
|
||||
auto dump_expr_path(expr_path const& exp) -> void;
|
||||
auto dump_expr_istring(expr_istring const& exp) -> void;
|
||||
auto dump_expr_string(expr_string const& exp) -> void;
|
||||
auto dump_expr_vector(expr_vector const& exp) -> void;
|
||||
auto dump_expr_float(expr_float const& exp) -> void;
|
||||
auto dump_expr_integer(expr_integer const& exp) -> void;
|
||||
auto dump_expr_false(expr_false const& exp) -> void;
|
||||
auto dump_expr_true(expr_true const& exp) -> void;
|
||||
auto dump_asm_jmp(asm_jmp const& exp) -> void;
|
||||
auto dump_asm_jmp_back(asm_jmp_back const& exp) -> void;
|
||||
auto dump_asm_jmp_cond(asm_jmp_cond const& exp) -> void;
|
||||
auto dump_asm_jmp_true(asm_jmp_true const& exp) -> void;
|
||||
auto dump_asm_jmp_false(asm_jmp_false const& exp) -> void;
|
||||
auto dump_asm_switch(asm_switch const& exp) -> void;
|
||||
auto dump_asm_endswitch(asm_endswitch const& exp) -> void;
|
||||
auto dump_asm_prescriptcall(asm_prescriptcall const& exp) -> void;
|
||||
auto dump_asm_voidcodepos(asm_voidcodepos const& exp) -> void;
|
||||
auto dump_asm_create(asm_create const& exp) -> void;
|
||||
auto dump_asm_access(asm_access const& exp) -> void;
|
||||
auto dump_asm_remove(asm_remove const& exp) -> void;
|
||||
auto dump_asm_clear(asm_clear const& exp) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
62
include/xsk/stdinc.hpp
Normal file
62
include/xsk/stdinc.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#if _WIN32
|
||||
#include <format>
|
||||
namespace fmt = std;
|
||||
#else
|
||||
#include <fmt/core.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
#undef ERROR
|
||||
#undef IN
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
#undef far
|
||||
#endif
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace xsk
|
||||
{
|
||||
|
||||
using usize = std::size_t;
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u64 = std::uint64_t;
|
||||
using i8 = std::int8_t;
|
||||
using i16 = std::int16_t;
|
||||
using i32 = std::int32_t;
|
||||
using i64 = std::int64_t;
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
};
|
47
include/xsk/t6/assembler.hpp
Normal file
47
include/xsk/t6/assembler.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
class assembler : public arc::assembler
|
||||
{
|
||||
std::string filename_;
|
||||
utils::writer::ptr script_;
|
||||
assembly::ptr assembly_;
|
||||
std::unordered_map<std::uint32_t, std::string> labels_;
|
||||
std::unordered_map<std::string, std::uint16_t> stringlist_;
|
||||
std::vector<export_ref> exports_;
|
||||
std::vector<import_ref> imports_;
|
||||
std::vector<animtree_ref> animtrees_;
|
||||
std::vector<string_ref> stringtables_;
|
||||
header header_;
|
||||
|
||||
public:
|
||||
auto output() -> std::vector<std::uint8_t>;
|
||||
void assemble(const std::string& file, std::vector<std::uint8_t>& data);
|
||||
void assemble(const std::string& file, assembly::ptr& data);
|
||||
|
||||
private:
|
||||
void assemble_function(const function::ptr& func);
|
||||
void assemble_instruction(const instruction::ptr& inst);
|
||||
void assemble_localvars(const instruction::ptr& inst);
|
||||
void assemble_jump(const instruction::ptr& inst);
|
||||
void assemble_switch(const instruction::ptr& inst);
|
||||
void assemble_end_switch(const instruction::ptr& inst);
|
||||
void process_string(const std::string& data);
|
||||
void process_function(const function::ptr& func);
|
||||
void process_instruction(const instruction::ptr& inst);
|
||||
void align_instruction(const instruction::ptr& inst);
|
||||
auto resolve_label(const std::string& name) -> std::int32_t;
|
||||
auto string_offset(const std::string& data) -> std::uint16_t;
|
||||
void add_string_reference(const std::string& str, string_type type, std::uint32_t ref);
|
||||
void add_import_reference(const std::vector<std::string>& data, std::uint32_t ref);
|
||||
void add_anim_reference(const std::vector<std::string>& data, std::uint32_t ref);
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t6
|
18
include/xsk/t6/common/arc.hpp
Normal file
18
include/xsk/t6/common/arc.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "location.hpp"
|
||||
#include "types.hpp"
|
||||
#include "block.hpp"
|
||||
#include "nodetree.hpp"
|
||||
|
||||
#include "interfaces/exception.hpp"
|
||||
#include "interfaces/assembler.hpp"
|
||||
#include "interfaces/disassembler.hpp"
|
||||
#include "interfaces/compiler.hpp"
|
||||
#include "interfaces/decompiler.hpp"
|
||||
#include "interfaces/context.hpp"
|
25
include/xsk/t6/common/block.hpp
Normal file
25
include/xsk/t6/common/block.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
struct block
|
||||
{
|
||||
using ptr = std::unique_ptr<block>;
|
||||
|
||||
std::string loc_end;
|
||||
std::string loc_break;
|
||||
std::string loc_continue;
|
||||
abort_t abort;
|
||||
bool is_dev;
|
||||
|
||||
block() : abort(abort_t::abort_none), is_dev(false) {}
|
||||
block(const std::string& lbreak, const std::string& lcont) : loc_break(lbreak), loc_continue(lcont), abort(abort_t::abort_none), is_dev(false) {}
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
22
include/xsk/t6/common/interfaces/assembler.hpp
Normal file
22
include/xsk/t6/common/interfaces/assembler.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class assembler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<assembler>;
|
||||
|
||||
virtual ~assembler() = default;
|
||||
virtual auto output() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void assemble(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||
virtual void assemble(const std::string& file, assembly::ptr& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
22
include/xsk/t6/common/interfaces/compiler.hpp
Normal file
22
include/xsk/t6/common/interfaces/compiler.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class compiler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<compiler>;
|
||||
|
||||
virtual ~compiler() = default;
|
||||
virtual auto output() -> assembly::ptr = 0;
|
||||
virtual auto output_raw() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void compile(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
26
include/xsk/t6/common/interfaces/context.hpp
Normal file
26
include/xsk/t6/common/interfaces/context.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class context
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<context>;
|
||||
|
||||
virtual ~context() = default;
|
||||
virtual void init(build mode, read_cb_type callback) = 0;
|
||||
virtual void cleanup() = 0;
|
||||
|
||||
virtual auto assembler() -> assembler& = 0;
|
||||
virtual auto disassembler() -> disassembler& = 0;
|
||||
virtual auto compiler() -> compiler& = 0;
|
||||
virtual auto decompiler() -> decompiler& = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
21
include/xsk/t6/common/interfaces/decompiler.hpp
Normal file
21
include/xsk/t6/common/interfaces/decompiler.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class decompiler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<decompiler>;
|
||||
|
||||
virtual ~decompiler() = default;
|
||||
virtual auto output() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void decompile(const std::string& file, const assembly::ptr& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
22
include/xsk/t6/common/interfaces/disassembler.hpp
Normal file
22
include/xsk/t6/common/interfaces/disassembler.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class disassembler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<disassembler>;
|
||||
|
||||
virtual ~disassembler() = default;
|
||||
virtual auto output() -> assembly::ptr = 0;
|
||||
virtual auto output_raw() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void disassemble(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
46
include/xsk/t6/common/interfaces/exception.hpp
Normal file
46
include/xsk/t6/common/interfaces/exception.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]: "s + what) {}
|
||||
};
|
||||
|
||||
class asm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
asm_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:assembler: "s + what) {}
|
||||
};
|
||||
|
||||
class disasm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
disasm_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:disassembler: "s + what) {}
|
||||
};
|
||||
|
||||
class comp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
comp_error(const location& loc, const std::string& what)
|
||||
: std::runtime_error("[ERROR]:compiler:" + loc.print() + ": " + what) {}
|
||||
};
|
||||
|
||||
class decomp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
decomp_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:decompiler: "s + what) {}
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
229
include/xsk/t6/common/location.hpp
Normal file
229
include/xsk/t6/common/location.hpp
Normal file
@ -0,0 +1,229 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
/// A point in a source file.
|
||||
class position
|
||||
{
|
||||
public:
|
||||
/// Type for file name.
|
||||
typedef const std::string filename_type;
|
||||
/// Type for line and column numbers.
|
||||
typedef int counter_type;
|
||||
|
||||
/// Construct a position.
|
||||
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
: filename(f), line(l), column(c) {}
|
||||
|
||||
/// Initialization.
|
||||
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
filename = fn;
|
||||
line = l;
|
||||
column = c;
|
||||
}
|
||||
|
||||
/** \name Line and Column related manipulators
|
||||
** \{ */
|
||||
/// (line related) Advance to the COUNT next lines.
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
column = 1;
|
||||
line = add_(line, count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// (column related) Advance to the COUNT next columns.
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
column = add_(column, count, 1);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
/// File name to which this position refers.
|
||||
filename_type *filename;
|
||||
/// Current line number.
|
||||
counter_type line;
|
||||
/// Current column number.
|
||||
counter_type column;
|
||||
|
||||
private:
|
||||
/// Compute max (min, lhs+rhs).
|
||||
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
||||
{
|
||||
return lhs + rhs < min ? min : lhs + rhs;
|
||||
}
|
||||
};
|
||||
|
||||
/// Add \a width columns, in place.
|
||||
inline position& operator+=(position &res, position::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add \a width columns.
|
||||
inline position operator+(position res, position::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns, in place.
|
||||
inline position& operator-=(position &res, position::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns.
|
||||
inline position operator-(position res, position::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
/** \brief Intercept output stream redirection.
|
||||
** \param ostr the destination output stream
|
||||
** \param pos a reference to the position to redirect
|
||||
*/
|
||||
template <typename YYChar>
|
||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const position &pos)
|
||||
{
|
||||
if (pos.filename)
|
||||
ostr << *pos.filename << ':';
|
||||
return ostr << pos.line << '.' << pos.column;
|
||||
}
|
||||
|
||||
/// Two points in a source file.
|
||||
class location
|
||||
{
|
||||
public:
|
||||
/// Type for file name.
|
||||
typedef position::filename_type filename_type;
|
||||
/// Type for line and column numbers.
|
||||
typedef position::counter_type counter_type;
|
||||
|
||||
/// Construct a location from \a b to \a e.
|
||||
location(const position &b, const position &e)
|
||||
: begin(b), end(e) {}
|
||||
|
||||
/// Construct a 0-width location in \a p.
|
||||
explicit location(const position &p = position())
|
||||
: begin(p), end(p) {}
|
||||
|
||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
||||
: begin(f, l, c), end(f, l, c) {}
|
||||
|
||||
/// Initialization.
|
||||
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
begin.initialize(f, l, c);
|
||||
end = begin;
|
||||
}
|
||||
|
||||
/** \name Line and Column related manipulators
|
||||
** \{ */
|
||||
public:
|
||||
/// Reset initial location to final location.
|
||||
void step()
|
||||
{
|
||||
begin = end;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next columns.
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next lines.
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
end.lines(count);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
public:
|
||||
auto print() const -> std::string
|
||||
{
|
||||
return *begin.filename + ":" + std::to_string(begin.line) + ":" + std::to_string(begin.column);
|
||||
}
|
||||
|
||||
auto label() const -> std::string
|
||||
{
|
||||
return fmt::format("loc_{:X}", begin.line);
|
||||
}
|
||||
|
||||
public:
|
||||
/// Beginning of the located region.
|
||||
position begin;
|
||||
/// End of the located region.
|
||||
position end;
|
||||
};
|
||||
|
||||
/// Join two locations, in place.
|
||||
inline location& operator+=(location &res, const location &end)
|
||||
{
|
||||
res.end = end.end;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Join two locations.
|
||||
inline location operator+(location res, const location &end)
|
||||
{
|
||||
return res += end;
|
||||
}
|
||||
|
||||
/// Add \a width columns to the end position, in place.
|
||||
inline location& operator+=(location &res, location::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add \a width columns to the end position.
|
||||
inline location operator+(location res, location::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns to the end position, in place.
|
||||
inline location& operator-=(location &res, location::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns to the end position.
|
||||
inline location operator-(location res, location::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
/** \brief Intercept output stream redirection.
|
||||
** \param ostr the destination output stream
|
||||
** \param loc a reference to the location to redirect
|
||||
**
|
||||
** Avoid duplicate information.
|
||||
*/
|
||||
template <typename YYChar>
|
||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const location &loc)
|
||||
{
|
||||
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
||||
ostr << loc.begin;
|
||||
if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename))
|
||||
ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.line < loc.end.line)
|
||||
ostr << '-' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.column < end_col)
|
||||
ostr << '-' << end_col;
|
||||
return ostr;
|
||||
}
|
||||
|
||||
} // namespace xsk::arc
|
1952
include/xsk/t6/common/nodetree.hpp
Normal file
1952
include/xsk/t6/common/nodetree.hpp
Normal file
File diff suppressed because it is too large
Load Diff
181
include/xsk/t6/common/types.hpp
Normal file
181
include/xsk/t6/common/types.hpp
Normal file
@ -0,0 +1,181 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
using read_cb_type = std::function<std::vector<std::uint8_t>(const std::string&)>;
|
||||
|
||||
enum class build
|
||||
{
|
||||
prod,
|
||||
dev,
|
||||
};
|
||||
|
||||
enum class abort_t
|
||||
{
|
||||
abort_none = 0,
|
||||
abort_continue = 1,
|
||||
abort_break = 2,
|
||||
abort_return = 3,
|
||||
};
|
||||
|
||||
struct include_t
|
||||
{
|
||||
std::string name;
|
||||
std::vector<std::string> funcs;
|
||||
|
||||
include_t(const std::string& name, const std::vector<std::string>& funcs) : name(name), funcs(funcs) {}
|
||||
};
|
||||
|
||||
struct animtree_t
|
||||
{
|
||||
std::string name;
|
||||
bool loaded;
|
||||
};
|
||||
|
||||
struct instruction
|
||||
{
|
||||
using ptr = std::unique_ptr<instruction>;
|
||||
|
||||
std::uint32_t index;
|
||||
std::uint32_t size;
|
||||
std::uint8_t opcode;
|
||||
std::vector<std::string> data;
|
||||
|
||||
instruction() : index(0), size(0), opcode(0xFF) {}
|
||||
};
|
||||
|
||||
struct function
|
||||
{
|
||||
using ptr = std::unique_ptr<function>;
|
||||
|
||||
std::uint32_t index;
|
||||
std::uint32_t size;
|
||||
std::uint8_t params;
|
||||
std::uint8_t flags;
|
||||
std::string name;
|
||||
std::vector<instruction::ptr> instructions;
|
||||
std::unordered_map<std::uint32_t, std::string> labels;
|
||||
|
||||
function() : index(0), size(0), params(0), flags(0) {}
|
||||
};
|
||||
|
||||
struct animation_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<animation_ref>;
|
||||
|
||||
std::string name;
|
||||
std::uint32_t ref;
|
||||
};
|
||||
|
||||
struct animtree_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<animtree_ref>;
|
||||
|
||||
std::string name;
|
||||
std::vector<std::uint32_t> refs;
|
||||
std::vector<animation_ref> anims;
|
||||
};
|
||||
|
||||
enum class string_type : std::uint8_t
|
||||
{
|
||||
literal = 0,
|
||||
canonical = 1,
|
||||
};
|
||||
|
||||
struct string_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<string_ref>;
|
||||
|
||||
std::string name;
|
||||
std::uint8_t type;
|
||||
std::vector<std::uint32_t> refs;
|
||||
};
|
||||
|
||||
enum class export_flags : std::uint8_t
|
||||
{
|
||||
export_none = 0x00,
|
||||
export_public = 0x01,
|
||||
export_autoexec = 0x02,
|
||||
export_private = 0x04,
|
||||
export_codecall = 0x08,
|
||||
export_private2 = 0x10,
|
||||
export_varargs = 0x20,
|
||||
};
|
||||
|
||||
struct export_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<export_ref>;
|
||||
|
||||
std::uint32_t checksum;
|
||||
std::uint32_t offset;
|
||||
std::string name;
|
||||
std::string space;
|
||||
std::uint8_t params;
|
||||
std::uint8_t flags;
|
||||
std::uint32_t size;
|
||||
};
|
||||
|
||||
enum class import_flags : std::uint8_t
|
||||
{
|
||||
none = 0,
|
||||
func_reference = 1,
|
||||
func_call = 2,
|
||||
func_call_thread = 3,
|
||||
meth_call = 4,
|
||||
meth_call_thread = 5,
|
||||
developer = 0x10,
|
||||
unk = 0x20, // T7, T8, T9
|
||||
};
|
||||
|
||||
struct import_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<import_ref>;
|
||||
|
||||
std::string space;
|
||||
std::string name;
|
||||
std::uint8_t params;
|
||||
std::uint8_t flags;
|
||||
std::vector<std::uint32_t> refs;
|
||||
};
|
||||
|
||||
struct header
|
||||
{
|
||||
std::uint64_t magic;
|
||||
std::uint32_t source_crc;
|
||||
std::uint32_t include_offset;
|
||||
std::uint32_t animtree_offset;
|
||||
std::uint32_t cseg_offset;
|
||||
std::uint32_t stringtablefixup_offset;
|
||||
std::uint32_t exports_offset;
|
||||
std::uint32_t imports_offset;
|
||||
std::uint32_t fixup_offset;
|
||||
std::uint32_t profile_offset;
|
||||
std::uint32_t cseg_size;
|
||||
std::uint16_t name;
|
||||
std::uint16_t stringtablefixup_count;
|
||||
std::uint16_t exports_count;
|
||||
std::uint16_t imports_count;
|
||||
std::uint16_t fixup_count;
|
||||
std::uint16_t profile_count;
|
||||
std::uint8_t include_count;
|
||||
std::uint8_t animtree_count;
|
||||
std::uint8_t flags;
|
||||
// char[1] pad;
|
||||
};
|
||||
|
||||
struct assembly
|
||||
{
|
||||
using ptr = std::unique_ptr<assembly>;
|
||||
|
||||
std::vector<function::ptr> functions;
|
||||
std::vector<std::string> includes;
|
||||
std::vector<animtree_ref> animtrees;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
164
include/xsk/t6/compiler.hpp
Normal file
164
include/xsk/t6/compiler.hpp
Normal file
@ -0,0 +1,164 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
enum class opcode : std::uint8_t;
|
||||
|
||||
class compiler : public arc::compiler
|
||||
{
|
||||
std::string filename_;
|
||||
assembly::ptr assembly_;
|
||||
function::ptr function_;
|
||||
std::uint32_t index_;
|
||||
std::uint32_t label_idx_;
|
||||
std::uint8_t stack_idx_;
|
||||
std::vector<std::string> local_stack_;
|
||||
std::vector<std::string> local_functions_;
|
||||
std::vector<include_t> includes_;
|
||||
std::vector<std::string> animtrees_;
|
||||
std::unordered_map<std::string, ast::expr> constants_;
|
||||
std::vector<block> blocks_;
|
||||
bool can_break_;
|
||||
bool can_continue_;
|
||||
bool developer_thread_;
|
||||
build mode_;
|
||||
utils::writer::ptr output_;
|
||||
|
||||
public:
|
||||
auto output() -> assembly::ptr;
|
||||
auto output_raw() -> std::vector<std::uint8_t>;
|
||||
void compile(const std::string& file, std::vector<std::uint8_t>& data);
|
||||
void mode(build mode);
|
||||
|
||||
private:
|
||||
auto parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr;
|
||||
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||
void compile_program(const ast::program::ptr& program);
|
||||
void emit_include(const ast::include::ptr& include);
|
||||
void emit_declaration(const ast::decl& decl);
|
||||
void emit_decl_usingtree(const ast::decl_usingtree::ptr& animtree);
|
||||
void emit_decl_thread(const ast::decl_thread::ptr& thread);
|
||||
void emit_stmt(const ast::stmt& stmt);
|
||||
void emit_stmt_list(const ast::stmt_list::ptr& stmt);
|
||||
void emit_stmt_dev(const ast::stmt_dev::ptr& stmt);
|
||||
void emit_stmt_expr(const ast::stmt_expr::ptr& stmt);
|
||||
void emit_stmt_call(const ast::stmt_call::ptr& stmt);
|
||||
void emit_stmt_const(const ast::stmt_const::ptr& stmt);
|
||||
void emit_stmt_assign(const ast::stmt_assign::ptr& stmt);
|
||||
void emit_stmt_endon(const ast::stmt_endon::ptr& stmt);
|
||||
void emit_stmt_notify(const ast::stmt_notify::ptr& stmt);
|
||||
void emit_stmt_wait(const ast::stmt_wait::ptr& stmt);
|
||||
void emit_stmt_waittill(const ast::stmt_waittill::ptr& stmt);
|
||||
void emit_stmt_waittillmatch(const ast::stmt_waittillmatch::ptr& stmt);
|
||||
void emit_stmt_waittillframeend(const ast::stmt_waittillframeend::ptr& stmt);
|
||||
void emit_stmt_if(const ast::stmt_if::ptr& stmt);
|
||||
void emit_stmt_ifelse(const ast::stmt_ifelse::ptr& stmt);
|
||||
void emit_stmt_while(const ast::stmt_while::ptr& stmt);
|
||||
void emit_stmt_dowhile(const ast::stmt_dowhile::ptr& stmt);
|
||||
void emit_stmt_for(const ast::stmt_for::ptr& stmt);
|
||||
void emit_stmt_foreach(const ast::stmt_foreach::ptr& stmt);
|
||||
void emit_stmt_switch(const ast::stmt_switch::ptr& stmt);
|
||||
void emit_stmt_case(const ast::stmt_case::ptr& stmt);
|
||||
void emit_stmt_default(const ast::stmt_default::ptr& stmt);
|
||||
void emit_stmt_break(const ast::stmt_break::ptr& stmt);
|
||||
void emit_stmt_continue(const ast::stmt_continue::ptr& stmt);
|
||||
void emit_stmt_return(const ast::stmt_return::ptr& stmt);
|
||||
void emit_stmt_prof_begin(const ast::stmt_prof_begin::ptr& stmt);
|
||||
void emit_stmt_prof_end(const ast::stmt_prof_end::ptr& stmt);
|
||||
void emit_expr(const ast::expr& expr);
|
||||
void emit_expr_assign(const ast::expr_assign::ptr& expr);
|
||||
void emit_expr_clear(const ast::expr& expr);
|
||||
void emit_expr_increment(const ast::expr_increment::ptr& expr, bool is_stmt);
|
||||
void emit_expr_decrement(const ast::expr_decrement::ptr& expr, bool is_stmt);
|
||||
void emit_expr_ternary(const ast::expr_ternary::ptr& expr);
|
||||
void emit_expr_binary(const ast::expr_binary::ptr& expr);
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, bool is_stmt);
|
||||
void emit_expr_call_function(const ast::expr_function::ptr& expr, bool is_stmt);
|
||||
void emit_expr_method(const ast::expr_method::ptr& expr, bool is_stmt);
|
||||
void emit_expr_method_pointer(const ast::expr_pointer::ptr& expr, const ast::expr& obj, bool is_stmt);
|
||||
void emit_expr_method_function(const ast::expr_function::ptr& expr, const ast::expr& obj, bool is_stmt);
|
||||
void emit_expr_parameters(const ast::expr_parameters::ptr& expr);
|
||||
void emit_expr_arguments(const ast::expr_arguments::ptr& expr);
|
||||
void emit_expr_isdefined(const ast::expr_isdefined::ptr& expr);
|
||||
void emit_expr_vectorscale(const ast::expr_vectorscale::ptr& expr);
|
||||
void emit_expr_anglestoup(const ast::expr_anglestoup::ptr& expr);
|
||||
void emit_expr_anglestoright(const ast::expr_anglestoright::ptr& expr);
|
||||
void emit_expr_anglestoforward(const ast::expr_anglestoforward::ptr& expr);
|
||||
void emit_expr_angleclamp180(const ast::expr_angleclamp180::ptr& expr);
|
||||
void emit_expr_vectortoangles(const ast::expr_vectortoangles::ptr& expr);
|
||||
void emit_expr_abs(const ast::expr_abs::ptr& expr);
|
||||
void emit_expr_gettime(const ast::expr_gettime::ptr& expr);
|
||||
void emit_expr_getdvar(const ast::expr_getdvar::ptr& expr);
|
||||
void emit_expr_getdvarint(const ast::expr_getdvarint::ptr& expr);
|
||||
void emit_expr_getdvarfloat(const ast::expr_getdvarfloat::ptr& expr);
|
||||
void emit_expr_getdvarvector(const ast::expr_getdvarvector::ptr& expr);
|
||||
void emit_expr_getdvarcolorred(const ast::expr_getdvarcolorred::ptr& expr);
|
||||
void emit_expr_getdvarcolorgreen(const ast::expr_getdvarcolorgreen::ptr& expr);
|
||||
void emit_expr_getdvarcolorblue(const ast::expr_getdvarcolorblue::ptr& expr);
|
||||
void emit_expr_getdvarcoloralpha(const ast::expr_getdvarcoloralpha::ptr& expr);
|
||||
void emit_expr_getfirstarraykey(const ast::expr_getfirstarraykey::ptr& expr);
|
||||
void emit_expr_getnextarraykey(const ast::expr_getnextarraykey::ptr& expr);
|
||||
void emit_expr_reference(const ast::expr_reference::ptr& expr);
|
||||
void emit_expr_size(const ast::expr_size::ptr& expr);
|
||||
void emit_expr_variable_ref(const ast::expr& expr, bool set);
|
||||
void emit_expr_array_ref(const ast::expr_array::ptr& expr, bool set);
|
||||
void emit_expr_field_ref(const ast::expr_field::ptr& expr, bool set);
|
||||
void emit_expr_local_ref(const ast::expr_identifier::ptr& expr, bool set);
|
||||
void emit_expr_variable(const ast::expr& expr);
|
||||
void emit_expr_array(const ast::expr_array::ptr& expr);
|
||||
void emit_expr_field(const ast::expr_field::ptr& expr);
|
||||
void emit_expr_local(const ast::expr_identifier::ptr& expr);
|
||||
void emit_expr_object(const ast::expr& expr);
|
||||
void emit_expr_vector(const ast::expr_vector::ptr& expr);
|
||||
void emit_expr_animation(const ast::expr_animation::ptr& expr);
|
||||
void emit_expr_animtree(const ast::expr_animtree::ptr& expr);
|
||||
void emit_expr_istring(const ast::expr_istring::ptr& expr);
|
||||
void emit_expr_string(const ast::expr_string::ptr& expr);
|
||||
void emit_expr_hash(const ast::expr_hash::ptr& expr);
|
||||
void emit_expr_float(const ast::expr_float::ptr& expr);
|
||||
void emit_expr_integer(const ast::expr_integer::ptr& expr);
|
||||
void emit_expr_false(const ast::expr_false::ptr& expr);
|
||||
void emit_expr_true(const ast::expr_true::ptr& expr);
|
||||
void emit_opcode(opcode op);
|
||||
void emit_opcode(opcode op, const std::string& data);
|
||||
void emit_opcode(opcode op, const std::vector<std::string>& data);
|
||||
void process_thread(const ast::decl_thread::ptr& decl);
|
||||
void process_stmt(const ast::stmt& stmt);
|
||||
void process_stmt_list(const ast::stmt_list::ptr& stmt);
|
||||
void process_stmt_dev(const ast::stmt_dev::ptr& stmt);
|
||||
void process_stmt_expr(const ast::stmt_expr::ptr& stmt);
|
||||
void process_stmt_assign(const ast::stmt_assign::ptr& stmt);
|
||||
void process_stmt_waittill(const ast::stmt_waittill::ptr& stmt);
|
||||
void process_stmt_if(const ast::stmt_if::ptr& stmt);
|
||||
void process_stmt_ifelse(const ast::stmt_ifelse::ptr& stmt);
|
||||
void process_stmt_while(const ast::stmt_while::ptr& stmt);
|
||||
void process_stmt_dowhile(const ast::stmt_dowhile::ptr& stmt);
|
||||
void process_stmt_for(const ast::stmt_for::ptr& stmt);
|
||||
void process_stmt_foreach(const ast::stmt_foreach::ptr& stmt);
|
||||
void process_stmt_switch(const ast::stmt_switch::ptr& stmt);
|
||||
void process_expr(const ast::expr& expr);
|
||||
void process_expr_parameters(const ast::expr_parameters::ptr& expr);
|
||||
void variable_register(const std::string& name);
|
||||
auto variable_access(const ast::expr_identifier::ptr& name) -> std::string;
|
||||
auto is_constant_condition(const ast::expr& expr) -> bool;
|
||||
auto create_label() -> std::string;
|
||||
auto insert_label() -> std::string;
|
||||
void insert_label(const std::string& label);
|
||||
auto map_known_includes(const std::string& include) -> bool;
|
||||
void print_function(const function::ptr& func);
|
||||
void print_instruction(const instruction::ptr& inst);
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t6
|
28
include/xsk/t6/context.hpp
Normal file
28
include/xsk/t6/context.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
class context : public arc::context
|
||||
{
|
||||
t6::assembler assembler_;
|
||||
t6::disassembler disassembler_;
|
||||
t6::compiler compiler_;
|
||||
t6::decompiler decompiler_;
|
||||
|
||||
public:
|
||||
void init(build mode, read_cb_type callback);
|
||||
void cleanup();
|
||||
|
||||
auto assembler() -> arc::assembler& { return assembler_; }
|
||||
auto disassembler() -> arc::disassembler& { return disassembler_; }
|
||||
auto compiler() -> arc::compiler& { return compiler_; }
|
||||
auto decompiler() -> arc::decompiler& { return decompiler_; }
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t6
|
100
include/xsk/t6/decompiler.hpp
Normal file
100
include/xsk/t6/decompiler.hpp
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
class decompiler : public arc::decompiler
|
||||
{
|
||||
std::string filename_;
|
||||
ast::program::ptr program_;
|
||||
ast::decl_thread::ptr func_;
|
||||
std::unordered_map<std::uint32_t, std::string> labels_;
|
||||
std::vector<std::string> expr_labels_;
|
||||
std::vector<std::string> tern_labels_;
|
||||
std::stack<ast::node::ptr> stack_;
|
||||
std::vector<std::string> locals_;
|
||||
std::vector<block> blocks_;
|
||||
bool in_waittill_;
|
||||
bool retbool_;
|
||||
int retnum_;
|
||||
|
||||
public:
|
||||
auto output() -> std::vector<std::uint8_t>;
|
||||
void decompile(const std::string& file, const assembly::ptr& data);
|
||||
|
||||
private:
|
||||
void decompile_function(const function::ptr& func);
|
||||
void decompile_instruction(const instruction::ptr& inst, bool last);
|
||||
void decompile_expressions(const instruction::ptr& inst);
|
||||
void decompile_statements(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_infinites(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_loops(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_devblocks(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_inf(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_loop(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_while(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_dowhile(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_for(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_foreach(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t begin);
|
||||
auto find_location_reference(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end, const std::string& location) -> bool;
|
||||
auto find_location_index(const ast::stmt_list::ptr& stmt, const std::string& location) -> std::size_t;
|
||||
auto last_location_index(const ast::stmt_list::ptr& stmt, std::size_t index) -> bool;
|
||||
auto lvalues_match(const ast::stmt_assign::ptr& stmt1, const ast::stmt_assign::ptr& stmt2) -> bool;
|
||||
auto resolve_label(const std::string& name) -> std::uint32_t;
|
||||
void process_thread(const ast::decl_thread::ptr& thread);
|
||||
void process_stmt(const ast::stmt& stmt);
|
||||
void process_stmt_list(const ast::stmt_list::ptr& stmt);
|
||||
void process_stmt_dev(const ast::stmt_dev::ptr& stmt);
|
||||
void process_stmt_expr(const ast::stmt_expr::ptr& stmt);
|
||||
void process_stmt_call(const ast::stmt_call::ptr& stmt);
|
||||
void process_stmt_assign(const ast::stmt_assign::ptr& stmt);
|
||||
void process_stmt_endon(const ast::stmt_endon::ptr& stmt);
|
||||
void process_stmt_notify(const ast::stmt_notify::ptr& stmt);
|
||||
void process_stmt_wait(const ast::stmt_wait::ptr& stmt);
|
||||
void process_stmt_waittill(const ast::stmt_waittill::ptr& stmt);
|
||||
void process_stmt_waittillmatch(const ast::stmt_waittillmatch::ptr& stmt);
|
||||
void process_stmt_if(const ast::stmt_if::ptr& stmt);
|
||||
void process_stmt_ifelse(const ast::stmt_ifelse::ptr& stmt);
|
||||
void process_stmt_while(const ast::stmt_while::ptr& stmt);
|
||||
void process_stmt_dowhile(const ast::stmt_dowhile::ptr& stmt);
|
||||
void process_stmt_for(const ast::stmt_for::ptr& stmt);
|
||||
void process_stmt_foreach(const ast::stmt_foreach::ptr& stmt);
|
||||
void process_stmt_switch(const ast::stmt_switch::ptr& stmt);
|
||||
void process_stmt_cases(const ast::stmt_list::ptr& stmt);
|
||||
void process_stmt_return(const ast::stmt_return::ptr& stmt);
|
||||
void process_expr(const ast::expr& expr);
|
||||
void process_expr_assign(ast::expr_assign::ptr& expr);
|
||||
void process_expr_increment(const ast::expr_increment::ptr& expr);
|
||||
void process_expr_decrement(const ast::expr_decrement::ptr& expr);
|
||||
void process_expr_ternary(const ast::expr_ternary::ptr& expr);
|
||||
void process_expr_binary(const ast::expr_binary::ptr& expr);
|
||||
void process_expr_and(const ast::expr_and::ptr& expr);
|
||||
void process_expr_or(const ast::expr_or::ptr& expr);
|
||||
void process_expr_complement(const ast::expr_complement::ptr& expr);
|
||||
void process_expr_not(const ast::expr_not::ptr& expr);
|
||||
void process_expr_call(const ast::expr_call::ptr& expr);
|
||||
void process_expr_method(const ast::expr_method::ptr& expr);
|
||||
void process_expr_call_pointer(const ast::expr_pointer::ptr& expr);
|
||||
void process_expr_call_function(const ast::expr_function::ptr& expr);
|
||||
void process_expr_method_pointer(const ast::expr_pointer::ptr& expr, ast::expr& obj);
|
||||
void process_expr_method_function(const ast::expr_function::ptr& expr, ast::expr& obj);
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& expr);
|
||||
void process_expr_parameters(const ast::expr_parameters::ptr& expr);
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t6
|
48
include/xsk/t6/disassembler.hpp
Normal file
48
include/xsk/t6/disassembler.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
class disassembler : public arc::disassembler
|
||||
{
|
||||
std::string filename_;
|
||||
utils::reader::ptr script_;
|
||||
utils::writer::ptr output_;
|
||||
assembly::ptr assembly_;
|
||||
std::vector<export_ref::ptr> exports_;
|
||||
std::vector<import_ref::ptr> imports_;
|
||||
std::vector<string_ref::ptr> strings_;
|
||||
std::vector<animtree_ref::ptr> animtrees_;
|
||||
std::map<std::uint32_t, std::string> stringlist_;
|
||||
std::map<std::uint32_t, import_ref::ptr> import_refs_;
|
||||
std::map<std::uint32_t, string_ref::ptr> string_refs_;
|
||||
std::map<std::uint32_t, animtree_ref::ptr> anim_refs_;
|
||||
std::unordered_map<std::uint32_t, std::string> labels_;
|
||||
header header_;
|
||||
|
||||
public:
|
||||
auto output() -> assembly::ptr;
|
||||
auto output_raw() -> std::vector<std::uint8_t>;
|
||||
void disassemble(const std::string& file, std::vector<std::uint8_t>& data);
|
||||
|
||||
private:
|
||||
void disassemble_function(const function::ptr& func);
|
||||
void disassemble_instruction(const instruction::ptr& inst);
|
||||
void disassemble_string(const instruction::ptr& inst);
|
||||
void disassemble_animtree(const instruction::ptr& inst);
|
||||
void disassemble_animation(const instruction::ptr& inst);
|
||||
void disassemble_localvars(const instruction::ptr& inst);
|
||||
void disassemble_import(const instruction::ptr& inst);
|
||||
void disassemble_jump(const instruction::ptr& inst);
|
||||
void disassemble_switch(const instruction::ptr& inst);
|
||||
void disassemble_end_switch(const instruction::ptr& inst);
|
||||
void print_function(const function::ptr& func);
|
||||
void print_instruction(const instruction::ptr& inst);
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t6
|
78
include/xsk/t6/lexer.hpp
Normal file
78
include/xsk/t6/lexer.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
constexpr size_t max_buf_size = 0x2000;
|
||||
|
||||
struct buffer
|
||||
{
|
||||
char* data;
|
||||
size_t length;
|
||||
|
||||
buffer();
|
||||
~buffer();
|
||||
bool push(char c);
|
||||
};
|
||||
|
||||
struct reader
|
||||
{
|
||||
enum state_type : std::uint8_t { end, ok };
|
||||
|
||||
const char* buffer_pos;
|
||||
std::uint32_t bytes_remaining;
|
||||
char last_byte;
|
||||
char current_byte;
|
||||
state_type state;
|
||||
|
||||
reader();
|
||||
|
||||
reader(const reader& obj)
|
||||
{
|
||||
std::memcpy(this, &obj, sizeof(reader));
|
||||
}
|
||||
|
||||
reader& operator=(const reader& obj)
|
||||
{
|
||||
std::memcpy(this, &obj, sizeof(reader));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void init(const char* data, size_t size);
|
||||
void advance();
|
||||
};
|
||||
|
||||
class lexer
|
||||
{
|
||||
enum class state : std::uint8_t { start, string, localize, preprocessor };
|
||||
|
||||
reader reader_;
|
||||
buffer buffer_;
|
||||
location loc_;
|
||||
std::stack<location> locs_;
|
||||
std::stack<reader> readers_;
|
||||
std::uint32_t header_top_;
|
||||
state state_;
|
||||
build mode_;
|
||||
bool indev_;
|
||||
bool clean_;
|
||||
|
||||
public:
|
||||
lexer(build mode, const std::string& name, const char* data, size_t size);
|
||||
auto lex() -> parser::symbol_type;
|
||||
void push_header(const std::string& file);
|
||||
void pop_header();
|
||||
void ban_header(const location& loc);
|
||||
|
||||
private:
|
||||
void advance();
|
||||
void preprocessor_wrap();
|
||||
void preprocessor_run(parser::token::token_kind_type token);
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t6
|
6416
include/xsk/t6/parser.hpp
Normal file
6416
include/xsk/t6/parser.hpp
Normal file
File diff suppressed because it is too large
Load Diff
25
include/xsk/t6/resolver.hpp
Normal file
25
include/xsk/t6/resolver.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
class resolver
|
||||
{
|
||||
public:
|
||||
static void init(read_cb_type callback);
|
||||
static void cleanup();
|
||||
static auto opcode_id(const std::string& name) -> std::uint8_t;
|
||||
static auto opcode_name(std::uint8_t id) -> std::string;
|
||||
static auto dvar_name(std::uint32_t id) -> std::string;
|
||||
|
||||
static auto make_token(std::string_view str) -> std::string;
|
||||
static auto file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>;
|
||||
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc::t6
|
157
include/xsk/t6/t6.hpp
Normal file
157
include/xsk/t6/t6.hpp
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xsk/stdinc.hpp"
|
||||
#include "xsk/utils/string.hpp"
|
||||
#include "xsk/utils/reader.hpp"
|
||||
#include "xsk/utils/writer.hpp"
|
||||
#include "common/arc.hpp"
|
||||
#include "assembler.hpp"
|
||||
#include "disassembler.hpp"
|
||||
#include "compiler.hpp"
|
||||
#include "decompiler.hpp"
|
||||
#include "resolver.hpp"
|
||||
#include "context.hpp"
|
||||
|
||||
namespace xsk::arc::t6
|
||||
{
|
||||
|
||||
constexpr std::uint64_t magic = 0x06000A0D43534780;
|
||||
|
||||
enum class opcode : std::uint8_t
|
||||
{
|
||||
OP_End = 0x0,
|
||||
OP_Return = 0x1,
|
||||
OP_GetUndefined = 0x2,
|
||||
OP_GetZero = 0x3,
|
||||
OP_GetByte = 0x4,
|
||||
OP_GetNegByte = 0x5,
|
||||
OP_GetUnsignedShort = 0x6,
|
||||
OP_GetNegUnsignedShort = 0x7,
|
||||
OP_GetInteger = 0x8,
|
||||
OP_GetFloat = 0x9,
|
||||
OP_GetString = 0xA,
|
||||
OP_GetIString = 0xB,
|
||||
OP_GetVector = 0xC,
|
||||
OP_GetLevelObject = 0xD,
|
||||
OP_GetAnimObject = 0xE,
|
||||
OP_GetSelf = 0xF,
|
||||
OP_GetLevel = 0x10,
|
||||
OP_GetGame = 0x11,
|
||||
OP_GetAnim = 0x12,
|
||||
OP_GetAnimation = 0x13,
|
||||
OP_GetGameRef = 0x14,
|
||||
OP_GetFunction = 0x15,
|
||||
OP_CreateLocalVariable = 0x16,
|
||||
OP_SafeCreateLocalVariables = 0x17,
|
||||
OP_RemoveLocalVariables = 0x18,
|
||||
OP_EvalLocalVariableCached = 0x19,
|
||||
OP_EvalArray = 0x1A,
|
||||
OP_EvalLocalArrayRefCached = 0x1B,
|
||||
OP_EvalArrayRef = 0x1C,
|
||||
OP_ClearArray = 0x1D,
|
||||
OP_EmptyArray = 0x1E,
|
||||
OP_GetSelfObject = 0x1F,
|
||||
OP_EvalFieldVariable = 0x20,
|
||||
OP_EvalFieldVariableRef = 0x21,
|
||||
OP_ClearFieldVariable = 0x22,
|
||||
OP_SafeSetVariableFieldCached = 0x23,
|
||||
OP_SafeSetWaittillVariableFieldCached = 0x24,
|
||||
OP_ClearParams = 0x25,
|
||||
OP_CheckClearParams = 0x26,
|
||||
OP_EvalLocalVariableRefCached = 0x27,
|
||||
OP_SetVariableField = 0x28,
|
||||
OP_CallBuiltin = 0x29,
|
||||
OP_CallBuiltinMethod = 0x2A,
|
||||
OP_Wait = 0x2B,
|
||||
OP_WaitTillFrameEnd = 0x2C,
|
||||
OP_PreScriptCall = 0x2D,
|
||||
OP_ScriptFunctionCall = 0x2E,
|
||||
OP_ScriptFunctionCallPointer = 0x2F,
|
||||
OP_ScriptMethodCall = 0x30,
|
||||
OP_ScriptMethodCallPointer = 0x31,
|
||||
OP_ScriptThreadCall = 0x32,
|
||||
OP_ScriptThreadCallPointer = 0x33,
|
||||
OP_ScriptMethodThreadCall = 0x34,
|
||||
OP_ScriptMethodThreadCallPointer = 0x35,
|
||||
OP_DecTop = 0x36,
|
||||
OP_CastFieldObject = 0x37,
|
||||
OP_CastBool = 0x38,
|
||||
OP_BoolNot = 0x39,
|
||||
OP_BoolComplement = 0x3A,
|
||||
OP_JumpOnFalse = 0x3B,
|
||||
OP_JumpOnTrue = 0x3C,
|
||||
OP_JumpOnFalseExpr = 0x3D,
|
||||
OP_JumpOnTrueExpr = 0x3E,
|
||||
OP_Jump = 0x3F,
|
||||
OP_JumpBack = 0x40,
|
||||
OP_Inc = 0x41,
|
||||
OP_Dec = 0x42,
|
||||
OP_Bit_Or = 0x43,
|
||||
OP_Bit_Xor = 0x44,
|
||||
OP_Bit_And = 0x45,
|
||||
OP_Equal = 0x46,
|
||||
OP_NotEqual = 0x47,
|
||||
OP_LessThan = 0x48,
|
||||
OP_GreaterThan = 0x49,
|
||||
OP_LessThanOrEqualTo = 0x4A,
|
||||
OP_GreaterThanOrEqualTo = 0x4B,
|
||||
OP_ShiftLeft = 0x4C,
|
||||
OP_ShiftRight = 0x4D,
|
||||
OP_Plus = 0x4E,
|
||||
OP_Minus = 0x4F,
|
||||
OP_Multiply = 0x50,
|
||||
OP_Divide = 0x51,
|
||||
OP_Modulus = 0x52,
|
||||
OP_SizeOf = 0x53,
|
||||
OP_WaitTillMatch = 0x54,
|
||||
OP_WaitTill = 0x55,
|
||||
OP_Notify = 0x56,
|
||||
OP_EndOn = 0x57,
|
||||
OP_VoidCodePos = 0x58,
|
||||
OP_Switch = 0x59,
|
||||
OP_EndSwitch = 0x5A,
|
||||
OP_Vector = 0x5B,
|
||||
OP_GetHash = 0x5C,
|
||||
OP_RealWait = 0x5D,
|
||||
OP_VectorConstant = 0x5E,
|
||||
OP_IsDefined = 0x5F,
|
||||
OP_VectorScale = 0x60,
|
||||
OP_AnglesToUp = 0x61,
|
||||
OP_AnglesToRight = 0x62,
|
||||
OP_AnglesToForward = 0x63,
|
||||
OP_AngleClamp180 = 0x64,
|
||||
OP_VectorToAngles = 0x65,
|
||||
OP_Abs = 0x66,
|
||||
OP_GetTime = 0x67,
|
||||
OP_GetDvar = 0x68,
|
||||
OP_GetDvarInt = 0x69,
|
||||
OP_GetDvarFloat = 0x6A,
|
||||
OP_GetDvarVector = 0x6B,
|
||||
OP_GetDvarColorRed = 0x6C,
|
||||
OP_GetDvarColorGreen = 0x6D,
|
||||
OP_GetDvarColorBlue = 0x6E,
|
||||
OP_GetDvarColorAlpha = 0x6F,
|
||||
OP_FirstArrayKey = 0x70,
|
||||
OP_NextArrayKey = 0x71,
|
||||
OP_ProfileStart = 0x72,
|
||||
OP_ProfileStop = 0x73,
|
||||
OP_SafeDecTop = 0x74,
|
||||
OP_Nop = 0x75,
|
||||
OP_Abort = 0x76,
|
||||
OP_Object = 0x77,
|
||||
OP_ThreadObject = 0x78,
|
||||
OP_EvalLocalVariable = 0x79,
|
||||
OP_EvalLocalVariableRef = 0x7A,
|
||||
OP_DevblockBegin = 0x7B,
|
||||
OP_DevblockEnd = 0x7C,
|
||||
OP_Count = 0x7D,
|
||||
};
|
||||
|
||||
auto opcode_size(std::uint8_t id) -> std::uint32_t;
|
||||
|
||||
} // namespace xsk::arc::t6
|
21
include/xsk/utils/file.hpp
Normal file
21
include/xsk/utils/file.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class file
|
||||
{
|
||||
public:
|
||||
static auto read(std::filesystem::path const& file) -> std::vector<u8>;
|
||||
static auto save(std::filesystem::path const& file, std::vector<u8> const& data) -> void;
|
||||
static auto save(std::filesystem::path const& file, u8 const* data, usize size) -> void;
|
||||
static auto length(std::filesystem::path const& file) -> usize;
|
||||
static auto exists(std::filesystem::path const& file) -> bool;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
40
include/xsk/utils/reader.hpp
Normal file
40
include/xsk/utils/reader.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class reader
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<reader>;
|
||||
|
||||
private:
|
||||
u8 const* data_;
|
||||
u32 size_;
|
||||
u32 pos_;
|
||||
bool swap_;
|
||||
|
||||
public:
|
||||
reader(bool swap = false);
|
||||
reader(std::vector<u8> const& data, bool swap = false);
|
||||
reader(u8 const* data, u32 size, bool swap = false);
|
||||
template <typename T>
|
||||
auto read() -> T;
|
||||
auto read_cstr() -> std::string;
|
||||
auto read_bytes(u32 pos, u32 count) -> std::string;
|
||||
auto is_avail() -> bool;
|
||||
auto seek(u32 size) -> void;
|
||||
auto seek_neg(u32 size) -> void;
|
||||
auto align(u32 size) -> u32;
|
||||
auto data() -> u8 const*;
|
||||
auto size() -> u32;
|
||||
auto pos() -> u32;
|
||||
auto pos(u32 pos) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
43
include/xsk/utils/string.hpp
Normal file
43
include/xsk/utils/string.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class string
|
||||
{
|
||||
public:
|
||||
template <typename ... Args>
|
||||
static auto va(std::string const& format, Args ... args) -> std::string
|
||||
{
|
||||
usize size = snprintf(nullptr, 0, format.data(), args ...) + 1;
|
||||
std::vector<char> buf;
|
||||
buf.resize(size);
|
||||
snprintf(buf.data(), size, format.data(), args ...);
|
||||
return std::string(buf.data(), buf.data() + size - 1);
|
||||
}
|
||||
|
||||
static auto oct_to_dec(char const* str) -> std::string;
|
||||
static auto bin_to_dec(char const* str) -> std::string;
|
||||
static auto hex_to_dec(char const* str) -> std::string;
|
||||
static auto iequals(std::string const& a, std::string const& b) -> bool;
|
||||
static auto is_number(std::string const& s) -> bool;
|
||||
static auto is_hex_number(std::string const& s) -> bool;
|
||||
static auto to_lower(std::string const& input) -> std::string;
|
||||
static auto to_code(std::string const& input) -> std::string;
|
||||
static auto to_literal(std::string const& input) -> std::string;
|
||||
static auto fordslash(std::string const& s) -> std::string;
|
||||
static auto backslash(std::string const& s) -> std::string;
|
||||
static auto quote(std::string const& s, bool single = true) -> std::string;
|
||||
static auto unquote(std::string const& s) -> std::string;
|
||||
static auto split(std::string& str, char delimiter) -> std::vector<std::string>;
|
||||
static auto clean_buffer_lines(std::vector<u8>& buffer) -> std::vector<std::string>;
|
||||
static auto parse_code(std::string& line) -> std::vector<std::string>;
|
||||
static auto float_string(float value, bool toint = false) -> std::string;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
41
include/xsk/utils/writer.hpp
Normal file
41
include/xsk/utils/writer.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class writer
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<writer>;
|
||||
|
||||
private:
|
||||
u8* data_;
|
||||
u32 size_;
|
||||
u32 pos_;
|
||||
bool swap_;
|
||||
|
||||
public:
|
||||
writer(bool swap = false);
|
||||
writer(u32 size, bool swap = false);
|
||||
~writer();
|
||||
auto clear() -> void;
|
||||
template <typename T>
|
||||
auto write(T data) -> void;
|
||||
auto write_string(std::string const& data) -> void;
|
||||
auto write_cstr(std::string const& data) -> void;
|
||||
auto is_avail() -> bool;
|
||||
auto seek(u32 size) -> void;
|
||||
auto seek_neg(u32 size) -> void;
|
||||
auto align(u32 size) -> u32;
|
||||
auto data() -> u8 const*;
|
||||
auto size() -> u32;
|
||||
auto pos() -> u32;
|
||||
auto pos(u32 pos) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
18
include/xsk/utils/zlib.hpp
Normal file
18
include/xsk/utils/zlib.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class zlib
|
||||
{
|
||||
public:
|
||||
static auto compress(std::vector<u8> const& data) -> std::vector<u8>;
|
||||
static auto decompress(std::vector<u8> const& data, u32 length) -> std::vector<u8>;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
Reference in New Issue
Block a user