refactor(arc): treyarch games & minor fixes (#119)

This commit is contained in:
Xenxo Espasandín
2023-05-13 19:24:57 +02:00
committed by GitHub
parent a8a62c2667
commit 07184a5d0f
105 changed files with 26274 additions and 28088 deletions

View 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
#include "xsk/utils/writer.hpp"
#include "xsk/arc/common/types.hpp"
namespace xsk::arc
{
class assembler
{
context const* ctx_;
function const* func_;
assembly const* assembly_;
utils::writer script_;
std::unordered_map<std::string, u16> strpool_;
std::vector<export_ref> exports_;
std::vector<import_ref> imports_;
std::vector<string_ref> strings_;
std::vector<animtree_ref> anims_;
public:
assembler(context const* ctx);
auto assemble(assembly const& data) -> buffer;
private:
auto assemble_function(function& func) -> void;
auto assemble_instruction(instruction const& inst) -> void;
auto assemble_localvars(instruction const& inst) -> void;
auto assemble_jump(instruction const& inst) -> void;
auto assemble_switch(instruction const& inst) -> void;
auto assemble_end_switch(instruction const& inst) -> void;
auto process_string(std::string const& data) -> void;
auto process_function(function const& func) -> void;
auto process_instruction(instruction const& inst) -> void;
auto align_instruction(instruction& inst) -> void;
auto resolve_label(std::string const& name) -> i32;
auto resolve_string(std::string const& name) -> u16;
void add_stringref(std::string const& str, string_type type, u32 ref);
void add_importref(std::vector<std::string> const& data, u32 ref);
void add_animref(std::vector<std::string> const& data, u32 ref);
};
} // namespace xsk::arc

View File

@ -166,6 +166,11 @@ struct instruction
u32 size;
opcode opcode;
std::vector<std::string> data;
static auto make() -> instruction::ptr
{
return std::unique_ptr<instruction>(new instruction);
}
};
struct function
@ -180,6 +185,11 @@ struct function
std::string space;
std::vector<instruction::ptr> instructions;
std::unordered_map<u32, std::string> labels;
static auto make() -> function::ptr
{
return std::unique_ptr<function>(new function);
}
};
struct assembly
@ -188,21 +198,11 @@ struct assembly
std::vector<std::string> includes;
std::vector<function::ptr> functions;
static auto make() -> assembly::ptr
{
return std::unique_ptr<assembly>(new assembly);
}
};
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

View File

