context wrappers

This commit is contained in:
xensik 2022-03-15 12:39:04 +01:00
parent 3098dacc9e
commit 096316ea67
87 changed files with 805 additions and 309 deletions

View File

@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
return result; return result;
@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>&
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/h1/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "h1.hpp"
namespace xsk::gsc::h1
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::h1

28
src/h1/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::h1
{
class context : public gsc::context
{
h1::assembler assembler_;
h1::disassembler disassembler_;
h1::compiler compiler_;
h1::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::iw5

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::h1 namespace xsk::gsc::h1
{ {

View File

@ -127,8 +127,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,6 +19,19 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint16_t> file_map_rev; std::unordered_map<std::string_view, std::uint16_t> file_map_rev;
std::unordered_map<std::string_view, std::uint16_t> token_map_rev; std::unordered_map<std::string_view, std::uint16_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
auto resolver::opcode_id(const std::string& name) -> std::uint8_t auto resolver::opcode_id(const std::string& name) -> std::uint8_t
{ {
@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 154> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 154> opcode_list
{{ {{
{ 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::h1
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -31,7 +34,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::h1 } // namespace xsk::gsc::h1

View File

@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
return result; return result;
@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>&
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/h2/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "h2.hpp"
namespace xsk::gsc::h2
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::h2

28
src/h2/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::h2
{
class context : public gsc::context
{
h2::assembler assembler_;
h2::disassembler disassembler_;
h2::compiler compiler_;
h2::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::h2

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::h2 namespace xsk::gsc::h2
{ {

View File

@ -127,8 +127,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,6 +19,19 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint16_t> file_map_rev; std::unordered_map<std::string_view, std::uint16_t> file_map_rev;
std::unordered_map<std::string_view, std::uint16_t> token_map_rev; std::unordered_map<std::string_view, std::uint16_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
auto resolver::opcode_id(const std::string& name) -> std::uint8_t auto resolver::opcode_id(const std::string& name) -> std::uint8_t
{ {
@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 154> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 154> opcode_list
{{ {{
{ 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::h2
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -31,7 +34,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::h2 } // namespace xsk::gsc::h2

View File

@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
return result; return result;
@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>&
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/iw5/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "iw5.hpp"
namespace xsk::gsc::iw5
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::iw5

28
src/iw5/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::iw5
{
class context : public gsc::context
{
iw5::assembler assembler_;
iw5::disassembler disassembler_;
iw5::compiler compiler_;
iw5::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::iw5

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::iw5 namespace xsk::gsc::iw5
{ {

View File

@ -126,8 +126,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,9 +19,20 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint16_t> file_map_rev; std::unordered_map<std::string_view, std::uint16_t> file_map_rev;
std::unordered_map<std::string, std::uint16_t> token_map_rev; std::unordered_map<std::string, std::uint16_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map; std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
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);
@ -264,9 +275,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -288,11 +296,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 153> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 153> opcode_list
{{ {{
{ 0x00, "END" }, { 0x00, "END" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::iw5
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -34,7 +37,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::iw5 } // namespace xsk::gsc::iw5

View File

@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
return result; return result;
@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>&
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/iw6/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "iw6.hpp"
namespace xsk::gsc::iw6
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::iw6

28
src/iw6/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::iw6
{
class context : public gsc::context
{
iw6::assembler assembler_;
iw6::disassembler disassembler_;
iw6::compiler compiler_;
iw6::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::iw6

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::iw6 namespace xsk::gsc::iw6
{ {

View File

@ -126,8 +126,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,6 +19,19 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint16_t> file_map_rev; std::unordered_map<std::string_view, std::uint16_t> file_map_rev;
std::unordered_map<std::string_view, std::uint16_t> token_map_rev; std::unordered_map<std::string_view, std::uint16_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
auto resolver::opcode_id(const std::string& name) -> std::uint8_t auto resolver::opcode_id(const std::string& name) -> std::uint8_t
{ {
@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 153> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 153> opcode_list
{{ {{
{ 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::iw6
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -31,7 +34,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::iw6 } // namespace xsk::gsc::iw6

View File

@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
return result; return result;
@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>&
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/iw7/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "iw7.hpp"
namespace xsk::gsc::iw7
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::iw7

28
src/iw7/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::iw7
{
class context : public gsc::context
{
iw7::assembler assembler_;
iw7::disassembler disassembler_;
iw7::compiler compiler_;
iw7::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::iw7

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::iw7 namespace xsk::gsc::iw7
{ {

View File

@ -126,8 +126,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,6 +19,19 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint32_t> file_map_rev; std::unordered_map<std::string_view, std::uint32_t> file_map_rev;
std::unordered_map<std::string_view, std::uint32_t> token_map_rev; std::unordered_map<std::string_view, std::uint32_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
auto resolver::opcode_id(const std::string& name) -> std::uint8_t auto resolver::opcode_id(const std::string& name) -> std::uint8_t
{ {
@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 153> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 153> opcode_list
{{ {{
{ 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::iw7
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -31,7 +34,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::iw7 } // namespace xsk::gsc::iw7

View File

@ -20,40 +20,36 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
std::cout << result->print();
return result; return result;
} }
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/iw8/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "iw8.hpp"
namespace xsk::gsc::iw8
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::iw8

28
src/iw8/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::iw8
{
class context : public gsc::context
{
iw8::assembler assembler_;
iw8::disassembler disassembler_;
iw8::compiler compiler_;
iw8::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::iw8

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::iw8 namespace xsk::gsc::iw8
{ {

View File

@ -129,8 +129,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,6 +19,19 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint32_t> file_map_rev; std::unordered_map<std::string_view, std::uint32_t> file_map_rev;
std::unordered_map<std::string_view, std::uint32_t> token_map_rev; std::unordered_map<std::string_view, std::uint32_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
auto resolver::opcode_id(const std::string& name) -> std::uint8_t auto resolver::opcode_id(const std::string& name) -> std::uint8_t
{ {
@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 190> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 190> opcode_list
{{ {{
{ 0x00, "CAST_FIELD_OBJECT" }, { 0x00, "CAST_FIELD_OBJECT" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::iw8
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -31,7 +34,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::iw8 } // namespace xsk::gsc::iw8

View File

@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
return result; return result;
@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>&
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/s1/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "s1.hpp"
namespace xsk::gsc::s1
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::s1

28
src/s1/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::s1
{
class context : public gsc::context
{
s1::assembler assembler_;
s1::disassembler disassembler_;
s1::compiler compiler_;
s1::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::s1

View File

@ -127,8 +127,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,6 +19,19 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint16_t> file_map_rev; std::unordered_map<std::string_view, std::uint16_t> file_map_rev;
std::unordered_map<std::string_view, std::uint16_t> token_map_rev; std::unordered_map<std::string_view, std::uint16_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
auto resolver::opcode_id(const std::string& name) -> std::uint8_t auto resolver::opcode_id(const std::string& name) -> std::uint8_t
{ {
@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 154> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 154> opcode_list
{{ {{
{ 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::s1
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -31,7 +34,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::s1 } // namespace xsk::gsc::s1

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::s1 namespace xsk::gsc::s1
{ {

View File

@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
return result; return result;
@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>&
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/s2/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "s2.hpp"
namespace xsk::gsc::s2
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::s2

28
src/s2/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::s2
{
class context : public gsc::context
{
s2::assembler assembler_;
s2::disassembler disassembler_;
s2::compiler compiler_;
s2::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::s2

View File

@ -127,8 +127,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,6 +19,19 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint16_t> file_map_rev; std::unordered_map<std::string_view, std::uint16_t> file_map_rev;
std::unordered_map<std::string_view, std::uint16_t> token_map_rev; std::unordered_map<std::string_view, std::uint16_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
auto resolver::opcode_id(const std::string& name) -> std::uint8_t auto resolver::opcode_id(const std::string& name) -> std::uint8_t
{ {
@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 155> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 155> opcode_list
{{ {{
{ 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::s2
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -31,7 +34,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::s2 } // namespace xsk::gsc::s2

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::s2 namespace xsk::gsc::s2
{ {

View File

@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector<std::uint8_t>& data)
{ {
filename_ = file; filename_ = file;
auto prog = parse_buffer(filename_, data); auto prog = parse_buffer(filename_, reinterpret_cast<char*>(data.data()), data.size());
compile_program(prog); compile_program(prog);
} }
void compiler::read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) void compiler::mode(build mode)
{ {
read_callback_ = func; mode_ = mode;
} }
auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> ast::program::ptr
{ {
ast::program::ptr result(nullptr); ast::program::ptr result(nullptr);
resolver::set_reader(read_callback_); lexer lexer(mode_, file, data, size);
lexer lexer(file, reinterpret_cast<char*>(data.data()), data.size());
parser parser(lexer, result); parser parser(lexer, result);
if (parser.parse() || result == nullptr) if (parser.parse() || result == nullptr)
{ {
throw comp_error(xsk::gsc::location(&file), "An unknown error ocurred while parsing gsc file."); throw comp_error(location(&file), "An unknown error ocurred while parsing gsc file.");
} }
return result; return result;
@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector<std::uint8_t>&
auto compiler::parse_file(const std::string& file) -> ast::program::ptr auto compiler::parse_file(const std::string& file) -> ast::program::ptr
{ {
auto buffer = read_callback_(file); auto data = resolver::file_data(file);
auto result = parse_buffer(file, buffer); auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data));
return result; return result;
} }

View File

@ -24,7 +24,6 @@ class compiler : public gsc::compiler
std::vector<include_t> includes_; std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_; std::vector<animtree_t> animtrees_;
std::unordered_map<std::string, ast::expr> constants_; std::unordered_map<std::string, ast::expr> constants_;
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback_;
std::vector<block*> break_blks_; std::vector<block*> break_blks_;
std::vector<block*> continue_blks_; std::vector<block*> continue_blks_;
bool can_break_; bool can_break_;
@ -32,13 +31,12 @@ class compiler : public gsc::compiler
bool developer_thread_; bool developer_thread_;
public: public:
compiler(build mode) : mode_(mode) {}
auto output() -> std::vector<function::ptr>; auto output() -> std::vector<function::ptr>;
void compile(const std::string& file, std::vector<std::uint8_t>& data); void compile(const std::string& file, std::vector<std::uint8_t>& data);
void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func); void mode(build mode);
private: private:
auto parse_buffer(const std::string& file, std::vector<std::uint8_t>& data) -> ast::program::ptr; auto parse_buffer(const std::string& file, 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);

23
src/s4/xsk/context.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "stdafx.hpp"
#include "s4.hpp"
namespace xsk::gsc::s4
{
void context::init(build mode, read_cb_type callback)
{
compiler_.mode(mode);
resolver::init(callback);
}
void context::cleanup()
{
resolver::cleanup();
}
} // namespace xsk::gsc::s4

28
src/s4/xsk/context.hpp Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc::s4
{
class context : public gsc::context
{
s4::assembler assembler_;
s4::disassembler disassembler_;
s4::compiler compiler_;
s4::decompiler decompiler_;
public:
void init(build mode, read_cb_type callback);
void cleanup();
auto assembler() -> gsc::assembler& { return assembler_; }
auto disassembler() -> gsc::disassembler& { return disassembler_; }
auto compiler() -> gsc::compiler& { return compiler_; }
auto decompiler() -> gsc::decompiler& { return decompiler_; }
};
} // namespace xsk::gsc::s4

View File

@ -129,8 +129,8 @@ void reader::advance()
} }
} }
lexer::lexer(const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)),
mode_(build::dev), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>()) mode_(mode), header_top_(0), locs_(std::stack<location>()), readers_(std::stack<reader>())
{ {
reader_.init(data, size); reader_.init(data, size);
} }

View File

@ -58,7 +58,7 @@ class lexer
bool clean_; bool clean_;
public: public:
lexer(const std::string& name, const char* data, size_t size); lexer(build mode, const std::string& name, const char* data, size_t size);
auto lex() -> parser::symbol_type; auto lex() -> parser::symbol_type;
void push_header(const std::string& file); void push_header(const std::string& file);
void pop_header(); void pop_header();

View File

@ -19,6 +19,19 @@ std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_map_rev; std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
std::unordered_map<std::string_view, std::uint32_t> file_map_rev; std::unordered_map<std::string_view, std::uint32_t> file_map_rev;
std::unordered_map<std::string_view, std::uint32_t> token_map_rev; std::unordered_map<std::string_view, std::uint32_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr;
std::set<std::string> string_map;
void resolver::init(read_cb_type callback)
{
read_callback = callback;
}
void resolver::cleanup()
{
files.clear();
}
auto resolver::opcode_id(const std::string& name) -> std::uint8_t auto resolver::opcode_id(const std::string& name) -> std::uint8_t
{ {
@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string
return data; return data;
} }
std::function<std::vector<std::uint8_t>(const std::string&)> read_callback = nullptr;
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
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*, char*, size_t>
{ {
const auto& itr = files.find(name); const auto& itr = files.find(name);
@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple<const std::strin
throw error("couldn't open gsc file '" + name + "'"); throw error("couldn't open gsc file '" + name + "'");
} }
void resolver::set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback)
{
read_callback = callback;
}
const std::array<std::pair<std::uint8_t, const char*>, 190> opcode_list const std::array<std::pair<std::uint8_t, const char*>, 190> opcode_list
{{ {{
{ 0x00, "CAST_FIELD_OBJECT" }, { 0x00, "CAST_FIELD_OBJECT" },

View File

@ -11,6 +11,9 @@ namespace xsk::gsc::s4
class resolver class resolver
{ {
public: public:
static void init(read_cb_type callback);
static void cleanup();
static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_id(const std::string& name) -> std::uint8_t;
static auto opcode_name(std::uint8_t id) -> std::string; static auto opcode_name(std::uint8_t id) -> std::string;
@ -31,7 +34,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
}; };
} // namespace xsk::gsc::s4 } // namespace xsk::gsc::s4

View File

@ -12,6 +12,7 @@
#include "compiler.hpp" #include "compiler.hpp"
#include "decompiler.hpp" #include "decompiler.hpp"
#include "resolver.hpp" #include "resolver.hpp"
#include "context.hpp"
namespace xsk::gsc::s4 namespace xsk::gsc::s4
{ {

View File

@ -19,8 +19,6 @@ public:
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*, char*, size_t>;
static void set_reader(std::function<std::vector<std::uint8_t>(const std::string&)> callback);
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;
}; };

View File

@ -91,10 +91,7 @@ auto overwrite_prompt(const std::string& file) -> bool
namespace gsc namespace gsc
{ {
std::map<game, gsc::assembler::ptr> assemblers; std::map<game, context::ptr> contexts;
std::map<game, gsc::disassembler::ptr> disassemblers;
std::map<game, gsc::compiler::ptr> compilers;
std::map<game, gsc::decompiler::ptr> decompilers;
std::map<mode, std::function<void(game game, std::string file)>> funcs; std::map<mode, std::function<void(game game, std::string file)>> funcs;
bool zonetool = false; bool zonetool = false;
@ -129,7 +126,7 @@ void assemble_file(game game, std::string file)
{ {
try try
{ {
const auto& assembler = assemblers[game]; auto& assembler = contexts[game]->assembler();
const auto ext = std::string(".gscasm"); const auto ext = std::string(".gscasm");
const auto extpos = file.find(ext); const auto extpos = file.find(ext);
@ -140,25 +137,25 @@ void assemble_file(game game, std::string file)
auto data = utils::file::read(file + ext); auto data = utils::file::read(file + ext);
assembler->assemble(file, data); assembler.assemble(file, data);
if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin"))) if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin")))
{ {
if (zonetool) if (zonetool)
{ {
utils::file::save("assembled/" + file + ".cgsc", assembler->output_script()); utils::file::save("assembled/" + file + ".cgsc", assembler.output_script());
utils::file::save("assembled/" + file + ".cgsc.stack", assembler->output_stack()); utils::file::save("assembled/" + file + ".cgsc.stack", assembler.output_stack());
std::cout << "assembled " << file << ".cgsc\n"; std::cout << "assembled " << file << ".cgsc\n";
} }
else else
{ {
asset script; asset script;
auto uncompressed = assembler->output_stack(); auto uncompressed = assembler.output_stack();
auto compressed = utils::zlib::compress(uncompressed); auto compressed = utils::zlib::compress(uncompressed);
script.name = file; script.name = file;
script.bytecode = assembler->output_script(); script.bytecode = assembler.output_script();
script.buffer = std::move(compressed); script.buffer = std::move(compressed);
script.len = uncompressed.size(); script.len = uncompressed.size();
script.compressedLen = script.buffer.size(); script.compressedLen = script.buffer.size();
@ -180,7 +177,7 @@ void disassemble_file(game game, std::string file)
{ {
try try
{ {
const auto& disassembler = disassemblers[game]; auto& disassembler = contexts[game]->disassembler();
if (zonetool) if (zonetool)
{ {
@ -203,7 +200,7 @@ void disassemble_file(game game, std::string file)
auto script = utils::file::read(file + ".cgsc"); auto script = utils::file::read(file + ".cgsc");
auto stack = utils::file::read(file + ".cgsc.stack"); auto stack = utils::file::read(file + ".cgsc.stack");
disassembler->disassemble(file, script, stack); disassembler.disassemble(file, script, stack);
} }
else else
{ {
@ -225,14 +222,14 @@ void disassemble_file(game game, std::string file)
auto stack = utils::zlib::decompress(script.buffer, script.len); auto stack = utils::zlib::decompress(script.buffer, script.len);
disassembler->disassemble(file, script.bytecode, stack); disassembler.disassemble(file, script.bytecode, stack);
} }
auto scriptid = std::filesystem::path(file).filename().string(); auto scriptid = std::filesystem::path(file).filename().string();
if (!isdigit(scriptid.data()[0])) if (!isdigit(scriptid.data()[0]))
{ {
utils::file::save("disassembled/" + file + ".gscasm", disassembler->output_data()); utils::file::save("disassembled/" + file + ".gscasm", disassembler.output_data());
std::cout << "disassembled " << file << ".gscasm\n"; std::cout << "disassembled " << file << ".gscasm\n";
} }
else else
@ -248,7 +245,7 @@ void disassemble_file(game game, std::string file)
} }
} }
utils::file::save("disassembled/" + file + filename + ".gscasm", disassembler->output_data()); utils::file::save("disassembled/" + file + filename + ".gscasm", disassembler.output_data());
std::cout << "disassembled " << file << filename << ".gscasm\n"; std::cout << "disassembled " << file << filename << ".gscasm\n";
} }
} }
@ -262,8 +259,8 @@ void compile_file(game game, std::string file)
{ {
try try
{ {
const auto& assembler = assemblers[game]; auto& assembler = contexts[game]->assembler();
const auto& compiler = compilers[game]; auto& compiler = contexts[game]->compiler();
const auto ext = std::string(".gsc"); const auto ext = std::string(".gsc");
const auto extpos = file.find(ext); const auto extpos = file.find(ext);
@ -274,30 +271,29 @@ void compile_file(game game, std::string file)
auto data = utils::file::read(file + ext); auto data = utils::file::read(file + ext);
compiler->read_callback(utils::file::read); compiler.compile(file, data);
compiler->compile(file, data);
auto assembly = compiler->output(); auto assembly = compiler.output();
assembler->assemble(file, assembly); assembler.assemble(file, assembly);
if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin"))) if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin")))
{ {
if (zonetool) if (zonetool)
{ {
utils::file::save("compiled/" + file + ".cgsc", assembler->output_script()); utils::file::save("compiled/" + file + ".cgsc", assembler.output_script());
utils::file::save("compiled/" + file + ".cgsc.stack", assembler->output_stack()); utils::file::save("compiled/" + file + ".cgsc.stack", assembler.output_stack());
std::cout << "compiled " << file << ".cgsc\n"; std::cout << "compiled " << file << ".cgsc\n";
} }
else else
{ {
asset script; asset script;
auto uncompressed = assembler->output_stack(); auto uncompressed = assembler.output_stack();
auto compressed = utils::zlib::compress(uncompressed); auto compressed = utils::zlib::compress(uncompressed);
script.name = file; script.name = file;
script.bytecode = assembler->output_script(); script.bytecode = assembler.output_script();
script.buffer = std::move(compressed); script.buffer = std::move(compressed);
script.len = uncompressed.size(); script.len = uncompressed.size();
script.compressedLen = script.buffer.size(); script.compressedLen = script.buffer.size();
@ -319,7 +315,7 @@ void decompile_file(game game, std::string file)
{ {
try try
{ {
const auto& disassembler = disassemblers[game]; auto& disassembler = contexts[game]->disassembler();
if (zonetool) if (zonetool)
{ {
@ -342,7 +338,7 @@ void decompile_file(game game, std::string file)
auto script = utils::file::read(file + ".cgsc"); auto script = utils::file::read(file + ".cgsc");
auto stack = utils::file::read(file + ".cgsc.stack"); auto stack = utils::file::read(file + ".cgsc.stack");
disassembler->disassemble(file, script, stack); disassembler.disassemble(file, script, stack);
} }
else else
{ {
@ -364,20 +360,20 @@ void decompile_file(game game, std::string file)
auto stack = utils::zlib::decompress(script.buffer, script.len); auto stack = utils::zlib::decompress(script.buffer, script.len);
disassembler->disassemble(file, script.bytecode, stack); disassembler.disassemble(file, script.bytecode, stack);
} }
const auto& decompiler = decompilers[game]; auto& decompiler = contexts[game]->decompiler();
auto output = disassembler->output(); auto output = disassembler.output();
decompiler->decompile(file, output); decompiler.decompile(file, output);
auto scriptid = std::filesystem::path(file).filename().string(); auto scriptid = std::filesystem::path(file).filename().string();
if (!isdigit(scriptid.data()[0])) if (!isdigit(scriptid.data()[0]))
{ {
utils::file::save("decompiled/" + file + ".gsc", decompiler->output()); utils::file::save("decompiled/" + file + ".gsc", decompiler.output());
std::cout << "decompiled " << file << ".gsc\n"; std::cout << "decompiled " << file << ".gsc\n";
} }
else else
@ -393,7 +389,7 @@ void decompile_file(game game, std::string file)
} }
} }
utils::file::save("decompiled/" + file + filename + ".gsc", decompiler->output()); utils::file::save("decompiled/" + file + filename + ".gsc", decompiler.output());
std::cout << "decompiled " << file << filename << ".gsc\n"; std::cout << "decompiled " << file << filename << ".gsc\n";
} }
} }
@ -405,42 +401,25 @@ void decompile_file(game game, std::string file)
void init() void init()
{ {
assemblers[game::IW5] = std::make_unique<iw5::assembler>(); contexts[game::IW5] = std::make_unique<iw5::context>();
assemblers[game::IW6] = std::make_unique<iw6::assembler>(); contexts[game::IW5]->init(build::prod, utils::file::read);
assemblers[game::IW7] = std::make_unique<iw7::assembler>(); contexts[game::IW6] = std::make_unique<iw6::context>();
assemblers[game::IW8] = std::make_unique<iw8::assembler>(); contexts[game::IW6]->init(build::prod, utils::file::read);
assemblers[game::S1] = std::make_unique<s1::assembler>(); contexts[game::IW7] = std::make_unique<iw7::context>();
assemblers[game::S2] = std::make_unique<s2::assembler>(); contexts[game::IW7]->init(build::prod, utils::file::read);
assemblers[game::S4] = std::make_unique<s4::assembler>(); contexts[game::IW8] = std::make_unique<iw8::context>();
assemblers[game::H1] = std::make_unique<h1::assembler>(); contexts[game::IW8]->init(build::prod, utils::file::read);
assemblers[game::H2] = std::make_unique<h2::assembler>(); contexts[game::S1] = std::make_unique<s1::context>();
disassemblers[game::IW5] = std::make_unique<iw5::disassembler>(); contexts[game::S1]->init(build::prod, utils::file::read);
disassemblers[game::IW6] = std::make_unique<iw6::disassembler>(); contexts[game::S2] = std::make_unique<s2::context>();
disassemblers[game::IW7] = std::make_unique<iw7::disassembler>(); contexts[game::S2]->init(build::prod, utils::file::read);
disassemblers[game::IW8] = std::make_unique<iw8::disassembler>(); contexts[game::S4] = std::make_unique<s4::context>();
disassemblers[game::S1] = std::make_unique<s1::disassembler>(); contexts[game::S4]->init(build::prod, utils::file::read);
disassemblers[game::S2] = std::make_unique<s2::disassembler>(); contexts[game::H1] = std::make_unique<h1::context>();
disassemblers[game::S4] = std::make_unique<s4::disassembler>(); contexts[game::H1]->init(build::prod, utils::file::read);
disassemblers[game::H1] = std::make_unique<h1::disassembler>(); contexts[game::H2] = std::make_unique<h2::context>();
disassemblers[game::H2] = std::make_unique<h2::disassembler>(); contexts[game::H2]->init(build::prod, utils::file::read);
compilers[game::IW5] = std::make_unique<iw5::compiler>(build::prod);
compilers[game::IW6] = std::make_unique<iw6::compiler>(build::prod);
compilers[game::IW7] = std::make_unique<iw7::compiler>(build::prod);
compilers[game::IW8] = std::make_unique<iw8::compiler>(build::prod);
compilers[game::S1] = std::make_unique<s1::compiler>(build::prod);
compilers[game::S2] = std::make_unique<s2::compiler>(build::prod);
compilers[game::S4] = std::make_unique<s4::compiler>(build::prod);
compilers[game::H1] = std::make_unique<h1::compiler>(build::prod);
compilers[game::H2] = std::make_unique<h2::compiler>(build::prod);
decompilers[game::IW5] = std::make_unique<iw5::decompiler>();
decompilers[game::IW6] = std::make_unique<iw6::decompiler>();
decompilers[game::IW7] = std::make_unique<iw7::decompiler>();
decompilers[game::IW8] = std::make_unique<iw8::decompiler>();
decompilers[game::S1] = std::make_unique<s1::decompiler>();
decompilers[game::S2] = std::make_unique<s2::decompiler>();
decompilers[game::S4] = std::make_unique<s4::decompiler>();
decompilers[game::H1] = std::make_unique<h1::decompiler>();
decompilers[game::H2] = std::make_unique<h2::decompiler>();
funcs[mode::ASM] = assemble_file; funcs[mode::ASM] = assemble_file;
funcs[mode::DISASM] = disassemble_file; funcs[mode::DISASM] = disassemble_file;
funcs[mode::COMP] = compile_file; funcs[mode::COMP] = compile_file;

View File

@ -16,7 +16,6 @@ public:
virtual ~compiler() = default; virtual ~compiler() = default;
virtual auto output() -> std::vector<gsc::function::ptr> = 0; virtual auto output() -> std::vector<gsc::function::ptr> = 0;
virtual void compile(const std::string& file, std::vector<std::uint8_t>& data) = 0; virtual void compile(const std::string& file, std::vector<std::uint8_t>& data) = 0;
virtual void read_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) = 0;
}; };
} // namespace xsk::gsc } // namespace xsk::gsc

View File

@ -0,0 +1,26 @@
// Copyright 2022 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#pragma once
namespace xsk::gsc
{
class context
{
public:
using ptr = std::unique_ptr<context>;
virtual ~context() = default;
virtual void init(build mode, read_cb_type callback) = 0;
virtual void cleanup() = 0;
virtual auto assembler() -> assembler& = 0;
virtual auto disassembler() -> disassembler& = 0;
virtual auto compiler() -> compiler& = 0;
virtual auto decompiler() -> decompiler& = 0;
};
} // namespace xsk::gsc

View File

@ -8,6 +8,8 @@
namespace xsk::gsc namespace xsk::gsc
{ {
using read_cb_type = std::function<std::vector<std::uint8_t>(const std::string&)>;
enum class build enum class build
{ {
dev, dev,

View File

@ -24,6 +24,7 @@
#include "gsc/interfaces/disassembler.hpp" #include "gsc/interfaces/disassembler.hpp"
#include "gsc/interfaces/compiler.hpp" #include "gsc/interfaces/compiler.hpp"
#include "gsc/interfaces/decompiler.hpp" #include "gsc/interfaces/decompiler.hpp"
#include "gsc/interfaces/context.hpp"
// ARC Types // ARC Types
#include "arc/location.hpp" #include "arc/location.hpp"