cleanup
This commit is contained in:
parent
79016a997e
commit
49c770414a
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
@ -229,28 +231,22 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CastBool:
|
case opcode::OP_CastBool:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
case opcode::OP_BoolComplement:
|
case opcode::OP_BoolComplement:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write_endian<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write_endian<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write_endian<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write_endian<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write_endian<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write_endian<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write_endian<float>(std::stof(inst->data[0]));
|
script_->write_endian<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
inst->size += script_->align(4);
|
inst->size += script_->align(4);
|
||||||
script_->write_endian<float>(std::stof(inst->data[0]));
|
script_->write_endian<float>(std::stof(inst->data[0]));
|
||||||
script_->write_endian<float>(std::stof(inst->data[1]));
|
script_->write_endian<float>(std::stof(inst->data[1]));
|
||||||
@ -258,23 +254,19 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
@ -291,7 +283,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_SetLocalVariableFieldCached:
|
case opcode::OP_SetLocalVariableFieldCached:
|
||||||
case opcode::OP_ClearLocalVariableFieldCached:
|
case opcode::OP_ClearLocalVariableFieldCached:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalLevelFieldVariable:
|
case opcode::OP_EvalLevelFieldVariable:
|
||||||
@ -314,7 +305,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
case opcode::OP_CallBuiltinPointer:
|
case opcode::OP_CallBuiltinPointer:
|
||||||
case opcode::OP_CallBuiltinMethodPointer:
|
case opcode::OP_CallBuiltinMethodPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_ScriptLocalFunctionCall2:
|
case opcode::OP_ScriptLocalFunctionCall2:
|
||||||
@ -390,8 +380,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -404,8 +392,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -419,7 +405,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -439,8 +424,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write_endian<std::int32_t>(addr - inst->index - 4);
|
script_->write_endian<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -448,8 +431,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write_endian<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write_endian<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -500,8 +481,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFF;
|
if (id == 0) id = 0xFFFF;
|
||||||
@ -517,8 +496,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1876,8 +1875,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2934,7 +2932,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
@ -2958,679 +2956,9 @@ void compiler::insert_label(const std::string& name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto compiler::map_known_includes(const std::string&) -> bool
|
||||||
gsc::include_t compiler::include_maps_mp_utility_ =
|
|
||||||
{
|
{
|
||||||
"maps/mp/_utility",
|
|
||||||
{
|
|
||||||
"exploder_sound",
|
|
||||||
"_beginlocationselection",
|
|
||||||
"stoplocationselection",
|
|
||||||
"endselectiononemp",
|
|
||||||
"endselectiononaction",
|
|
||||||
"endselectiononendgame",
|
|
||||||
"isattachment",
|
|
||||||
"getattachmenttype",
|
|
||||||
"delaythread",
|
|
||||||
"delaythread_proc",
|
|
||||||
"getplant",
|
|
||||||
"orienttonormal",
|
|
||||||
"deleteplacedentity",
|
|
||||||
"playsoundonplayers",
|
|
||||||
"sortlowermessages",
|
|
||||||
"addlowermessage",
|
|
||||||
"removelowermessage",
|
|
||||||
"getlowermessage",
|
|
||||||
"setlowermessage",
|
|
||||||
"updatelowermessage",
|
|
||||||
"clearondeath",
|
|
||||||
"clearafterfade",
|
|
||||||
"clearlowermessage",
|
|
||||||
"clearlowermessages",
|
|
||||||
"printonteam",
|
|
||||||
"printboldonteam",
|
|
||||||
"printboldonteamarg",
|
|
||||||
"printonteamarg",
|
|
||||||
"printonplayers",
|
|
||||||
"printandsoundoneveryone",
|
|
||||||
"printandsoundonteam",
|
|
||||||
"printandsoundonplayer",
|
|
||||||
"_playlocalsound",
|
|
||||||
"dvarintvalue",
|
|
||||||
"dvarfloatvalue",
|
|
||||||
"play_sound_on_tag",
|
|
||||||
"getotherteam",
|
|
||||||
"wait_endon",
|
|
||||||
"initpersstat",
|
|
||||||
"getpersstat",
|
|
||||||
"incpersstat",
|
|
||||||
"setpersstat",
|
|
||||||
"initplayerstat",
|
|
||||||
"incplayerstat",
|
|
||||||
"setplayerstat",
|
|
||||||
"getplayerstat",
|
|
||||||
"getplayerstattime",
|
|
||||||
"setplayerstatifgreater",
|
|
||||||
"setplayerstatiflower",
|
|
||||||
"updatepersratio",
|
|
||||||
"updatepersratiobuffered",
|
|
||||||
"waittillslowprocessallowed",
|
|
||||||
"waitfortimeornotify",
|
|
||||||
"isexcluded",
|
|
||||||
"leaderdialog",
|
|
||||||
"leaderdialogbothteams",
|
|
||||||
"leaderdialogonplayers",
|
|
||||||
"leaderdialogonplayer",
|
|
||||||
"playleaderdialogonplayer",
|
|
||||||
"updatemainmenu",
|
|
||||||
"updateobjectivetext",
|
|
||||||
"setobjectivetext",
|
|
||||||
"setobjectivescoretext",
|
|
||||||
"setobjectivehinttext",
|
|
||||||
"getobjectivetext",
|
|
||||||
"getobjectivescoretext",
|
|
||||||
"getobjectivehinttext",
|
|
||||||
"gettimepassed",
|
|
||||||
"getsecondspassed",
|
|
||||||
"getminutespassed",
|
|
||||||
"clearkillcamstate",
|
|
||||||
"isinkillcam",
|
|
||||||
"isvalidclass",
|
|
||||||
"getvalueinrange",
|
|
||||||
"waitfortimeornotifies",
|
|
||||||
"closemenus",
|
|
||||||
"logxpgains",
|
|
||||||
"registerroundswitchdvar",
|
|
||||||
"registerroundlimitdvar",
|
|
||||||
"registerwinlimitdvar",
|
|
||||||
"registerscorelimitdvar",
|
|
||||||
"registertimelimitdvar",
|
|
||||||
"registerhalftimedvar",
|
|
||||||
"registernumlivesdvar",
|
|
||||||
"setovertimelimitdvar",
|
|
||||||
"get_damageable_player",
|
|
||||||
"get_damageable_sentry",
|
|
||||||
"get_damageable_grenade",
|
|
||||||
"get_damageable_mine",
|
|
||||||
"get_damageable_player_pos",
|
|
||||||
"getstancecenter",
|
|
||||||
"get_damageable_grenade_pos",
|
|
||||||
"getdvarvec",
|
|
||||||
"strip_suffix",
|
|
||||||
"_takeweaponsexcept",
|
|
||||||
"savedata",
|
|
||||||
"restoredata",
|
|
||||||
"_setactionslot",
|
|
||||||
"isfloat",
|
|
||||||
"registerwatchdvarint",
|
|
||||||
"registerwatchdvarfloat",
|
|
||||||
"registerwatchdvar",
|
|
||||||
"setoverridewatchdvar",
|
|
||||||
"getwatcheddvar",
|
|
||||||
"updatewatcheddvars",
|
|
||||||
"isroundbased",
|
|
||||||
"islastround",
|
|
||||||
"wasonlyround",
|
|
||||||
"waslastround",
|
|
||||||
"hitroundlimit",
|
|
||||||
"hitscorelimit",
|
|
||||||
"hitwinlimit",
|
|
||||||
"getscorelimit",
|
|
||||||
"getroundswon",
|
|
||||||
"isobjectivebased",
|
|
||||||
"gettimelimit",
|
|
||||||
"gethalftime",
|
|
||||||
"inovertime",
|
|
||||||
"gamehasstarted",
|
|
||||||
"getaverageorigin",
|
|
||||||
"getlivingplayers",
|
|
||||||
"setusingremote",
|
|
||||||
"getremotename",
|
|
||||||
"freezecontrolswrapper",
|
|
||||||
"clearusingremote",
|
|
||||||
"isusingremote",
|
|
||||||
"queuecreate",
|
|
||||||
"queueadd",
|
|
||||||
"queueremovefirst",
|
|
||||||
"_giveweapon",
|
|
||||||
"_hasperk",
|
|
||||||
"giveperk",
|
|
||||||
"_setperk",
|
|
||||||
"_setextraperks",
|
|
||||||
"_unsetperk",
|
|
||||||
"_unsetextraperks",
|
|
||||||
"_clearperks",
|
|
||||||
"quicksort",
|
|
||||||
"quicksortmid",
|
|
||||||
"swap",
|
|
||||||
"_suicide",
|
|
||||||
"isreallyalive",
|
|
||||||
"playdeathsound",
|
|
||||||
"rankingenabled",
|
|
||||||
"privatematch",
|
|
||||||
"matchmakinggame",
|
|
||||||
"setaltsceneobj",
|
|
||||||
"endsceneondeath",
|
|
||||||
"getgametypenumlives",
|
|
||||||
"givecombathigh",
|
|
||||||
"arrayinsertion",
|
|
||||||
"getproperty",
|
|
||||||
"getintproperty",
|
|
||||||
"getfloatproperty",
|
|
||||||
"statusmenu",
|
|
||||||
"ischangingweapon",
|
|
||||||
"killshouldaddtokillstreak",
|
|
||||||
"streakshouldchain",
|
|
||||||
"isjuggernaut",
|
|
||||||
"iskillstreakweapon",
|
|
||||||
"isenvironmentweapon",
|
|
||||||
"getweaponclass",
|
|
||||||
"isdeathstreakweapon",
|
|
||||||
"getbaseweaponname",
|
|
||||||
"fixakimbostring",
|
|
||||||
"playsoundinspace",
|
|
||||||
"limitdecimalplaces",
|
|
||||||
"rounddecimalplaces",
|
|
||||||
"playerforclientid",
|
|
||||||
"isrested",
|
|
||||||
"stringtofloat",
|
|
||||||
"setselfusable",
|
|
||||||
"maketeamusable",
|
|
||||||
"_updateteamusable",
|
|
||||||
"makeenemyusable",
|
|
||||||
"_updateenemyusable",
|
|
||||||
"getnextlifeid",
|
|
||||||
"initgameflags",
|
|
||||||
"gameflaginit",
|
|
||||||
"gameflag",
|
|
||||||
"gameflagset",
|
|
||||||
"gameflagclear",
|
|
||||||
"gameflagwait",
|
|
||||||
"isprimarydamage",
|
|
||||||
"isbulletdamage",
|
|
||||||
"initlevelflags",
|
|
||||||
"levelflaginit",
|
|
||||||
"levelflag",
|
|
||||||
"levelflagset",
|
|
||||||
"levelflagclear",
|
|
||||||
"levelflagwait",
|
|
||||||
"levelflagwaitopen",
|
|
||||||
"getweaponattachments",
|
|
||||||
"isemped",
|
|
||||||
"isairdenied",
|
|
||||||
"isnuked",
|
|
||||||
"getplayerforguid",
|
|
||||||
"teamplayercardsplash",
|
|
||||||
"iscacprimaryweapon",
|
|
||||||
"iscacsecondaryweapon",
|
|
||||||
"getlastlivingplayer",
|
|
||||||
"getpotentiallivingplayers",
|
|
||||||
"waittillrecoveredhealth",
|
|
||||||
"attachmentmap",
|
|
||||||
"validateattachment",
|
|
||||||
"_objective_delete",
|
|
||||||
"touchingbadtrigger",
|
|
||||||
"setthirdpersondof",
|
|
||||||
"killtrigger",
|
|
||||||
"findisfacing",
|
|
||||||
"combinearrays",
|
|
||||||
"setrecoilscale",
|
|
||||||
"cleanarray",
|
|
||||||
"notusableforjoiningplayers",
|
|
||||||
"isstrstart",
|
|
||||||
"validateusestreak",
|
|
||||||
"currentactivevehiclecount",
|
|
||||||
"maxvehiclesallowed",
|
|
||||||
"incrementfauxvehiclecount",
|
|
||||||
"decrementfauxvehiclecount",
|
|
||||||
"lightweightscalar",
|
|
||||||
"allowteamchoice",
|
|
||||||
"allowclasschoice",
|
|
||||||
"isbuffunlockedforweapon",
|
|
||||||
"isbuffequippedonweapon",
|
|
||||||
"setcommonrulesfrommatchrulesdata",
|
|
||||||
"reinitializematchrulesonmigration",
|
|
||||||
"getmatchrulesspecialclass",
|
|
||||||
"recipeclassapplyjuggernaut",
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
gsc::include_t compiler::include_common_scripts_createfx_ =
|
|
||||||
{
|
|
||||||
"common_scripts/_createfx",
|
|
||||||
{
|
|
||||||
"createeffect",
|
|
||||||
"getloopeffectdelaydefault",
|
|
||||||
"getoneshoteffectdelaydefault",
|
|
||||||
"getexploderdelaydefault",
|
|
||||||
"getintervalsounddelaymindefault",
|
|
||||||
"getintervalsounddelaymaxdefault",
|
|
||||||
"add_effect",
|
|
||||||
"createloopsound",
|
|
||||||
"createintervalsound",
|
|
||||||
"createnewexploder",
|
|
||||||
"createexploderex",
|
|
||||||
"set_origin_and_angles",
|
|
||||||
"set_forward_and_up_vectors",
|
|
||||||
"createfx_common",
|
|
||||||
"createfxlogic",
|
|
||||||
"copy_angles_of_selected_ents",
|
|
||||||
"reset_axis_of_selected_ents",
|
|
||||||
"last_selected_entity_has_changed",
|
|
||||||
"createfx_showorigin",
|
|
||||||
"drop_selection_to_ground",
|
|
||||||
"set_off_exploders",
|
|
||||||
"draw_distance",
|
|
||||||
"createfx_autosave",
|
|
||||||
"rotate_over_time",
|
|
||||||
"delete_pressed",
|
|
||||||
"remove_selected_option",
|
|
||||||
"remove_option",
|
|
||||||
"delete_selection",
|
|
||||||
"move_selection_to_cursor",
|
|
||||||
"insert_effect",
|
|
||||||
"show_help",
|
|
||||||
"select_last_entity",
|
|
||||||
"select_all_exploders_of_currently_selected",
|
|
||||||
"copy_ents",
|
|
||||||
"post_entity_creation_function",
|
|
||||||
"paste_ents",
|
|
||||||
"add_and_select_entity",
|
|
||||||
"get_center_of_array",
|
|
||||||
"ent_draw_axis",
|
|
||||||
"rotation_is_occuring",
|
|
||||||
"print_fx_options",
|
|
||||||
"entity_highlight_disable",
|
|
||||||
"entity_highlight_enable",
|
|
||||||
"toggle_createfx_drawing",
|
|
||||||
"manipulate_createfx_ents",
|
|
||||||
"clear_settable_fx",
|
|
||||||
"reset_fx_hud_colors",
|
|
||||||
"button_is_held",
|
|
||||||
"button_is_clicked",
|
|
||||||
"toggle_entity_selection",
|
|
||||||
"select_entity",
|
|
||||||
"ent_is_highlighted",
|
|
||||||
"deselect_entity",
|
|
||||||
"index_is_selected",
|
|
||||||
"ent_is_selected",
|
|
||||||
"clear_entity_selection",
|
|
||||||
"draw_axis",
|
|
||||||
"clear_fx_hudelements",
|
|
||||||
"set_fx_hudelement",
|
|
||||||
"createfx_centerprint",
|
|
||||||
"createfx_centerprint_thread",
|
|
||||||
"buttondown",
|
|
||||||
"buttonpressed_internal",
|
|
||||||
"get_selected_move_vector",
|
|
||||||
"process_button_held_and_clicked",
|
|
||||||
"locked",
|
|
||||||
"kb_locked",
|
|
||||||
"add_button",
|
|
||||||
"add_kb_button",
|
|
||||||
"set_anglemod_move_vector",
|
|
||||||
"cfxprintlnstart",
|
|
||||||
"cfxprintln",
|
|
||||||
"cfxprintlnend",
|
|
||||||
"update_selected_entities",
|
|
||||||
"hack_start",
|
|
||||||
"get_player",
|
|
||||||
"createfx_orgranize_array",
|
|
||||||
"stop_fx_looper",
|
|
||||||
"stop_loopsound",
|
|
||||||
"func_get_level_fx",
|
|
||||||
"restart_fx_looper",
|
|
||||||
"process_fx_rotater",
|
|
||||||
"generate_fx_log",
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
gsc::include_t compiler::include_common_scripts_utility_ =
|
|
||||||
{
|
|
||||||
"common_scripts/utility",
|
|
||||||
{
|
|
||||||
"scriptprintln",
|
|
||||||
"debugprintln",
|
|
||||||
"draw_debug_line",
|
|
||||||
"waittillend",
|
|
||||||
"noself_func",
|
|
||||||
"self_func",
|
|
||||||
"randomvector",
|
|
||||||
"randomvectorrange",
|
|
||||||
"angle_dif",
|
|
||||||
"sign",
|
|
||||||
"track",
|
|
||||||
"get_enemy_team",
|
|
||||||
"clear_exception",
|
|
||||||
"set_exception",
|
|
||||||
"set_all_exceptions",
|
|
||||||
"cointoss",
|
|
||||||
"choose_from_weighted_array",
|
|
||||||
"get_cumulative_weights",
|
|
||||||
"waittill_string",
|
|
||||||
"waittill_multiple",
|
|
||||||
"waittill_multiple_ents",
|
|
||||||
"waittill_any_return",
|
|
||||||
"waittill_any_timeout",
|
|
||||||
"_timeout",
|
|
||||||
"waittill_any",
|
|
||||||
"waittill_any_ents",
|
|
||||||
"isflashed",
|
|
||||||
"flag_exist",
|
|
||||||
"flag",
|
|
||||||
"init_flags",
|
|
||||||
"flag_init",
|
|
||||||
"empty_init_func",
|
|
||||||
"issuffix",
|
|
||||||
"flag_set",
|
|
||||||
"assign_unique_id",
|
|
||||||
"flag_wait",
|
|
||||||
"flag_clear",
|
|
||||||
"flag_waitopen",
|
|
||||||
"waittill_either",
|
|
||||||
"array_thread",
|
|
||||||
"array_call",
|
|
||||||
"array_thread4",
|
|
||||||
"array_thread5",
|
|
||||||
"trigger_on",
|
|
||||||
"trigger_on_proc",
|
|
||||||
"trigger_off",
|
|
||||||
"trigger_off_proc",
|
|
||||||
"set_trigger_flag_permissions",
|
|
||||||
"update_trigger_based_on_flags",
|
|
||||||
"create_flags_and_return_tokens",
|
|
||||||
"init_trigger_flags",
|
|
||||||
"getstruct",
|
|
||||||
"getstructarray",
|
|
||||||
"struct_class_init",
|
|
||||||
"fileprint_start",
|
|
||||||
"fileprint_map_start",
|
|
||||||
"fileprint_map_header",
|
|
||||||
"fileprint_map_keypairprint",
|
|
||||||
"fileprint_map_entity_start",
|
|
||||||
"fileprint_map_entity_end",
|
|
||||||
"fileprint_radiant_vec",
|
|
||||||
"array_remove",
|
|
||||||
"array_remove_array",
|
|
||||||
"array_removeundefined",
|
|
||||||
"array_levelthread",
|
|
||||||
"array_levelcall",
|
|
||||||
"add_to_array",
|
|
||||||
"flag_assert",
|
|
||||||
"flag_wait_either",
|
|
||||||
"flag_wait_either_return",
|
|
||||||
"flag_wait_any",
|
|
||||||
"flag_wait_any_return",
|
|
||||||
"flag_wait_all",
|
|
||||||
"flag_wait_or_timeout",
|
|
||||||
"flag_waitopen_or_timeout",
|
|
||||||
"wait_for_flag_or_time_elapses",
|
|
||||||
"delaycall",
|
|
||||||
"delaycall_proc",
|
|
||||||
"noself_delaycall",
|
|
||||||
"noself_delaycall_proc",
|
|
||||||
"issp",
|
|
||||||
"issp_towerdefense",
|
|
||||||
"string_starts_with",
|
|
||||||
"plot_points",
|
|
||||||
"draw_line_for_time",
|
|
||||||
"array_combine",
|
|
||||||
"flat_angle",
|
|
||||||
"flat_origin",
|
|
||||||
"draw_arrow_time",
|
|
||||||
"get_linked_ents",
|
|
||||||
"get_linked_vehicle_nodes",
|
|
||||||
"get_linked_ent",
|
|
||||||
"get_linked_vehicle_node",
|
|
||||||
"get_links",
|
|
||||||
"run_thread_on_targetname",
|
|
||||||
"run_thread_on_noteworthy",
|
|
||||||
"draw_arrow",
|
|
||||||
"getfx",
|
|
||||||
"fxexists",
|
|
||||||
"print_csv_asset",
|
|
||||||
"fileprint_csv_start",
|
|
||||||
"_loadfx",
|
|
||||||
"getlastweapon",
|
|
||||||
"playerunlimitedammothread",
|
|
||||||
"isusabilityenabled",
|
|
||||||
"_disableusability",
|
|
||||||
"_enableusability",
|
|
||||||
"resetusability",
|
|
||||||
"_disableweapon",
|
|
||||||
"_enableweapon",
|
|
||||||
"isweaponenabled",
|
|
||||||
"_disableweaponswitch",
|
|
||||||
"_enableweaponswitch",
|
|
||||||
"isweaponswitchenabled",
|
|
||||||
"_disableoffhandweapons",
|
|
||||||
"_enableoffhandweapons",
|
|
||||||
"isoffhandweaponenabled",
|
|
||||||
"random",
|
|
||||||
"spawn_tag_origin",
|
|
||||||
"waittill_notify_or_timeout",
|
|
||||||
"fileprint_launcher_start_file",
|
|
||||||
"fileprint_launcher",
|
|
||||||
"fileprint_launcher_end_file",
|
|
||||||
"launcher_write_clipboard",
|
|
||||||
"isdestructible",
|
|
||||||
"pauseeffect",
|
|
||||||
"activate_individual_exploder",
|
|
||||||
"waitframe",
|
|
||||||
"brush_delete",
|
|
||||||
"brush_throw",
|
|
||||||
"get_target_ent",
|
|
||||||
"brush_show",
|
|
||||||
"exploder_earthquake",
|
|
||||||
"do_earthquake",
|
|
||||||
"exploder_rumble",
|
|
||||||
"exploder_delay",
|
|
||||||
"exploder_damage",
|
|
||||||
"effect_loopsound",
|
|
||||||
"play_loopsound_in_space",
|
|
||||||
"sound_effect",
|
|
||||||
"effect_soundalias",
|
|
||||||
"play_sound_in_space",
|
|
||||||
"cannon_effect",
|
|
||||||
"exploder_playsound",
|
|
||||||
"fire_effect",
|
|
||||||
"loop_fx_sound",
|
|
||||||
"loop_fx_sound_interval",
|
|
||||||
"loop_sound_delete",
|
|
||||||
"exploder_before_load",
|
|
||||||
"exploder_after_load",
|
|
||||||
"activate_exploder",
|
|
||||||
"createloopeffect",
|
|
||||||
"createoneshoteffect",
|
|
||||||
"createexploder",
|
|
||||||
"alphabetize",
|
|
||||||
"is_later_in_alphabet",
|
|
||||||
"alphabet_compare",
|
|
||||||
"play_loop_sound_on_entity",
|
|
||||||
"stop_loop_sound_on_entity",
|
|
||||||
"delete_on_death",
|
|
||||||
"error",
|
|
||||||
"exploder",
|
|
||||||
"create_dvar",
|
|
||||||
"void",
|
|
||||||
"tag_project",
|
|
||||||
"ter_op",
|
|
||||||
"create_lock",
|
|
||||||
"lock",
|
|
||||||
"is_locked",
|
|
||||||
"unlock_wait",
|
|
||||||
"unlock",
|
|
||||||
"unlock_thread",
|
|
||||||
"get_template_level",
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
gsc::include_t compiler::include_maps_mp_gametypes_hud_util_ =
|
|
||||||
{
|
|
||||||
"maps/mp/gametypes/_hud_util",
|
|
||||||
{
|
|
||||||
"setparent",
|
|
||||||
"getparent",
|
|
||||||
"addchild",
|
|
||||||
"removechild",
|
|
||||||
"setpoint",
|
|
||||||
"setpointbar",
|
|
||||||
"updatebar",
|
|
||||||
"updatebarscale",
|
|
||||||
"createfontstring",
|
|
||||||
"createserverfontstring",
|
|
||||||
"createservertimer",
|
|
||||||
"createtimer",
|
|
||||||
"createicon",
|
|
||||||
"createservericon",
|
|
||||||
"createserverbar",
|
|
||||||
"createbar",
|
|
||||||
"getcurrentfraction",
|
|
||||||
"createprimaryprogressbar",
|
|
||||||
"createprimaryprogressbartext",
|
|
||||||
"createteamprogressbar",
|
|
||||||
"createteamprogressbartext",
|
|
||||||
"setflashfrac",
|
|
||||||
"hideelem",
|
|
||||||
"showelem",
|
|
||||||
"flashthread",
|
|
||||||
"destroyelem",
|
|
||||||
"seticonshader",
|
|
||||||
"geticonshader",
|
|
||||||
"seticonsize",
|
|
||||||
"setwidth",
|
|
||||||
"setheight",
|
|
||||||
"setsize",
|
|
||||||
"updatechildren",
|
|
||||||
"transitionreset",
|
|
||||||
"transitionzoomin",
|
|
||||||
"transitionpulsefxin",
|
|
||||||
"transitionslidein",
|
|
||||||
"transitionslideout",
|
|
||||||
"transitionzoomout",
|
|
||||||
"transitionfadein",
|
|
||||||
"transitionfadeout",
|
|
||||||
"getweeklyref",
|
|
||||||
"getdailyref",
|
|
||||||
"ch_getprogress",
|
|
||||||
"ch_getstate",
|
|
||||||
"ch_setprogress",
|
|
||||||
"ch_setstate",
|
|
||||||
"ch_gettarget",
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto compiler::map_known_includes(const std::string& include) -> bool
|
|
||||||
{
|
|
||||||
if (include == "maps/mp/_utility")
|
|
||||||
{
|
|
||||||
includes_.push_back(include_maps_mp_utility_);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (include == "common_scripts/utility")
|
|
||||||
{
|
|
||||||
includes_.push_back(include_common_scripts_utility_);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (include == "common_scripts/_createfx")
|
|
||||||
{
|
|
||||||
includes_.push_back(include_common_scripts_createfx_);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (include == "maps/mp/gametypes/_hud_util")
|
|
||||||
{
|
|
||||||
includes_.push_back(include_maps_mp_gametypes_hud_util_);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::print_debug_info()
|
|
||||||
{
|
|
||||||
printf("----------------------------------\n");
|
|
||||||
printf("files included: %zu\n", includes_.size());
|
|
||||||
printf("animtrees used: %zu\n", animtrees_.size());
|
|
||||||
printf("functions compiled: %zu\n",assembly_.size());
|
|
||||||
|
|
||||||
for (auto& func : assembly_)
|
|
||||||
{
|
|
||||||
print_function(func);
|
|
||||||
|
|
||||||
for (auto& inst : func->instructions)
|
|
||||||
{
|
|
||||||
const auto itr = func->labels.find(inst->index);
|
|
||||||
|
|
||||||
if (itr != func->labels.end())
|
|
||||||
{
|
|
||||||
print_label(itr->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_instruction(inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("----------------------------------\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void compiler::print_opcodes(std::uint32_t, std::uint32_t)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
void compiler::print_function(const function::ptr& func)
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
printf("%s\n", func->name.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void compiler::print_instruction(const instruction::ptr& inst)
|
|
||||||
{
|
|
||||||
switch (opcode(inst->opcode))
|
|
||||||
{
|
|
||||||
case opcode::OP_endswitch:
|
|
||||||
print_opcodes(inst->index, 3);
|
|
||||||
printf("%s", resolver::opcode_name(inst->opcode).data());
|
|
||||||
printf(" %s\n", inst->data[0].data());
|
|
||||||
{
|
|
||||||
std::uint32_t totalcase = std::stoul(inst->data[0]);
|
|
||||||
auto index = 0;
|
|
||||||
for (auto casenum = 0u; casenum < totalcase; casenum++)
|
|
||||||
{
|
|
||||||
print_opcodes(inst->index, 7);
|
|
||||||
if (inst->data[1 + index] == "case")
|
|
||||||
{
|
|
||||||
printf("%s %s %s", inst->data[1 + index].data(), inst->data[1 + index + 1].data(), inst->data[1 + index + 2].data());
|
|
||||||
index += 3;
|
|
||||||
}
|
|
||||||
else if (inst->data[1 + index] == "default")
|
|
||||||
{
|
|
||||||
printf("%s %s", inst->data[1 + index].data(), inst->data[1 + index + 1].data());
|
|
||||||
index += 2;
|
|
||||||
}
|
|
||||||
if (casenum != totalcase - 1)
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
print_opcodes(inst->index, inst->size);
|
|
||||||
printf("%s", resolver::opcode_name(inst->opcode).data());
|
|
||||||
for (auto& d : inst->data)
|
|
||||||
{
|
|
||||||
printf(" %s", d.data());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void compiler::print_label(const std::string& label)
|
|
||||||
{
|
|
||||||
printf(" %s\n", label.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xsk::gsc::iw5c
|
} // namespace xsk::gsc::iw5c
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
@ -153,18 +153,7 @@ private:
|
|||||||
auto insert_label() -> std::string;
|
auto insert_label() -> std::string;
|
||||||
void insert_label(const std::string& label);
|
void insert_label(const std::string& label);
|
||||||
|
|
||||||
static gsc::include_t include_maps_mp_utility_;
|
|
||||||
static gsc::include_t include_common_scripts_utility_;
|
|
||||||
static gsc::include_t include_common_scripts_createfx_;
|
|
||||||
static gsc::include_t include_maps_mp_gametypes_hud_util_;
|
|
||||||
auto map_known_includes(const std::string& include) -> bool;
|
auto map_known_includes(const std::string& include) -> bool;
|
||||||
|
|
||||||
// debug
|
|
||||||
void print_debug_info();
|
|
||||||
void print_opcodes(std::uint32_t index, std::uint32_t size);
|
|
||||||
void print_function(const function::ptr& func);
|
|
||||||
void print_instruction(const instruction::ptr& inst);
|
|
||||||
void print_label(const std::string& label);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xsk::gsc::iw5c
|
} // namespace xsk::gsc::iw5c
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1822,7 +1822,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -77,18 +77,13 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
dissasemble_instruction(inst);
|
dissasemble_instruction(inst);
|
||||||
|
|
||||||
if(inst->size > size)
|
|
||||||
{
|
|
||||||
throw disasm_error("aaaaa");
|
|
||||||
}
|
|
||||||
|
|
||||||
size -= inst->size;
|
size -= inst->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
@ -465,7 +460,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -490,14 +485,14 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
return func->name;
|
return func->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//return "error";
|
|
||||||
throw disasm_error(utils::string::va("couldn't resolve function name at index '0x%04X'!", idx));
|
throw disasm_error(utils::string::va("couldn't resolve function name at index '0x%04X'!", idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,7 +523,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -540,8 +535,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -566,9 +560,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (const auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
output_->write_string("\n");
|
output_->write_string("\n");
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::iw5c
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
@ -172,7 +172,7 @@ auto opcode_size(std::uint8_t id) -> std::uint32_t
|
|||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
return 13;
|
return 13;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Couldn't resolve instruction size for " + std::to_string(id));
|
throw std::runtime_error("couldn't resolve instruction size for " + std::to_string(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +566,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -586,7 +586,7 @@ lex_name:
|
|||||||
{
|
{
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -230,52 +232,42 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_AddArray:
|
case opcode::OP_AddArray:
|
||||||
case opcode::OP_waittillmatch2:
|
case opcode::OP_waittillmatch2:
|
||||||
case opcode::OP_shift_right:
|
case opcode::OP_shift_right:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SetNewLocalVariableFieldCached0:
|
case opcode::OP_SetNewLocalVariableFieldCached0:
|
||||||
@ -292,7 +284,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
case opcode::OP_EvalLocalArrayCached:
|
case opcode::OP_EvalLocalArrayCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalSelfFieldVariable:
|
case opcode::OP_EvalSelfFieldVariable:
|
||||||
@ -315,7 +306,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptChildThreadCallPointer:
|
case opcode::OP_ScriptChildThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodThreadCallPointer:
|
case opcode::OP_ScriptMethodThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
@ -391,8 +381,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -405,8 +393,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -420,7 +406,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -440,8 +425,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -449,8 +432,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -501,8 +482,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFF;
|
if (id == 0) id = 0xFFFF;
|
||||||
@ -518,8 +497,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1884,8 +1883,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2941,7 +2939,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1828,7 +1828,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -460,7 +460,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -485,7 +485,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -523,7 +523,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -535,8 +535,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -563,9 +562,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::h1
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
|
@ -567,7 +567,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -587,7 +587,7 @@ lex_name:
|
|||||||
{
|
{
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -230,52 +232,42 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_AddArray:
|
case opcode::OP_AddArray:
|
||||||
case opcode::OP_waittillmatch2:
|
case opcode::OP_waittillmatch2:
|
||||||
case opcode::OP_shift_right:
|
case opcode::OP_shift_right:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SetNewLocalVariableFieldCached0:
|
case opcode::OP_SetNewLocalVariableFieldCached0:
|
||||||
@ -292,7 +284,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
case opcode::OP_EvalLocalArrayCached:
|
case opcode::OP_EvalLocalArrayCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalSelfFieldVariable:
|
case opcode::OP_EvalSelfFieldVariable:
|
||||||
@ -315,7 +306,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptChildThreadCallPointer:
|
case opcode::OP_ScriptChildThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodThreadCallPointer:
|
case opcode::OP_ScriptMethodThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
@ -391,8 +381,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -405,8 +393,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -420,7 +406,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -440,8 +425,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -449,8 +432,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -501,8 +482,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFF;
|
if (id == 0) id = 0xFFFF;
|
||||||
@ -518,8 +497,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1884,8 +1883,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2940,7 +2938,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1828,7 +1828,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -456,11 +456,11 @@ auto disassembler::disassemble_offset() -> std::int32_t
|
|||||||
|
|
||||||
void disassembler::resolve_local_functions()
|
void disassembler::resolve_local_functions()
|
||||||
{
|
{
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
for (auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -485,7 +485,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -523,7 +523,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -535,8 +535,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -563,9 +562,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::h2
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
|
@ -567,7 +567,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -587,7 +587,7 @@ lex_name:
|
|||||||
{
|
{
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
@ -229,51 +231,41 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CastBool:
|
case opcode::OP_CastBool:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
case opcode::OP_BoolComplement:
|
case opcode::OP_BoolComplement:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
@ -290,7 +282,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_SetLocalVariableFieldCached:
|
case opcode::OP_SetLocalVariableFieldCached:
|
||||||
case opcode::OP_ClearLocalVariableFieldCached:
|
case opcode::OP_ClearLocalVariableFieldCached:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalLevelFieldVariable:
|
case opcode::OP_EvalLevelFieldVariable:
|
||||||
@ -313,7 +304,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
case opcode::OP_CallBuiltinPointer:
|
case opcode::OP_CallBuiltinPointer:
|
||||||
case opcode::OP_CallBuiltinMethodPointer:
|
case opcode::OP_CallBuiltinMethodPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_ScriptLocalFunctionCall2:
|
case opcode::OP_ScriptLocalFunctionCall2:
|
||||||
@ -389,8 +379,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -403,8 +391,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -418,7 +404,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -438,8 +423,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -447,8 +430,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -499,8 +480,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFF;
|
if (id == 0) id = 0xFFFF;
|
||||||
@ -516,8 +495,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1876,8 +1875,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2931,7 +2929,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
@ -3543,91 +3541,4 @@ auto compiler::map_known_includes(const std::string& include) -> bool
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::print_debug_info()
|
|
||||||
{
|
|
||||||
printf("----------------------------------\n");
|
|
||||||
printf("files included: %zu\n", includes_.size());
|
|
||||||
printf("animtrees used: %zu\n", animtrees_.size());
|
|
||||||
printf("functions compiled: %zu\n",assembly_.size());
|
|
||||||
|
|
||||||
for (auto& func : assembly_)
|
|
||||||
{
|
|
||||||
print_function(func);
|
|
||||||
|
|
||||||
for (auto& inst : func->instructions)
|
|
||||||
{
|
|
||||||
const auto itr = func->labels.find(inst->index);
|
|
||||||
|
|
||||||
if (itr != func->labels.end())
|
|
||||||
{
|
|
||||||
print_label(itr->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_instruction(inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("----------------------------------\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void compiler::print_opcodes(std::uint32_t, std::uint32_t)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
void compiler::print_function(const function::ptr& func)
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
printf("%s\n", func->name.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void compiler::print_instruction(const instruction::ptr& inst)
|
|
||||||
{
|
|
||||||
switch (opcode(inst->opcode))
|
|
||||||
{
|
|
||||||
case opcode::OP_endswitch:
|
|
||||||
print_opcodes(inst->index, 3);
|
|
||||||
printf("%s", resolver::opcode_name(inst->opcode).data());
|
|
||||||
printf(" %s\n", inst->data[0].data());
|
|
||||||
{
|
|
||||||
std::uint32_t totalcase = std::stoul(inst->data[0]);
|
|
||||||
auto index = 0;
|
|
||||||
for (auto casenum = 0u; casenum < totalcase; casenum++)
|
|
||||||
{
|
|
||||||
print_opcodes(inst->index, 7);
|
|
||||||
if (inst->data[1 + index] == "case")
|
|
||||||
{
|
|
||||||
printf("%s %s %s", inst->data[1 + index].data(), inst->data[1 + index + 1].data(), inst->data[1 + index + 2].data());
|
|
||||||
index += 3;
|
|
||||||
}
|
|
||||||
else if (inst->data[1 + index] == "default")
|
|
||||||
{
|
|
||||||
printf("%s %s", inst->data[1 + index].data(), inst->data[1 + index + 1].data());
|
|
||||||
index += 2;
|
|
||||||
}
|
|
||||||
if (casenum != totalcase - 1)
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
print_opcodes(inst->index, inst->size);
|
|
||||||
printf("%s", resolver::opcode_name(inst->opcode).data());
|
|
||||||
for (auto& d : inst->data)
|
|
||||||
{
|
|
||||||
printf(" %s", d.data());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void compiler::print_label(const std::string& label)
|
|
||||||
{
|
|
||||||
printf(" %s\n", label.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xsk::gsc::iw5
|
} // namespace xsk::gsc::iw5
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
@ -158,13 +158,6 @@ private:
|
|||||||
static gsc::include_t include_common_scripts_createfx_;
|
static gsc::include_t include_common_scripts_createfx_;
|
||||||
static gsc::include_t include_maps_mp_gametypes_hud_util_;
|
static gsc::include_t include_maps_mp_gametypes_hud_util_;
|
||||||
auto map_known_includes(const std::string& include) -> bool;
|
auto map_known_includes(const std::string& include) -> bool;
|
||||||
|
|
||||||
// debug
|
|
||||||
void print_debug_info();
|
|
||||||
void print_opcodes(std::uint32_t index, std::uint32_t size);
|
|
||||||
void print_function(const function::ptr& func);
|
|
||||||
void print_instruction(const instruction::ptr& inst);
|
|
||||||
void print_label(const std::string& label);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xsk::gsc::iw5
|
} // namespace xsk::gsc::iw5
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1822,7 +1822,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
@ -459,7 +459,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -484,7 +484,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -522,7 +522,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -534,8 +534,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -560,9 +559,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
output_->write_string("\n");
|
output_->write_string("\n");
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::iw5
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
|
@ -566,7 +566,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -586,7 +586,7 @@ lex_name:
|
|||||||
{
|
{
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -229,52 +231,42 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_AddArray:
|
case opcode::OP_AddArray:
|
||||||
case opcode::OP_waittillmatch2:
|
case opcode::OP_waittillmatch2:
|
||||||
case opcode::OP_shift_right:
|
case opcode::OP_shift_right:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SetNewLocalVariableFieldCached0:
|
case opcode::OP_SetNewLocalVariableFieldCached0:
|
||||||
@ -291,7 +283,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
case opcode::OP_EvalLocalArrayCached:
|
case opcode::OP_EvalLocalArrayCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalSelfFieldVariable:
|
case opcode::OP_EvalSelfFieldVariable:
|
||||||
@ -314,7 +305,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptChildThreadCallPointer:
|
case opcode::OP_ScriptChildThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodThreadCallPointer:
|
case opcode::OP_ScriptMethodThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
@ -390,8 +380,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -404,8 +392,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -419,7 +405,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -439,8 +424,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -448,8 +431,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -500,8 +481,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFF;
|
if (id == 0) id = 0xFFFF;
|
||||||
@ -517,8 +496,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1876,8 +1875,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2931,7 +2929,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1822,7 +1822,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -459,7 +459,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -484,7 +484,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -522,7 +522,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -534,8 +534,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -562,9 +561,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::iw6
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
|
@ -566,7 +566,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -586,7 +586,7 @@ lex_name:
|
|||||||
{
|
{
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -229,52 +231,42 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_AddArray:
|
case opcode::OP_AddArray:
|
||||||
case opcode::OP_waittillmatch2:
|
case opcode::OP_waittillmatch2:
|
||||||
case opcode::OP_shift_right:
|
case opcode::OP_shift_right:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SetNewLocalVariableFieldCached0:
|
case opcode::OP_SetNewLocalVariableFieldCached0:
|
||||||
@ -291,7 +283,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
case opcode::OP_EvalLocalArrayCached:
|
case opcode::OP_EvalLocalArrayCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalSelfFieldVariable:
|
case opcode::OP_EvalSelfFieldVariable:
|
||||||
@ -314,7 +305,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptChildThreadCallPointer:
|
case opcode::OP_ScriptChildThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodThreadCallPointer:
|
case opcode::OP_ScriptMethodThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
@ -390,8 +380,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -404,8 +392,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -419,7 +405,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -439,8 +424,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -448,8 +431,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -500,8 +481,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFFFFFF;
|
if (id == 0) id = 0xFFFFFFFF;
|
||||||
@ -517,8 +496,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1876,8 +1875,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2931,7 +2929,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1822,7 +1822,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -459,7 +459,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -484,7 +484,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -522,7 +522,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -534,8 +534,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -562,9 +561,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::iw7
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
|
@ -566,7 +566,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -586,7 +586,7 @@ lex_name:
|
|||||||
{
|
{
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_CastFieldObject:
|
case opcode::OP_CastFieldObject:
|
||||||
case opcode::OP_plus:
|
case opcode::OP_plus:
|
||||||
@ -242,52 +244,42 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_BoolNotAfterAnd:
|
case opcode::OP_BoolNotAfterAnd:
|
||||||
case opcode::OP_IsDefined:
|
case opcode::OP_IsDefined:
|
||||||
case opcode::OP_IsTrue:
|
case opcode::OP_IsTrue:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(encrypt_string(inst->data[0]));
|
stack_->write_c_string(encrypt_string(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(encrypt_string(inst->data[0]));
|
stack_->write_c_string(encrypt_string(inst->data[0]));
|
||||||
stack_->write_c_string(encrypt_string(inst->data[1]));
|
stack_->write_c_string(encrypt_string(inst->data[1]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(encrypt_string(inst->data[0]));
|
stack_->write_c_string(encrypt_string(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SetNewLocalVariableFieldCached0:
|
case opcode::OP_SetNewLocalVariableFieldCached0:
|
||||||
@ -304,7 +296,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
case opcode::OP_EvalLocalArrayCached:
|
case opcode::OP_EvalLocalArrayCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalSelfFieldVariable:
|
case opcode::OP_EvalSelfFieldVariable:
|
||||||
@ -327,7 +318,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptChildThreadCallPointer:
|
case opcode::OP_ScriptChildThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodThreadCallPointer:
|
case opcode::OP_ScriptMethodThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
@ -445,8 +435,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -459,8 +447,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -474,7 +460,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -494,8 +479,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -503,8 +486,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -555,8 +536,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFFFFFF;
|
if (id == 0) id = 0xFFFFFFFF;
|
||||||
@ -572,8 +551,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_formal_params(const instruction::ptr& inst)
|
void assembler::assemble_formal_params(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoi(inst->data[0]);
|
const auto count = std::stoi(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(count));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(count));
|
||||||
@ -586,8 +563,6 @@ void assembler::assemble_formal_params(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1935,8 +1934,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2991,7 +2989,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1859,7 +1859,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_CastFieldObject:
|
case opcode::OP_CastFieldObject:
|
||||||
case opcode::OP_plus:
|
case opcode::OP_plus:
|
||||||
@ -523,7 +523,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -548,7 +548,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -603,7 +603,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -615,8 +615,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -643,9 +642,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::iw8
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_CastFieldObject:
|
case opcode::OP_CastFieldObject:
|
||||||
case opcode::OP_plus:
|
case opcode::OP_plus:
|
||||||
|
@ -569,7 +569,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -600,7 +600,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -230,52 +232,42 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_AddArray:
|
case opcode::OP_AddArray:
|
||||||
case opcode::OP_waittillmatch2:
|
case opcode::OP_waittillmatch2:
|
||||||
case opcode::OP_shift_right:
|
case opcode::OP_shift_right:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SetNewLocalVariableFieldCached0:
|
case opcode::OP_SetNewLocalVariableFieldCached0:
|
||||||
@ -292,7 +284,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
case opcode::OP_EvalLocalArrayCached:
|
case opcode::OP_EvalLocalArrayCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalSelfFieldVariable:
|
case opcode::OP_EvalSelfFieldVariable:
|
||||||
@ -315,7 +306,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptChildThreadCallPointer:
|
case opcode::OP_ScriptChildThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodThreadCallPointer:
|
case opcode::OP_ScriptMethodThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
@ -391,8 +381,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -405,8 +393,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -420,7 +406,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -440,8 +425,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -449,8 +432,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -501,8 +482,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFF;
|
if (id == 0) id = 0xFFFF;
|
||||||
@ -518,8 +497,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1884,8 +1883,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2940,7 +2938,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1828,7 +1828,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -460,7 +460,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -485,7 +485,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -523,7 +523,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -535,8 +535,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -563,9 +562,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -567,7 +567,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -587,7 +587,7 @@ lex_name:
|
|||||||
{
|
{
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::s1
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -231,52 +233,42 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_waittillmatch2:
|
case opcode::OP_waittillmatch2:
|
||||||
case opcode::OP_shift_right:
|
case opcode::OP_shift_right:
|
||||||
case opcode::OP_BoolNotAfterAnd:
|
case opcode::OP_BoolNotAfterAnd:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SetNewLocalVariableFieldCached0:
|
case opcode::OP_SetNewLocalVariableFieldCached0:
|
||||||
@ -293,7 +285,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
case opcode::OP_EvalLocalArrayCached:
|
case opcode::OP_EvalLocalArrayCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalSelfFieldVariable:
|
case opcode::OP_EvalSelfFieldVariable:
|
||||||
@ -316,7 +307,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptChildThreadCallPointer:
|
case opcode::OP_ScriptChildThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodThreadCallPointer:
|
case opcode::OP_ScriptMethodThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
@ -392,8 +382,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -406,8 +394,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -421,7 +407,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -441,8 +426,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -450,8 +433,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -502,8 +483,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFF;
|
if (id == 0) id = 0xFFFF;
|
||||||
@ -519,8 +498,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1884,8 +1883,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2940,7 +2938,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1835,7 +1835,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
@ -461,7 +461,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -486,7 +486,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -524,7 +524,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -536,8 +536,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -564,9 +563,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -567,7 +567,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -587,7 +587,7 @@ lex_name:
|
|||||||
{
|
{
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::s2
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_Return:
|
case opcode::OP_Return:
|
||||||
case opcode::OP_BoolNot:
|
case opcode::OP_BoolNot:
|
||||||
|
@ -87,12 +87,12 @@ void assembler::assemble(const std::string& file, std::vector<std::uint8_t>& dat
|
|||||||
{
|
{
|
||||||
auto inst = std::make_unique<instruction>();
|
auto inst = std::make_unique<instruction>();
|
||||||
inst->index = index;
|
inst->index = index;
|
||||||
inst->opcode = static_cast<std::uint8_t>(resolver::opcode_id(opdata[0]));
|
inst->opcode = resolver::opcode_id(opdata[0]);
|
||||||
inst->size = opcode_size(inst->opcode);
|
inst->size = opcode_size(inst->opcode);
|
||||||
opdata.erase(opdata.begin());
|
opdata.erase(opdata.begin());
|
||||||
inst->data = std::move(opdata);
|
inst->data = std::move(opdata);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -158,7 +158,9 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void assembler::assemble_instruction(const instruction::ptr& inst)
|
void assembler::assemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
||||||
|
|
||||||
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_CastFieldObject:
|
case opcode::OP_CastFieldObject:
|
||||||
case opcode::OP_plus:
|
case opcode::OP_plus:
|
||||||
@ -242,52 +244,42 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_BoolNotAfterAnd:
|
case opcode::OP_BoolNotAfterAnd:
|
||||||
case opcode::OP_IsDefined:
|
case opcode::OP_IsDefined:
|
||||||
case opcode::OP_IsTrue:
|
case opcode::OP_IsTrue:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetByte:
|
case opcode::OP_GetByte:
|
||||||
case opcode::OP_GetNegByte:
|
case opcode::OP_GetNegByte:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetUnsignedShort:
|
case opcode::OP_GetUnsignedShort:
|
||||||
case opcode::OP_GetNegUnsignedShort:
|
case opcode::OP_GetNegUnsignedShort:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetInteger:
|
case opcode::OP_GetInteger:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
script_->write<std::int32_t>(std::stoi(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetFloat:
|
case opcode::OP_GetFloat:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetVector:
|
case opcode::OP_GetVector:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<float>(std::stof(inst->data[0]));
|
script_->write<float>(std::stof(inst->data[0]));
|
||||||
script_->write<float>(std::stof(inst->data[1]));
|
script_->write<float>(std::stof(inst->data[1]));
|
||||||
script_->write<float>(std::stof(inst->data[2]));
|
script_->write<float>(std::stof(inst->data[2]));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
case opcode::OP_GetIString:
|
case opcode::OP_GetIString:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimation:
|
case opcode::OP_GetAnimation:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
script_->write<std::uint32_t>(0);
|
script_->write<std::uint32_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
stack_->write_c_string(inst->data[1]);
|
stack_->write_c_string(inst->data[1]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetAnimTree:
|
case opcode::OP_GetAnimTree:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
stack_->write_c_string(inst->data[0]);
|
stack_->write_c_string(inst->data[0]);
|
||||||
break;
|
break;
|
||||||
case opcode::OP_waittillmatch:
|
case opcode::OP_waittillmatch:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SetNewLocalVariableFieldCached0:
|
case opcode::OP_SetNewLocalVariableFieldCached0:
|
||||||
@ -304,7 +296,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_CreateLocalVariable:
|
case opcode::OP_CreateLocalVariable:
|
||||||
case opcode::OP_EvalLocalVariableObjectCached:
|
case opcode::OP_EvalLocalVariableObjectCached:
|
||||||
case opcode::OP_EvalLocalArrayCached:
|
case opcode::OP_EvalLocalArrayCached:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EvalSelfFieldVariable:
|
case opcode::OP_EvalSelfFieldVariable:
|
||||||
@ -327,7 +318,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptChildThreadCallPointer:
|
case opcode::OP_ScriptChildThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodThreadCallPointer:
|
case opcode::OP_ScriptMethodThreadCallPointer:
|
||||||
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
case opcode::OP_ScriptMethodChildThreadCallPointer:
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[0])));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
@ -445,8 +435,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method, bool args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[1])));
|
||||||
@ -459,8 +447,6 @@ void assembler::assemble_builtin_call(const instruction::ptr& inst, bool method,
|
|||||||
|
|
||||||
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_function(inst->data[0]);
|
const auto addr = resolve_function(inst->data[0]);
|
||||||
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
const auto offset = static_cast<std::int32_t>(addr - inst->index - 1);
|
||||||
|
|
||||||
@ -474,7 +460,6 @@ void assembler::assemble_local_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
script_->write<std::uint8_t>(0);
|
script_->write<std::uint8_t>(0);
|
||||||
script_->write<std::uint16_t>(0);
|
script_->write<std::uint16_t>(0);
|
||||||
|
|
||||||
@ -494,8 +479,6 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
|||||||
|
|
||||||
void assembler::assemble_switch(const instruction::ptr& inst)
|
void assembler::assemble_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::int32_t>(addr - inst->index - 4);
|
script_->write<std::int32_t>(addr - inst->index - 4);
|
||||||
@ -503,8 +486,6 @@ void assembler::assemble_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
void assembler::assemble_end_switch(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoul(inst->data[0]);
|
const auto count = std::stoul(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
script_->write<std::uint16_t>(static_cast<std::uint16_t>(count));
|
||||||
@ -555,8 +536,6 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
void assembler::assemble_field_variable(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
auto id = resolver::token_id(inst->data[0]);
|
auto id = resolver::token_id(inst->data[0]);
|
||||||
|
|
||||||
if (id == 0) id = 0xFFFFFFFF;
|
if (id == 0) id = 0xFFFFFFFF;
|
||||||
@ -572,8 +551,6 @@ void assembler::assemble_field_variable(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_formal_params(const instruction::ptr& inst)
|
void assembler::assemble_formal_params(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto count = std::stoi(inst->data[0]);
|
const auto count = std::stoi(inst->data[0]);
|
||||||
|
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(count));
|
script_->write<std::uint8_t>(static_cast<std::uint8_t>(count));
|
||||||
@ -586,8 +563,6 @@ void assembler::assemble_formal_params(const instruction::ptr& inst)
|
|||||||
|
|
||||||
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
void assembler::assemble_jump(const instruction::ptr& inst, bool expr, bool back)
|
||||||
{
|
{
|
||||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
|
|
||||||
|
|
||||||
const auto addr = resolve_label(inst->data[0]);
|
const auto addr = resolve_label(inst->data[0]);
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
|
@ -20,7 +20,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -49,9 +49,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) ->
|
|||||||
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
auto compiler::parse_file(const std::string& file) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
auto data = resolver::file_data(file);
|
auto data = resolver::file_data(file);
|
||||||
auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
|
||||||
|
|
||||||
return result;
|
return parse_buffer(file, std::get<1>(data), std::get<2>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::compile_program(const ast::program::ptr& program)
|
void compiler::compile_program(const ast::program::ptr& program)
|
||||||
@ -1935,8 +1934,7 @@ void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr, const bloc
|
|||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
const auto& value = itr->second;
|
emit_expr(itr->second, blk);
|
||||||
emit_expr(value, blk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2991,7 +2989,7 @@ void compiler::insert_label(const std::string& name)
|
|||||||
{
|
{
|
||||||
for (auto& inst : function_->instructions)
|
for (auto& inst : function_->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_JumpOnFalse:
|
case opcode::OP_JumpOnFalse:
|
||||||
case opcode::OP_JumpOnTrue:
|
case opcode::OP_JumpOnTrue:
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
|
@ -61,7 +61,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end");
|
throw decomp_error("stack isn't empty at function end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -85,7 +85,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
|||||||
|
|
||||||
auto loc = location(&filename_, inst->index);
|
auto loc = location(&filename_, inst->index);
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_End:
|
case opcode::OP_End:
|
||||||
{
|
{
|
||||||
@ -1859,7 +1859,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ void disassembler::dissasemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
void disassembler::dissasemble_instruction(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_CastFieldObject:
|
case opcode::OP_CastFieldObject:
|
||||||
case opcode::OP_plus:
|
case opcode::OP_plus:
|
||||||
@ -525,7 +525,7 @@ void disassembler::resolve_local_functions()
|
|||||||
{
|
{
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -550,7 +550,7 @@ auto disassembler::resolve_function(const std::string& index) -> std::string
|
|||||||
{
|
{
|
||||||
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
std::uint32_t idx = std::stoul(index, nullptr, 16);
|
||||||
|
|
||||||
for (auto& func : functions_)
|
for (const auto& func : functions_)
|
||||||
{
|
{
|
||||||
if (func->index == idx)
|
if (func->index == idx)
|
||||||
{
|
{
|
||||||
@ -588,7 +588,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetLocalFunction:
|
case opcode::OP_GetLocalFunction:
|
||||||
case opcode::OP_ScriptLocalFunctionCall:
|
case opcode::OP_ScriptLocalFunctionCall:
|
||||||
@ -600,8 +600,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
case opcode::OP_ScriptLocalChildThreadCall:
|
case opcode::OP_ScriptLocalChildThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodThreadCall:
|
case opcode::OP_ScriptLocalMethodThreadCall:
|
||||||
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
case opcode::OP_ScriptLocalMethodChildThreadCall:
|
||||||
output_->write_string(utils::string::va(" sub_%s", inst->data[0].data()));
|
output_->write_string(utils::string::va(" sub_%s %s\n", inst->data[0].data(), inst->data[1].data()));
|
||||||
output_->write_string(utils::string::va(" %s", inst->data[1].data()));
|
|
||||||
break;
|
break;
|
||||||
case opcode::OP_endswitch:
|
case opcode::OP_endswitch:
|
||||||
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
output_->write_string(utils::string::va(" %s\n", inst->data[0].data()));
|
||||||
@ -628,9 +627,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& d : inst->data)
|
for (auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va(" %s", d.data()));
|
output_->write_string(utils::string::va(" %s", data.data()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -569,7 +569,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -600,7 +600,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -249,22 +249,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data)});
|
const auto res = files.insert({ name, std::move(data)});
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
static void add_method(const std::string& name, std::uint16_t id);
|
static void add_method(const std::string& name, std::uint16_t id);
|
||||||
|
|
||||||
static auto make_token(std::string_view str) -> 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*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ namespace xsk::gsc::s4
|
|||||||
|
|
||||||
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
auto opcode_size(std::uint8_t id) -> std::uint32_t
|
||||||
{
|
{
|
||||||
switch (opcode(id))
|
switch (static_cast<opcode>(id))
|
||||||
{
|
{
|
||||||
case opcode::OP_CastFieldObject:
|
case opcode::OP_CastFieldObject:
|
||||||
case opcode::OP_plus:
|
case opcode::OP_plus:
|
||||||
|
@ -200,7 +200,7 @@ void assembler::assemble_function(const function::ptr& func)
|
|||||||
|
|
||||||
func->size += inst->size;
|
func->size += inst->size;
|
||||||
|
|
||||||
const auto& itr = func->labels.find(old_idx);
|
const auto itr = func->labels.find(old_idx);
|
||||||
|
|
||||||
if (itr != func->labels.end())
|
if (itr != func->labels.end())
|
||||||
{
|
{
|
||||||
@ -799,7 +799,7 @@ auto assembler::resolve_label(const std::string& name) -> std::int32_t
|
|||||||
|
|
||||||
auto assembler::string_offset(const std::string& name) -> std::uint16_t
|
auto assembler::string_offset(const std::string& name) -> std::uint16_t
|
||||||
{
|
{
|
||||||
const auto& itr = stringlist_.find(name);
|
const auto itr = stringlist_.find(name);
|
||||||
|
|
||||||
if (itr != stringlist_.end())
|
if (itr != stringlist_.end())
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
|
|||||||
{
|
{
|
||||||
filename_ = file;
|
filename_ = file;
|
||||||
|
|
||||||
auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
|
auto prog = parse_buffer(filename_, reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
|
||||||
compile_program(prog);
|
compile_program(prog);
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ void compiler::mode(build mode)
|
|||||||
mode_ = mode;
|
mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
|
auto compiler::parse_buffer(const std::string& file, const char* data, size_t size) -> ast::program::ptr
|
||||||
{
|
{
|
||||||
ast::program::ptr result(nullptr);
|
ast::program::ptr result(nullptr);
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ void compiler::emit_decl_usingtree(const ast::decl_usingtree::ptr& animtree)
|
|||||||
{
|
{
|
||||||
if (developer_thread_)
|
if (developer_thread_)
|
||||||
{
|
{
|
||||||
throw comp_error(animtree->loc(), "cannot put #using_animtree inside /# ... #/ comment");
|
throw comp_error(animtree->loc(), "cannot put #using_animtree inside developer block comment");
|
||||||
}
|
}
|
||||||
|
|
||||||
animtrees_.push_back({ animtree->name->value, false });
|
animtrees_.push_back({ animtree->name->value, false });
|
||||||
@ -155,10 +155,10 @@ void compiler::emit_decl_usingtree(const ast::decl_usingtree::ptr& animtree)
|
|||||||
|
|
||||||
void compiler::emit_decl_constant(const ast::decl_constant::ptr& constant)
|
void compiler::emit_decl_constant(const ast::decl_constant::ptr& constant)
|
||||||
{
|
{
|
||||||
if (constants_.contains(constant->name->value))
|
const auto itr = constants_.find(constant->name->value);
|
||||||
{
|
|
||||||
throw comp_error(constant->loc(), "duplicated constant definition");
|
if (itr != constants_.end())
|
||||||
}
|
throw comp_error(constant->loc(), "duplicated constant '" + constant->name->value + "'");
|
||||||
|
|
||||||
constants_.insert({ constant->name->value, std::move(constant->value) });
|
constants_.insert({ constant->name->value, std::move(constant->value) });
|
||||||
}
|
}
|
||||||
@ -1632,7 +1632,7 @@ void compiler::emit_expr_field_ref(const ast::expr_field::ptr& expr, bool set)
|
|||||||
|
|
||||||
void compiler::emit_expr_local_ref(const ast::expr_identifier::ptr& expr, bool set)
|
void compiler::emit_expr_local_ref(const ast::expr_identifier::ptr& expr, bool set)
|
||||||
{
|
{
|
||||||
const auto& itr = constants_.find(expr->value);
|
const auto itr = constants_.find(expr->value);
|
||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
{
|
{
|
||||||
@ -1723,7 +1723,7 @@ void compiler::emit_expr_field(const ast::expr_field::ptr& expr)
|
|||||||
void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr)
|
void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr)
|
||||||
{
|
{
|
||||||
// is constant ( should only allow: string, loc string, number, vector)
|
// is constant ( should only allow: string, loc string, number, vector)
|
||||||
const auto& itr = constants_.find(expr->value);
|
const auto itr = constants_.find(expr->value);
|
||||||
|
|
||||||
if (itr != constants_.end())
|
if (itr != constants_.end())
|
||||||
emit_expr(itr->second);
|
emit_expr(itr->second);
|
||||||
@ -2329,7 +2329,7 @@ auto compiler::create_label() -> std::string
|
|||||||
|
|
||||||
auto compiler::insert_label() -> std::string
|
auto compiler::insert_label() -> std::string
|
||||||
{
|
{
|
||||||
const auto& itr = function_->labels.find(index_);
|
const auto itr = function_->labels.find(index_);
|
||||||
|
|
||||||
if (itr != function_->labels.end())
|
if (itr != function_->labels.end())
|
||||||
{
|
{
|
||||||
@ -2346,7 +2346,7 @@ auto compiler::insert_label() -> std::string
|
|||||||
|
|
||||||
void compiler::insert_label(const std::string& name)
|
void compiler::insert_label(const std::string& name)
|
||||||
{
|
{
|
||||||
const auto& itr = function_->labels.find(index_);
|
const auto itr = function_->labels.find(index_);
|
||||||
|
|
||||||
if (itr != function_->labels.end())
|
if (itr != function_->labels.end())
|
||||||
{
|
{
|
||||||
@ -2387,7 +2387,7 @@ void compiler::print_function(const function::ptr& func)
|
|||||||
output_->write_string("\n");
|
output_->write_string("\n");
|
||||||
output_->write_string(utils::string::va("sub_%s %i %i\n", func->name.data(), func->params, func->flags));
|
output_->write_string(utils::string::va("sub_%s %i %i\n", func->name.data(), func->params, func->flags));
|
||||||
|
|
||||||
for (auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
const auto itr = func->labels.find(inst->index);
|
const auto itr = func->labels.find(inst->index);
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ class compiler : public arc::compiler
|
|||||||
bool can_continue_;
|
bool can_continue_;
|
||||||
bool developer_thread_;
|
bool developer_thread_;
|
||||||
build mode_;
|
build mode_;
|
||||||
|
utils::byte_buffer::ptr output_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
auto output() -> assembly::ptr;
|
auto output() -> assembly::ptr;
|
||||||
@ -36,7 +37,7 @@ public:
|
|||||||
void mode(build mode);
|
void mode(build mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr;
|
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;
|
auto parse_file(const std::string& file) -> ast::program::ptr;
|
||||||
void compile_program(const ast::program::ptr& program);
|
void compile_program(const ast::program::ptr& program);
|
||||||
void emit_include(const ast::include::ptr& include);
|
void emit_include(const ast::include::ptr& include);
|
||||||
@ -154,10 +155,7 @@ private:
|
|||||||
auto create_label() -> std::string;
|
auto create_label() -> std::string;
|
||||||
auto insert_label() -> std::string;
|
auto insert_label() -> std::string;
|
||||||
void insert_label(const std::string& label);
|
void insert_label(const std::string& label);
|
||||||
|
|
||||||
auto map_known_includes(const std::string& include) -> bool;
|
auto map_known_includes(const std::string& include) -> bool;
|
||||||
|
|
||||||
utils::byte_buffer::ptr output_;
|
|
||||||
void print_function(const function::ptr& func);
|
void print_function(const function::ptr& func);
|
||||||
void print_instruction(const instruction::ptr& inst);
|
void print_instruction(const instruction::ptr& inst);
|
||||||
};
|
};
|
||||||
|
@ -77,7 +77,7 @@ void decompiler::decompile_function(const function::ptr& func)
|
|||||||
|
|
||||||
if (stack_.size() > 0)
|
if (stack_.size() > 0)
|
||||||
{
|
{
|
||||||
throw decomp_error("stack isn't emty at function end " + func->name);
|
throw decomp_error("stack isn't empty at function end " + func->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& stmt = func_->stmt;
|
const auto& stmt = func_->stmt;
|
||||||
@ -1184,7 +1184,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last)
|
|||||||
|
|
||||||
void decompiler::decompile_expressions(const instruction::ptr& inst)
|
void decompiler::decompile_expressions(const instruction::ptr& inst)
|
||||||
{
|
{
|
||||||
const auto& itr = labels_.find(inst->index);
|
const auto itr = labels_.find(inst->index);
|
||||||
|
|
||||||
if (itr == labels_.end())
|
if (itr == labels_.end())
|
||||||
return;
|
return;
|
||||||
@ -1347,7 +1347,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
|||||||
{
|
{
|
||||||
for (auto i = 0u; i < stmt->list.size(); i++)
|
for (auto i = 0u; i < stmt->list.size(); i++)
|
||||||
{
|
{
|
||||||
auto& entry = stmt->list.at(i);
|
const auto& entry = stmt->list.at(i);
|
||||||
|
|
||||||
if (entry == ast::kind::asm_jump_cond)
|
if (entry == ast::kind::asm_jump_cond)
|
||||||
{
|
{
|
||||||
|
@ -453,7 +453,7 @@ void disassembler::disassemble_string(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
inst->size += script_->align(2);
|
inst->size += script_->align(2);
|
||||||
|
|
||||||
const auto& entry = string_refs_.find(script_->pos());
|
const auto entry = string_refs_.find(script_->pos());
|
||||||
|
|
||||||
if (entry != string_refs_.end())
|
if (entry != string_refs_.end())
|
||||||
{
|
{
|
||||||
@ -470,7 +470,7 @@ void disassembler::disassemble_animation(const instruction::ptr& inst)
|
|||||||
inst->size += script_->align(4);
|
inst->size += script_->align(4);
|
||||||
|
|
||||||
const auto ref = script_->pos();
|
const auto ref = script_->pos();
|
||||||
const auto& entry = anim_refs_.find(ref);
|
const auto entry = anim_refs_.find(ref);
|
||||||
|
|
||||||
if (entry != anim_refs_.end())
|
if (entry != anim_refs_.end())
|
||||||
{
|
{
|
||||||
@ -506,7 +506,7 @@ void disassembler::disassemble_import(const instruction::ptr& inst)
|
|||||||
inst->size += script_->align(4);
|
inst->size += script_->align(4);
|
||||||
script_->seek(4);
|
script_->seek(4);
|
||||||
|
|
||||||
const auto& entry = import_refs_.find(inst->index);
|
const auto entry = import_refs_.find(inst->index);
|
||||||
|
|
||||||
if (entry != import_refs_.end())
|
if (entry != import_refs_.end())
|
||||||
{
|
{
|
||||||
@ -544,7 +544,7 @@ void disassembler::disassemble_end_switch(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
inst->size += script_->align(4);
|
inst->size += script_->align(4);
|
||||||
|
|
||||||
const auto& itr = labels_.find(script_->pos());
|
const auto itr = labels_.find(script_->pos());
|
||||||
|
|
||||||
if (itr != labels_.end())
|
if (itr != labels_.end())
|
||||||
{
|
{
|
||||||
@ -557,7 +557,7 @@ void disassembler::disassemble_end_switch(const instruction::ptr& inst)
|
|||||||
labels_.erase(script_->pos());
|
labels_.erase(script_->pos());
|
||||||
|
|
||||||
const auto label = utils::string::va("loc_%X", inst->index);
|
const auto label = utils::string::va("loc_%X", inst->index);
|
||||||
const auto& itr2 = labels_.find(inst->index);
|
const auto itr2 = labels_.find(inst->index);
|
||||||
|
|
||||||
if (itr2 == labels_.end())
|
if (itr2 == labels_.end())
|
||||||
{
|
{
|
||||||
@ -615,7 +615,7 @@ void disassembler::print_function(const function::ptr& func)
|
|||||||
|
|
||||||
for (const auto& inst : func->instructions)
|
for (const auto& inst : func->instructions)
|
||||||
{
|
{
|
||||||
const auto& itr = func->labels.find(inst->index);
|
const auto itr = func->labels.find(inst->index);
|
||||||
|
|
||||||
if (itr != func->labels.end())
|
if (itr != func->labels.end())
|
||||||
{
|
{
|
||||||
@ -632,7 +632,7 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\t\t%s(", resolver::opcode_name(inst->opcode).data()));
|
output_->write_string(utils::string::va("\t\t%s(", resolver::opcode_name(inst->opcode).data()));
|
||||||
|
|
||||||
switch (opcode(inst->opcode))
|
switch (static_cast<opcode>(inst->opcode))
|
||||||
{
|
{
|
||||||
case opcode::OP_GetHash:
|
case opcode::OP_GetHash:
|
||||||
case opcode::OP_GetString:
|
case opcode::OP_GetString:
|
||||||
@ -653,9 +653,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
output_->write_string(utils::string::va("\"%s\", \"%s\"", inst->data[0].data(), inst->data[1].data()));
|
output_->write_string(utils::string::va("\"%s\", \"%s\"", inst->data[0].data(), inst->data[1].data()));
|
||||||
break;
|
break;
|
||||||
case opcode::OP_SafeCreateLocalVariables:
|
case opcode::OP_SafeCreateLocalVariables:
|
||||||
for (const auto& d : inst->data)
|
for (const auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("\"%s\"%s", d.data(), &d == &inst->data.back() ? "" : ", "));
|
output_->write_string(utils::string::va("\"%s\"%s", data.data(), &data == &inst->data.back() ? "" : ", "));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case opcode::OP_EndSwitch:
|
case opcode::OP_EndSwitch:
|
||||||
@ -681,9 +681,9 @@ void disassembler::print_instruction(const instruction::ptr& inst)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (const auto& d : inst->data)
|
for (const auto& data : inst->data)
|
||||||
{
|
{
|
||||||
output_->write_string(utils::string::va("%s%s", d.data(), &d == &inst->data.back() ? "" : ", "));
|
output_->write_string(utils::string::va("%s%s", data.data(), &data == &inst->data.back() ? "" : ", "));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -580,7 +580,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 16)
|
if (buffer_.length < 16)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
{
|
{
|
||||||
@ -608,7 +608,7 @@ lex_name:
|
|||||||
|
|
||||||
if (buffer_.length < 17)
|
if (buffer_.length < 17)
|
||||||
{
|
{
|
||||||
const auto& itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
const auto itr = keyword_map.find(std::string_view(buffer_.data, buffer_.length));
|
||||||
|
|
||||||
if (itr != keyword_map.end())
|
if (itr != keyword_map.end())
|
||||||
return parser::symbol_type(itr->second, loc_);
|
return parser::symbol_type(itr->second, loc_);
|
||||||
|
@ -32,7 +32,7 @@ void resolver::cleanup()
|
|||||||
|
|
||||||
auto resolver::opcode_id(const std::string& name) -> std::uint8_t
|
auto resolver::opcode_id(const std::string& name) -> std::uint8_t
|
||||||
{
|
{
|
||||||
const auto& itr = opcode_map_rev.find(name);
|
const auto itr = opcode_map_rev.find(name);
|
||||||
|
|
||||||
if (itr != opcode_map_rev.end())
|
if (itr != opcode_map_rev.end())
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ auto resolver::opcode_id(const std::string& name) -> std::uint8_t
|
|||||||
|
|
||||||
auto resolver::opcode_name(std::uint8_t id) -> std::string
|
auto resolver::opcode_name(std::uint8_t id) -> std::string
|
||||||
{
|
{
|
||||||
const auto& itr = opcode_map.find(id);
|
const auto itr = opcode_map.find(id);
|
||||||
|
|
||||||
if (itr != opcode_map.end())
|
if (itr != opcode_map.end())
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ auto resolver::opcode_name(std::uint8_t id) -> std::string
|
|||||||
|
|
||||||
auto resolver::dvar_name(std::uint32_t id) -> std::string
|
auto resolver::dvar_name(std::uint32_t id) -> std::string
|
||||||
{
|
{
|
||||||
const auto& itr = dvar_map.find(id);
|
const auto itr = dvar_map.find(id);
|
||||||
|
|
||||||
if (itr != dvar_map.end())
|
if (itr != dvar_map.end())
|
||||||
{
|
{
|
||||||
@ -84,22 +84,22 @@ auto resolver::make_token(std::string_view str) -> std::string
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>
|
auto resolver::file_data(const std::string& name) -> std::tuple<const std::string*, const char*, size_t>
|
||||||
{
|
{
|
||||||
const auto& itr = files.find(name);
|
const auto itr = files.find(name);
|
||||||
|
|
||||||
if (itr != files.end())
|
if (itr != files.end())
|
||||||
{
|
{
|
||||||
return { &itr->first ,reinterpret_cast<char*>(itr->second.data()), itr->second.size() };
|
return { &itr->first ,reinterpret_cast<const char*>(itr->second.data()), itr->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = read_callback(name);
|
auto data = read_callback(name);
|
||||||
|
|
||||||
const auto& res = files.insert({ name, std::move(data) });
|
const auto res = files.insert({ name, std::move(data) });
|
||||||
|
|
||||||
if (res.second)
|
if (res.second)
|
||||||
{
|
{
|
||||||
return { &res.first->first, reinterpret_cast<char*>(res.first->second.data()), res.first->second.size() };
|
return { &res.first->first, reinterpret_cast<const char*>(res.first->second.data()), res.first->second.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("couldn't open gsc file '" + name + "'");
|
throw error("couldn't open gsc file '" + name + "'");
|
||||||
|
@ -18,7 +18,7 @@ public:
|
|||||||
static auto dvar_name(std::uint32_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 make_token(std::string_view str) -> std::string;
|
||||||
static auto file_data(const std::string& name) -> std::tuple<const std::string*, char*, size_t>;
|
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;
|
static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user