@ -8,33 +8,32 @@
namespace xsk::arc
{
constexpr usize header_size_32 = 64;
constexpr usize header_size_64 = 72;
constexpr usize header_size_v1 = 64;
constexpr usize header_size_v2 = 72;
constexpr usize header_size_v3 = 0;
struct header
enum class string_type : u8
{
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;
literal = 0,
canonical = 1,
};
enum class param_type : u8
{
value = 0,
reference = 1,
vararg = 2,
};
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,
};
enum class import_flags : u8
@ -49,6 +48,58 @@ enum class import_flags : u8
unk = 0x20, // T7, T8, T9
};
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 globalvar_offset;
u32 profile_offset;
u32 cseg_size;
u32 name;
u16 stringtablefixup_count;
u16 exports_count;
u16 imports_count;
u16 fixup_count;
u16 globalvar_count;
u16 profile_count;
u16 devblock_stringtablefixup_count;
u8 include_count;
u8 animtree_count;
u8 flags;
};
struct 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;
};
struct string_ref
{
using ptr = std::shared_ptr<string_ref>;
std::string name;
u8 type;
std::vector<u32> refs;
};
struct import_ref
{
using ptr = std::shared_ptr<import_ref>;
@ -60,17 +111,6 @@ struct import_ref
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>;
@ -84,36 +124,4 @@ struct export_ref
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

File diff suppressed because it is too large Load Diff

View 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
{
struct define
{
enum kind : u8 { PLAIN, BUILTIN, OBJECT, FUNCTION };
kind type;
// bool vararg;
std::vector<token> args;
std::vector<token> exp;
};
} // namespace xsk::arc

View 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::arc
{
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::arc

View 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::arc
{
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::arc

View 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
namespace xsk::arc
{
struct scope
{
using ptr = std::unique_ptr<scope>;
enum abort_type
{
abort_none = 0,
abort_continue = 1,
abort_break = 2,
abort_return = 3,
};
std::string end;
std::string cnt;
std::string brk;
abort_type abort;
bool is_dev;
scope() : abort(abort_type::abort_none), is_dev(false) {}
scope(std::string const& brk, std::string const& cnt) : cnt{ cnt }, brk{ brk }, abort(abort_type::abort_none), is_dev(false) {}
};
} // namespace xsk::arc

View 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::arc
{
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::arc

View 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::arc
{
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, HASHSTR, INT, FLT,
DEVBEGIN, DEVEND, INLINE, INCLUDE, USINGTREE, ANIMTREE, AUTOEXEC, CODECALL, PRIVATE,
ENDON, NOTIFY, WAIT, WAITTILL, WAITTILLMATCH, WAITTILLFRAMEEND, IF, ELSE, DO, WHILE,
FOR, FOREACH, IN, SWITCH, CASE, DEFAULT, BREAK, CONTINUE, RETURN, PROFBEGIN, PROFEND,
THREAD, TRUE, FALSE, UNDEFINED, SIZE, GAME, SELF, ANIM, LEVEL,
CONST, ISDEFINED, VECTORSCALE, ANGLESTOUP, ANGLESTORIGHT, ANGLESTOFORWARD, ANGLECLAMP180,
VECTORTOANGLES, ABS, GETTIME, GETDVAR, GETDVARINT, GETDVARFLOAT, GETDVARVECTOR, GETDVARCOLORRED,
GETDVARCOLORGREEN, GETDVARCOLORBLUE, GETDVARCOLORALPHA, GETFIRSTARRAYKEY, GETNEXTARRAYKEY,
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::arc

View File

@ -5,12 +5,18 @@
#pragma once
#include "asset.hpp"
#include "assembly.hpp"
#include "buffer.hpp"
#include "location.hpp"
#include "exception.hpp"
#include "ast.hpp"
#include "xsk/arc/common/asset.hpp"
#include "xsk/arc/common/assembly.hpp"
#include "xsk/arc/common/buffer.hpp"
#include "xsk/arc/common/location.hpp"
#include "xsk/arc/common/exception.hpp"
#include "xsk/arc/common/lookahead.hpp"
#include "xsk/arc/common/directive.hpp"
#include "xsk/arc/common/scope.hpp"
#include "xsk/arc/common/space.hpp"
#include "xsk/arc/common/token.hpp"
#include "xsk/arc/common/define.hpp"
#include "xsk/arc/common/ast.hpp"
namespace xsk::arc
{
@ -37,7 +43,12 @@ enum class system : u8
{
pc,
ps3,
ps4,
ps5,
xb2,
xb3,
xb4,
wiiu,
};
enum class engine : u8
@ -52,8 +63,19 @@ struct props
{
enum values : u32
{
none = 0 << 0,
version2 = 1 << 0,
none = 0 << 0,
v2 = 1 << 0,
v3 = 1 << 1,
header64 = 1 << 2,
header72 = 1 << 3,
headerxx = 1 << 4,
size64 = 1 << 5,
hashids = 1 << 6,
devstr = 1 << 7,
spaces = 1 << 8,
globals = 1 << 9,
refvarg = 1 << 10,
foreach = 1 << 11,
};
props(values value) : value_(value) {}

View File

@ -0,0 +1,153 @@
// 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/arc/common/types.hpp"
namespace xsk::arc
{
class compiler
{
context* ctx_;
assembly::ptr assembly_;
function::ptr function_;
std::vector<std::string> localfuncs_;
std::vector<std::string> stackframe_;
std::vector<scope> scopes_;
std::unordered_map<std::string, expr const*> constants_;
std::string animtree_;
u32 index_;
u32 label_idx_;
bool can_break_;
bool can_continue_;
bool developer_thread_;
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_include(include const& inc) -> void;
auto emit_decl(decl const& dec) -> void;
auto emit_decl_usingtree(decl_usingtree const& animtree) -> void;
auto emit_decl_function(decl_function const& func) -> void;
auto emit_stmt(stmt const& stm) -> void;
auto emit_stmt_list(stmt_list const& stm) -> void;
auto emit_stmt_comp(stmt_comp const& stm) -> void;
auto emit_stmt_dev(stmt_dev const& stm) -> void;
auto emit_stmt_expr(stmt_expr const& stm) -> void;
auto emit_stmt_endon(stmt_endon const& stm) -> void;
auto emit_stmt_notify(stmt_notify const& stm) -> void;
auto emit_stmt_wait(stmt_wait const& stm) -> void;
auto emit_stmt_waittill(stmt_waittill const& stm) -> void;
auto emit_stmt_waittillmatch(stmt_waittillmatch const& stm) -> void;
auto emit_stmt_waittillframeend(stmt_waittillframeend const& stm) -> void;
auto emit_stmt_if(stmt_if const& stm) -> void;
auto emit_stmt_ifelse(stmt_ifelse const& stm) -> void;
auto emit_stmt_while(stmt_while const& stm) -> void;
auto emit_stmt_dowhile(stmt_dowhile const& stm) -> void;
auto emit_stmt_for(stmt_for const& stm) -> void;
auto emit_stmt_foreach(stmt_foreach const& stm) -> void;
auto emit_stmt_switch(stmt_switch const& stm) -> void;
auto emit_stmt_case(stmt_case const& stm) -> void;
auto emit_stmt_default(stmt_default const& stm) -> void;
auto emit_stmt_break(stmt_break const& stm) -> void;
auto emit_stmt_continue(stmt_continue const& stm) -> void;
auto emit_stmt_return(stmt_return const& stm) -> void;
auto emit_stmt_breakpoint(stmt_breakpoint const& stm) -> void;
auto emit_stmt_prof_begin(stmt_prof_begin const& stm) -> void;
auto emit_stmt_prof_end(stmt_prof_end const& stm) -> void;
auto emit_expr(expr const& exp) -> void;
auto emit_expr_const(expr_const const& exp) -> void;
auto emit_expr_assign(expr_assign const& exp) -> void;
auto emit_expr_clear(expr const& exp) -> void;
auto emit_expr_clear_local(expr_identifier const& exp) -> void;
auto emit_expr_increment(expr_increment const& exp, bool is_stmt) -> void;
auto emit_expr_decrement(expr_decrement const& exp, bool is_stmt) -> void;
auto emit_expr_ternary(expr_ternary const& exp) -> void;
auto emit_expr_binary(expr_binary const& exp) -> void;
auto emit_expr_complement(expr_complement const& exp) -> void;
auto emit_expr_negate(expr_negate const& exp) -> void;
auto emit_expr_not(expr_not const& exp) -> void;
auto emit_expr_call(expr_call const& exp, bool is_stmt) -> void;
auto emit_expr_call_pointer(expr_pointer const& exp, bool is_stmt) -> void;
auto emit_expr_call_function(expr_function const& exp, bool is_stmt) -> void;
auto emit_expr_method(expr_method const& exp, bool is_stmt) -> void;
auto emit_expr_method_pointer(expr_pointer const& exp, expr const& obj, bool is_stmt) -> void;
auto emit_expr_method_function(expr_function const& exp, expr const& obj, bool is_stmt) -> void;
auto emit_expr_parameters(expr_parameters const& exp) -> void;
auto emit_expr_arguments(expr_arguments const& exp) -> void;
auto emit_expr_isdefined(expr_isdefined const& exp) -> void;
auto emit_expr_vectorscale(expr_vectorscale const& exp) -> void;
auto emit_expr_anglestoup(expr_anglestoup const& exp) -> void;
auto emit_expr_anglestoright(expr_anglestoright const& exp) -> void;
auto emit_expr_anglestoforward(expr_anglestoforward const& exp) -> void;
auto emit_expr_angleclamp180(expr_angleclamp180 const& exp) -> void;
auto emit_expr_vectortoangles(expr_vectortoangles const& exp) -> void;
auto emit_expr_abs(expr_abs const& exp) -> void;
auto emit_expr_gettime(expr_gettime const& exp) -> void;
auto emit_expr_getdvar(expr_getdvar const& exp) -> void;
auto emit_expr_getdvarint(expr_getdvarint const& exp) -> void;
auto emit_expr_getdvarfloat(expr_getdvarfloat const& exp) -> void;
auto emit_expr_getdvarvector(expr_getdvarvector const& exp) -> void;
auto emit_expr_getdvarcolorred(expr_getdvarcolorred const& exp) -> void;
auto emit_expr_getdvarcolorgreen(expr_getdvarcolorgreen const& exp) -> void;
auto emit_expr_getdvarcolorblue(expr_getdvarcolorblue const& exp) -> void;
auto emit_expr_getdvarcoloralpha(expr_getdvarcoloralpha const& exp) -> void;
auto emit_expr_getfirstarraykey(expr_getfirstarraykey const& exp) -> void;
auto emit_expr_getnextarraykey(expr_getnextarraykey const& exp) -> void;
auto emit_expr_reference(expr_reference const& exp) -> void;
auto emit_expr_size(expr_size const& exp) -> void;
auto emit_expr_variable_ref(expr const& exp, bool set) -> void;
auto emit_expr_array_ref(expr_array const& exp, bool set) -> void;
auto emit_expr_field_ref(expr_field const& exp, bool set) -> void;
auto emit_expr_local_ref(expr_identifier const& exp, bool set) -> void;
auto emit_expr_variable(expr const& exp) -> void;
auto emit_expr_array(expr_array const& exp) -> void;
auto emit_expr_field(expr_field const& exp) -> void;
auto emit_expr_local(expr_identifier const& exp) -> void;
auto emit_expr_object(expr const& exp) -> void;
auto emit_expr_vector(expr_vector const& exp) -> 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_hash(expr_hash 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_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) -> void;
auto process_stmt_list(stmt_list const& stm) -> void;
auto process_stmt_comp(stmt_comp const& stm) -> void;
auto process_stmt_dev(stmt_dev const& stm) -> void;
auto process_stmt_expr(stmt_expr const& stm) -> void;
auto process_stmt_waittill(stmt_waittill const& stm) -> void;
auto process_stmt_if(stmt_if const& stm) -> void;
auto process_stmt_ifelse(stmt_ifelse const& stm) -> void;
auto process_stmt_while(stmt_while const& stm) -> void;
auto process_stmt_dowhile(stmt_dowhile const& stm) -> void;
auto process_stmt_for(stmt_for const& stm) -> void;
auto process_stmt_foreach(stmt_foreach const& stm) -> void;
auto process_stmt_switch(stmt_switch const& stm) -> void;
auto process_expr(expr const& exp) -> void;
auto process_expr_parameters(expr_parameters const& exp) -> void;
auto variable_register(expr_identifier const& exp) -> void;
auto variable_access(expr_identifier const& exp) -> u8;
auto is_constant_condition(expr const& exp) -> bool;
auto insert_label(std::string const& label) -> void;
auto insert_label() -> std::string;
auto create_label() -> std::string;
};
} // namespace xsk::arc

View File

@ -5,10 +5,12 @@
#pragma once
#include "common/types.hpp"
#include "source.hpp"
#include "disassembler.hpp"
#include "decompiler.hpp"
#include "xsk/arc/common/types.hpp"
#include "xsk/arc/source.hpp"
#include "xsk/arc/assembler.hpp"
#include "xsk/arc/disassembler.hpp"
#include "xsk/arc/compiler.hpp"
#include "xsk/arc/decompiler.hpp"
namespace xsk::arc
{
@ -28,7 +30,9 @@ public:
auto instance() const -> instance { return instance_; }
auto magic() const -> u64 { return magic_; }
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 init(arc::build build, fs_callback callback) -> void;
@ -36,14 +40,14 @@ public:
auto engine_name() const -> std::string_view;
auto opcode_size(opcode op) const -> u32;
auto opcode_id(opcode op) const -> u8;
auto opcode_id(opcode op) const -> u16;
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;
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>;
protected:
arc::props props_;
@ -54,16 +58,18 @@ protected:
arc::instance instance_;
u64 magic_;
arc::source source_;
arc::assembler assembler_;
arc::disassembler disassembler_;
arc::compiler compiler_;
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<opcode, u16> code_map_rev_;
std::unordered_map<u32, std::string_view> hash_map_;
std::unordered_map<std::string, std::vector<u8>> header_files_;
};
} // namespace xsk::arc

View File

@ -5,7 +5,7 @@
#pragma once
#include "common/types.hpp"
#include "xsk/arc/common/types.hpp"
namespace xsk::arc
{
@ -20,6 +20,7 @@ class decompiler
std::vector<std::string> expr_labels_;
std::vector<std::string> tern_labels_;
std::vector<std::string> locals_;
std::vector<param_type> params_;
std::stack<node::ptr> stack_;
locjmp locs_;
bool in_waittill_;
@ -52,7 +53,7 @@ private:
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 lvalues_match(stmt_expr const& stm1, stmt_expr const& stm2) -> bool;
auto resolve_label(std::string const& name) -> u32;
auto process_function(decl_function& func) -> void;
auto process_stmt(stmt& stm) -> void;
@ -60,14 +61,12 @@ private:
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_waitrealtime(stmt_waitrealtime& 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;
@ -78,14 +77,12 @@ private:
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(expr::ptr& exp) -> void;
auto process_expr_increment(expr_increment& exp) -> void;
auto process_expr_decrement(expr_decrement& exp) -> void;
auto process_expr_assign(expr_assign::ptr& 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;
@ -93,8 +90,8 @@ private:
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_method_pointer(expr_pointer& exp, expr::ptr& obj) -> void;
auto process_expr_method_function(expr_function& exp, expr::ptr& 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;

View File

@ -5,8 +5,8 @@
#pragma once
#include "common/types.hpp"
#include "xsk/utils/reader.hpp"
#include "xsk/arc/common/types.hpp"
namespace xsk::arc
{

View File

@ -12,13 +12,6 @@ namespace xsk::arc::t6
{
constexpr usize code_count = 125;
constexpr usize dvar_count = 3326;
constexpr u64 header_magic = 0x06000A0D43534780;
constexpr usize hash_count = 3326;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::gsc::t6
} // namespace xsk::arc::t6

View 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
#include "xsk/arc/engine/t6.hpp"
namespace xsk::arc::t6::pc
{
constexpr u64 header_magic = 0x06000A0D43534780;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::arc::t6::pc

View 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
#include "xsk/arc/engine/t6.hpp"
namespace xsk::arc::t6::ps3
{
constexpr u64 header_magic = 0x804753430D0A0006;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::arc::t6::ps3

View 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
#include "xsk/arc/engine/t6.hpp"
namespace xsk::arc::t6::wiiu
{
constexpr u64 header_magic = 0x804753430D0A0006;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::arc::t6::wiiu

View 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
#include "xsk/arc/engine/t6.hpp"
namespace xsk::arc::t6::xb2
{
constexpr u64 header_magic = 0x804753430D0A0006;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::arc::t6::xb2

View File

@ -11,9 +11,8 @@
namespace xsk::arc::t7
{
constexpr usize code_count = 8192;
constexpr usize dvar_count = 0;
constexpr usize hash_count = 178717;
constexpr usize code_count = 16384;
constexpr usize hash_count = 178806;
constexpr u64 header_magic = 0x1C000A0D43534780;
class context : public arc::context

View File

@ -12,9 +12,8 @@ namespace xsk::arc::t8
{
constexpr usize code_count = 0;
constexpr usize dvar_count = 0;
constexpr usize hash_count = 0;
constexpr u64 header_magic = 0;
constexpr u64 header_magic = 0x36000A0D43534780;
class context : public arc::context
{

View File

@ -12,9 +12,8 @@ namespace xsk::arc::t9
{
constexpr usize code_count = 0;
constexpr usize dvar_count = 0;
constexpr usize hash_count = 0;
constexpr u64 header_magic = 0;
constexpr u64 header_magic = 0x38000A0D43534780;
class context : public arc::context
{

33
include/xsk/arc/lexer.hpp Normal file
View 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 "xsk/arc/common/types.hpp"
namespace xsk::arc
{
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::arc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
// 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/arc/common/types.hpp"
#include "xsk/arc/lexer.hpp"
namespace xsk::arc
{
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_;
std::string date_;
std::string time_;
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;
auto get_local_time(std::tm& ltime) -> void;
auto get_date_define(std::tm* time_p) -> void;
auto get_time_define(std::tm* time_p) -> void;
};
} // namespace xsk::arc

View File

@ -5,7 +5,7 @@
#pragma once
#include "common/types.hpp"
#include "xsk/arc/common/types.hpp"
namespace xsk::arc
{
@ -18,6 +18,12 @@ class source
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>;
@ -33,21 +39,20 @@ private:
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_decl_empty(decl_empty const& dec) -> void;
auto dump_stmt(stmt const& stm) -> void;
auto dump_stmt_empty(stmt_empty 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_waitrealtime(stmt_waitrealtime 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;
@ -63,41 +68,21 @@ private:
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_jmp(stmt_jmp const& stm) -> void;
auto dump_stmt_jmp_back(stmt_jmp_back const& stm) -> void;
auto dump_stmt_jmp_cond(stmt_jmp_cond const& stm) -> void;
auto dump_stmt_jmp_true(stmt_jmp_true const& stm) -> void;
auto dump_stmt_jmp_false(stmt_jmp_false const& stm) -> void;
auto dump_stmt_jmp_switch(stmt_jmp_switch const& stm) -> void;
auto dump_stmt_jmp_endswitch(stmt_jmp_endswitch const& stm) -> void;
auto dump_stmt_jmp_dev(stmt_jmp_dev 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_assign(expr_assign const& exp) -> void;
auto dump_expr_const(expr_const 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_binary(expr_binary 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;
@ -134,6 +119,7 @@ private:
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_ellipsis(expr_ellipsis 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;
@ -154,17 +140,6 @@ private:
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

View File

@ -6,7 +6,7 @@
#pragma once
#include "xsk/utils/writer.hpp"
#include "common/types.hpp"
#include "xsk/gsc/common/types.hpp"
namespace xsk::gsc
{

View File

@ -228,6 +228,11 @@ struct instruction
u32 size;
opcode opcode;
std::vector<std::string> data;
static auto make() -> instruction::ptr
{
return std::unique_ptr<instruction>(new instruction);
}
};
struct function
@ -240,6 +245,11 @@ struct function
std::string name;
std::vector<instruction::ptr> instructions;
std::unordered_map<u32, std::string> labels;
static auto make() -> function::ptr
{
return std::unique_ptr<function>(new function);
}
};
struct assembly
@ -247,21 +257,11 @@ struct assembly
using ptr = std::unique_ptr<assembly>;
std::vector<function::ptr> functions;
static auto make() -> assembly::ptr
{
return std::unique_ptr<assembly>(new assembly);
}
};
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

View File

@ -5,18 +5,18 @@
#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"
#include "xsk/gsc/common/asset.hpp"
#include "xsk/gsc/common/scope.hpp"
#include "xsk/gsc/common/buffer.hpp"
#include "xsk/gsc/common/assembly.hpp"
#include "xsk/gsc/common/location.hpp"
#include "xsk/gsc/common/exception.hpp"
#include "xsk/gsc/common/lookahead.hpp"
#include "xsk/gsc/common/directive.hpp"
#include "xsk/gsc/common/space.hpp"
#include "xsk/gsc/common/token.hpp"
#include "xsk/gsc/common/define.hpp"
#include "xsk/gsc/common/ast.hpp"
namespace xsk::gsc
{

View File

@ -5,7 +5,7 @@
#pragma once
#include "common/types.hpp"
#include "xsk/gsc/common/types.hpp"
namespace xsk::gsc
{
@ -15,8 +15,8 @@ class compiler
context* ctx_;
assembly::ptr assembly_;
function::ptr function_;
std::vector<std::string> stackframe_;
std::vector<std::string> localfuncs_;
std::vector<std::string> stackframe_;
std::unordered_map<std::string, expr const*> constants_;
std::unordered_map<node*, scope::ptr> scopes_;
std::vector<scope*> break_blks_;

View File

@ -5,12 +5,12 @@
#pragma once
#include "common/types.hpp"
#include "source.hpp"
#include "assembler.hpp"
#include "disassembler.hpp"
#include "compiler.hpp"
#include "decompiler.hpp"
#include "xsk/gsc/common/types.hpp"
#include "xsk/gsc/source.hpp"
#include "xsk/gsc/assembler.hpp"
#include "xsk/gsc/disassembler.hpp"
#include "xsk/gsc/compiler.hpp"
#include "xsk/gsc/decompiler.hpp"
namespace xsk::gsc
{

View File

@ -5,7 +5,7 @@
#pragma once
#include "common/types.hpp"
#include "xsk/gsc/common/types.hpp"
namespace xsk::gsc
{

View File

@ -6,7 +6,7 @@
#pragma once
#include "xsk/utils/reader.hpp"
#include "common/types.hpp"
#include "xsk/gsc/common/types.hpp"
namespace xsk::gsc
{

View File

@ -5,7 +5,7 @@
#pragma once
#include "common/types.hpp"
#include "xsk/gsc/common/types.hpp"
namespace xsk::gsc
{

View File

@ -5,8 +5,8 @@
#pragma once
#include "common/types.hpp"
#include "lexer.hpp"
#include "xsk/gsc/common/types.hpp"
#include "xsk/gsc/lexer.hpp"
namespace xsk::gsc
{

View File

@ -5,7 +5,7 @@
#pragma once
#include "common/types.hpp"
#include "xsk/gsc/common/types.hpp"
namespace xsk::gsc
{

View File

@ -62,4 +62,4 @@ using i64 = std::int64_t;
using f32 = float;
using f64 = double;
};
} // namespace xsk

View File

@ -1,47 +0,0 @@
// 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

View File

@ -1,18 +0,0 @@
// 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"

View File

@ -1,25 +0,0 @@
// 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

View File

@ -1,22 +0,0 @@
// 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

View File

@ -1,22 +0,0 @@
// 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

View File

@ -1,26 +0,0 @@
// 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

View File

@ -1,21 +0,0 @@
// 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

View File

@ -1,22 +0,0 @@
// 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

View File

@ -1,46 +0,0 @@
// 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

View File

@ -1,229 +0,0 @@
// 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

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +0,0 @@
// 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

View File

@ -1,164 +0,0 @@
// 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

View File

@ -1,28 +0,0 @@
// 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

View File

@ -1,100 +0,0 @@
// 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

View File

@ -1,48 +0,0 @@
// 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

View File

@ -1,78 +0,0 @@
// 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

View File

@ -1,25 +0,0 @@
// 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

View File

@ -1,157 +0,0 @@
// 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