fix(t6): assemble hash & endswitch (#122)

This commit is contained in:
Xenxo Espasandín 2023-05-15 13:07:09 +02:00 committed by xensik
parent f21bf9646a
commit 806b5249fa
7 changed files with 32 additions and 1051 deletions

View File

@ -1121,7 +1121,7 @@ auto map_token(context const* ctx_, token& tok) -> parser::symbol_type
return parser::symbol_type(parser::token::IDENTIFIER, std::move(tok.data), tok.pos);
}
else if (tok.type == token::PATH ||tok.type == token::STRING ||tok.type == token::ISTRING || tok.type == token::INT ||tok.type == token::FLT)
else if (tok.type == token::PATH ||tok.type == token::HASHSTR ||tok.type == token::STRING ||tok.type == token::ISTRING || tok.type == token::INT ||tok.type == token::FLT)
{
auto it = tok_to_parser.find(tok.type);

View File

@ -1,10 +0,0 @@
generate: t6
clean:
rm -rf ./parser.hpp
rm -rf ./parser.cpp
t6: parser.ypp
bison parser.ypp -Wcounterexamples
mv parser.hpp ../../include/xsk/t6/
mv parser.cpp ../../src/t6/

File diff suppressed because it is too large Load Diff

View File

@ -59,6 +59,7 @@ private:
auto read_directive_usingtree(token& hash, token& name) -> void;
auto read_hashtoken(token& hash) -> void;
auto read_hashtoken_animtree(token& hash, token& name) -> void;
auto read_hashtoken_hashstr(token& hash, token& name) -> void;
auto expand(token& tok, define& def) -> void;
auto expand_params(token& tok, define& def) -> std::vector<std::vector<token>>;
auto expect(token& tok, token::kind expected, spacing space = spacing::none) -> void;

View File

@ -395,7 +395,7 @@ auto assembler::assemble_instruction(instruction const& inst) -> void
break;
case opcode::OP_GetHash:
script_.align(4);
script_.write<u32>(static_cast<u32>(std::stoul(inst.data[0], 0, 16)));
script_.write<u32>(ctx_->hash_id(inst.data[0]));
break;
case opcode::OP_SafeCreateLocalVariables:
assemble_localvars(inst);
@ -483,7 +483,7 @@ auto assembler::assemble_switch(instruction const& inst) -> void
auto assembler::assemble_end_switch(instruction const& inst) -> void
{
const auto count = std::stoul(inst.data[0]);
const auto numerical = inst.data.back() == "i";
const auto type = static_cast<switch_type>(std::stoul(inst.data.back()));
script_.align(4);
script_.write<u32>(count);
@ -492,7 +492,7 @@ auto assembler::assemble_end_switch(instruction const& inst) -> void
{
if (inst.data[1 + (3 * i)] == "case")
{
if (numerical /*&& utils::string::is_number(inst->data[1 + (3 * i) + 1])*/)
if (type == switch_type::integer)
{
script_.write<u32>((std::stoi(inst.data[1 + (3 * i) + 1]) & 0xFFFFFF) + 0x800000);
}
@ -515,7 +515,7 @@ auto assembler::assemble_end_switch(instruction const& inst) -> void
}
else
{
throw asm_error("invalid switch case '" + inst.data[1 + (3 * i)] + "'!");
throw asm_error(fmt::format("invalid switch case {}", inst.data[1 + (3 * i)]));
}
}
}
@ -586,13 +586,13 @@ auto assembler::process_instruction(instruction const& inst) -> void
case opcode::OP_EndSwitch:
{
const auto count = std::stoul(inst.data[0]);
const auto numerical = inst.data.back() == "i";
const auto type = static_cast<switch_type>(std::stoul(inst.data.back()));
for (auto i = 0u; i < count; i++)
{
if (inst.data[1 + (3 * i)] == "case")
{
if (!numerical /*|| !utils::string::is_number(inst->data[1 + (3 * i) + 1])*/)
if (type == switch_type::string)
{
process_string(inst.data[1 + (3 * i) + 1]);
}
@ -809,13 +809,13 @@ auto assembler::align_instruction(instruction& inst) -> void
script_.seek(4);
const auto count = std::stoul(inst.data[0]);
const auto numerical = inst.data.back() == "i";
const auto type = static_cast<switch_type>(std::stoul(inst.data.back()));
for (auto i = 0u; i < count; i++)
{
if (inst.data[1 + (3 * i)] == "case")
{
if (!numerical /*|| !utils::string::is_number(inst.data[1 + (3 * i) + 1])*/)
if (type == switch_type::string)
{
add_stringref(inst.data[1 + (3 * i) + 1], string_type::literal, script_.pos() + 2);
}
@ -842,7 +842,7 @@ auto assembler::resolve_label(std::string const& name) -> i32
}
}
throw asm_error("couldn't resolve label address of '" + name + "'!");
throw asm_error(fmt::format("couldn't resolve label address of {}", name));
}
auto assembler::resolve_string(std::string const& name) -> u16
@ -854,7 +854,7 @@ auto assembler::resolve_string(std::string const& name) -> u16
return itr->second;
}
throw asm_error("couldn't resolve string assembly address of '" + name + "'!");
throw asm_error(fmt::format("couldn't resolve string address of {}", name));
}
void assembler::add_stringref(std::string const& str, string_type type, u32 ref)

View File

@ -5546,7 +5546,7 @@ auto map_token(context const* ctx_, token& tok) -> parser::symbol_type
return parser::symbol_type(parser::token::IDENTIFIER, std::move(tok.data), tok.pos);
}
else if (tok.type == token::PATH ||tok.type == token::STRING ||tok.type == token::ISTRING || tok.type == token::INT ||tok.type == token::FLT)
else if (tok.type == token::PATH ||tok.type == token::HASHSTR ||tok.type == token::STRING ||tok.type == token::ISTRING || tok.type == token::INT ||tok.type == token::FLT)
{
auto it = tok_to_parser.find(tok.type);

View File

@ -709,8 +709,10 @@ auto preprocessor::read_hashtoken(token& tok) -> void
return read_hashtoken_animtree(tok, next);
}
}
// TODO: iw9 hash literals #d"src_game"
else if (next.type == token::STRING)
{
return read_hashtoken_hashstr(tok, next);
}
// if nothing match return '#'
tokens_.push_front(std::move(next));
@ -732,6 +734,21 @@ auto preprocessor::read_hashtoken_animtree(token& hash, token& name) -> void
}
}
auto preprocessor::read_hashtoken_hashstr(token& hash, token& name) -> void
{
if (name.space == spacing::none)
{
name.pos.begin = hash.pos.begin;
tokens_.push_front(token{ token::HASHSTR, spacing::none, name.pos, name.data });
}
else
{
// if '# ""' return 2 tokens
tokens_.push_front(std::move(name));
tokens_.push_front(token{ token::HASH, hash.space, hash.pos });
}
}
auto preprocessor::expand(token& tok, define& def) -> void
{
if (def.type == define::PLAIN)