diff --git a/src/h1/xsk/compiler.cpp b/src/h1/xsk/compiler.cpp index ddf36de..496cd0f 100644 --- a/src/h1/xsk/compiler.cpp +++ b/src/h1/xsk/compiler.cpp @@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; @@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector& auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/h1/xsk/compiler.hpp b/src/h1/xsk/compiler.hpp index 44a24a0..31330e2 100644 --- a/src/h1/xsk/compiler.hpp +++ b/src/h1/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/h1/xsk/context.cpp b/src/h1/xsk/context.cpp new file mode 100644 index 0000000..d287166 --- /dev/null +++ b/src/h1/xsk/context.cpp @@ -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 diff --git a/src/h1/xsk/context.hpp b/src/h1/xsk/context.hpp new file mode 100644 index 0000000..f04e179 --- /dev/null +++ b/src/h1/xsk/context.hpp @@ -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 diff --git a/src/h1/xsk/h1.hpp b/src/h1/xsk/h1.hpp index ac76c78..efe2d84 100644 --- a/src/h1/xsk/h1.hpp +++ b/src/h1/xsk/h1.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::h1 { diff --git a/src/h1/xsk/lexer.cpp b/src/h1/xsk/lexer.cpp index adc5692..1f3ade7 100644 --- a/src/h1/xsk/lexer.cpp +++ b/src/h1/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/h1/xsk/lexer.hpp b/src/h1/xsk/lexer.hpp index 2e0358e..ae5c13a 100644 --- a/src/h1/xsk/lexer.hpp +++ b/src/h1/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/h1/xsk/resolver.cpp b/src/h1/xsk/resolver.cpp index 0a7e2fd..abfa590 100644 --- a/src/h1/xsk/resolver.cpp +++ b/src/h1/xsk/resolver.cpp @@ -19,6 +19,19 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; +std::unordered_map> files; +read_cb_type read_callback = nullptr; +std::set 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 { @@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 154> opcode_list {{ { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, diff --git a/src/h1/xsk/resolver.hpp b/src/h1/xsk/resolver.hpp index 2538673..6032cfc 100644 --- a/src/h1/xsk/resolver.hpp +++ b/src/h1/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::h1 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -31,7 +34,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::h1 diff --git a/src/h2/xsk/compiler.cpp b/src/h2/xsk/compiler.cpp index d1999b2..805c135 100644 --- a/src/h2/xsk/compiler.cpp +++ b/src/h2/xsk/compiler.cpp @@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; @@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector& auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/h2/xsk/compiler.hpp b/src/h2/xsk/compiler.hpp index b5fdebf..4c302b0 100644 --- a/src/h2/xsk/compiler.hpp +++ b/src/h2/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/h2/xsk/context.cpp b/src/h2/xsk/context.cpp new file mode 100644 index 0000000..a1bf69b --- /dev/null +++ b/src/h2/xsk/context.cpp @@ -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 diff --git a/src/h2/xsk/context.hpp b/src/h2/xsk/context.hpp new file mode 100644 index 0000000..2b83d15 --- /dev/null +++ b/src/h2/xsk/context.hpp @@ -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 diff --git a/src/h2/xsk/h2.hpp b/src/h2/xsk/h2.hpp index 056c542..b035d38 100644 --- a/src/h2/xsk/h2.hpp +++ b/src/h2/xsk/h2.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::h2 { diff --git a/src/h2/xsk/lexer.cpp b/src/h2/xsk/lexer.cpp index f3a048a..6d1ad38 100644 --- a/src/h2/xsk/lexer.cpp +++ b/src/h2/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/h2/xsk/lexer.hpp b/src/h2/xsk/lexer.hpp index df618fd..8166364 100644 --- a/src/h2/xsk/lexer.hpp +++ b/src/h2/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/h2/xsk/resolver.cpp b/src/h2/xsk/resolver.cpp index 2f696b8..53a080a 100644 --- a/src/h2/xsk/resolver.cpp +++ b/src/h2/xsk/resolver.cpp @@ -19,6 +19,19 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; +std::unordered_map> files; +read_cb_type read_callback = nullptr; +std::set 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 { @@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 154> opcode_list {{ { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, diff --git a/src/h2/xsk/resolver.hpp b/src/h2/xsk/resolver.hpp index ab3b339..cbc90a2 100644 --- a/src/h2/xsk/resolver.hpp +++ b/src/h2/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::h2 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -31,7 +34,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::h2 diff --git a/src/iw5/xsk/compiler.cpp b/src/iw5/xsk/compiler.cpp index e73fe4f..2364b57 100644 --- a/src/iw5/xsk/compiler.cpp +++ b/src/iw5/xsk/compiler.cpp @@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; @@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector& auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/iw5/xsk/compiler.hpp b/src/iw5/xsk/compiler.hpp index 67f833f..00b90cb 100644 --- a/src/iw5/xsk/compiler.hpp +++ b/src/iw5/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/iw5/xsk/context.cpp b/src/iw5/xsk/context.cpp new file mode 100644 index 0000000..2a81edf --- /dev/null +++ b/src/iw5/xsk/context.cpp @@ -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 diff --git a/src/iw5/xsk/context.hpp b/src/iw5/xsk/context.hpp new file mode 100644 index 0000000..881d386 --- /dev/null +++ b/src/iw5/xsk/context.hpp @@ -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 diff --git a/src/iw5/xsk/iw5.hpp b/src/iw5/xsk/iw5.hpp index 84d94ef..93386a9 100644 --- a/src/iw5/xsk/iw5.hpp +++ b/src/iw5/xsk/iw5.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::iw5 { diff --git a/src/iw5/xsk/lexer.cpp b/src/iw5/xsk/lexer.cpp index 3131cb7..b647f42 100644 --- a/src/iw5/xsk/lexer.cpp +++ b/src/iw5/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/iw5/xsk/lexer.hpp b/src/iw5/xsk/lexer.hpp index 4470c73..26da631 100644 --- a/src/iw5/xsk/lexer.hpp +++ b/src/iw5/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/iw5/xsk/resolver.cpp b/src/iw5/xsk/resolver.cpp index 6ecb292..1958af3 100644 --- a/src/iw5/xsk/resolver.cpp +++ b/src/iw5/xsk/resolver.cpp @@ -19,9 +19,20 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; - +std::unordered_map> files; +read_cb_type read_callback = nullptr; std::set 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 { const auto itr = opcode_map_rev.find(name); @@ -264,9 +275,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -288,11 +296,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 153> opcode_list {{ { 0x00, "END" }, diff --git a/src/iw5/xsk/resolver.hpp b/src/iw5/xsk/resolver.hpp index b3ef441..2b5cd72 100644 --- a/src/iw5/xsk/resolver.hpp +++ b/src/iw5/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::iw5 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -34,7 +37,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::iw5 diff --git a/src/iw6/xsk/compiler.cpp b/src/iw6/xsk/compiler.cpp index 5c9ef95..56a55a2 100644 --- a/src/iw6/xsk/compiler.cpp +++ b/src/iw6/xsk/compiler.cpp @@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; @@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector& auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/iw6/xsk/compiler.hpp b/src/iw6/xsk/compiler.hpp index 6a2bddf..d09d6ee 100644 --- a/src/iw6/xsk/compiler.hpp +++ b/src/iw6/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/iw6/xsk/context.cpp b/src/iw6/xsk/context.cpp new file mode 100644 index 0000000..9408f90 --- /dev/null +++ b/src/iw6/xsk/context.cpp @@ -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 diff --git a/src/iw6/xsk/context.hpp b/src/iw6/xsk/context.hpp new file mode 100644 index 0000000..7a253b5 --- /dev/null +++ b/src/iw6/xsk/context.hpp @@ -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 diff --git a/src/iw6/xsk/iw6.hpp b/src/iw6/xsk/iw6.hpp index d4ced45..d32bef5 100644 --- a/src/iw6/xsk/iw6.hpp +++ b/src/iw6/xsk/iw6.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::iw6 { diff --git a/src/iw6/xsk/lexer.cpp b/src/iw6/xsk/lexer.cpp index 76b628f..c831227 100644 --- a/src/iw6/xsk/lexer.cpp +++ b/src/iw6/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/iw6/xsk/lexer.hpp b/src/iw6/xsk/lexer.hpp index 1dc4071..5f15e66 100644 --- a/src/iw6/xsk/lexer.hpp +++ b/src/iw6/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/iw6/xsk/resolver.cpp b/src/iw6/xsk/resolver.cpp index 3d55177..4cae160 100644 --- a/src/iw6/xsk/resolver.cpp +++ b/src/iw6/xsk/resolver.cpp @@ -19,6 +19,19 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; +std::unordered_map> files; +read_cb_type read_callback = nullptr; +std::set 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 { @@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 153> opcode_list {{ { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, diff --git a/src/iw6/xsk/resolver.hpp b/src/iw6/xsk/resolver.hpp index 5e9efdd..a88a272 100644 --- a/src/iw6/xsk/resolver.hpp +++ b/src/iw6/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::iw6 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -31,7 +34,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::iw6 diff --git a/src/iw7/xsk/compiler.cpp b/src/iw7/xsk/compiler.cpp index ff8d3fb..e64e4a7 100644 --- a/src/iw7/xsk/compiler.cpp +++ b/src/iw7/xsk/compiler.cpp @@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; @@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector& auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/iw7/xsk/compiler.hpp b/src/iw7/xsk/compiler.hpp index 258a06f..ed87275 100644 --- a/src/iw7/xsk/compiler.hpp +++ b/src/iw7/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/iw7/xsk/context.cpp b/src/iw7/xsk/context.cpp new file mode 100644 index 0000000..4d91663 --- /dev/null +++ b/src/iw7/xsk/context.cpp @@ -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 diff --git a/src/iw7/xsk/context.hpp b/src/iw7/xsk/context.hpp new file mode 100644 index 0000000..62a950d --- /dev/null +++ b/src/iw7/xsk/context.hpp @@ -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 diff --git a/src/iw7/xsk/iw7.hpp b/src/iw7/xsk/iw7.hpp index 18b02f2..6049c41 100644 --- a/src/iw7/xsk/iw7.hpp +++ b/src/iw7/xsk/iw7.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::iw7 { diff --git a/src/iw7/xsk/lexer.cpp b/src/iw7/xsk/lexer.cpp index 3fc6236..71f3517 100644 --- a/src/iw7/xsk/lexer.cpp +++ b/src/iw7/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/iw7/xsk/lexer.hpp b/src/iw7/xsk/lexer.hpp index 7f6cc24..29e4e4c 100644 --- a/src/iw7/xsk/lexer.hpp +++ b/src/iw7/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/iw7/xsk/resolver.cpp b/src/iw7/xsk/resolver.cpp index 8db0bc4..d27eb59 100644 --- a/src/iw7/xsk/resolver.cpp +++ b/src/iw7/xsk/resolver.cpp @@ -19,6 +19,19 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; +std::unordered_map> files; +read_cb_type read_callback = nullptr; +std::set 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 { @@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 153> opcode_list {{ { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, diff --git a/src/iw7/xsk/resolver.hpp b/src/iw7/xsk/resolver.hpp index 26de516..acab024 100644 --- a/src/iw7/xsk/resolver.hpp +++ b/src/iw7/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::iw7 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -31,7 +34,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::iw7 diff --git a/src/iw8/xsk/compiler.cpp b/src/iw8/xsk/compiler.cpp index 995a4b7..e4dfd46 100644 --- a/src/iw8/xsk/compiler.cpp +++ b/src/iw8/xsk/compiler.cpp @@ -20,40 +20,36 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; } auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/iw8/xsk/compiler.hpp b/src/iw8/xsk/compiler.hpp index 401b9db..d44d78c 100644 --- a/src/iw8/xsk/compiler.hpp +++ b/src/iw8/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/iw8/xsk/context.cpp b/src/iw8/xsk/context.cpp new file mode 100644 index 0000000..ed18fa0 --- /dev/null +++ b/src/iw8/xsk/context.cpp @@ -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 diff --git a/src/iw8/xsk/context.hpp b/src/iw8/xsk/context.hpp new file mode 100644 index 0000000..a0277fb --- /dev/null +++ b/src/iw8/xsk/context.hpp @@ -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 diff --git a/src/iw8/xsk/iw8.hpp b/src/iw8/xsk/iw8.hpp index 01a1c26..d4758a7 100644 --- a/src/iw8/xsk/iw8.hpp +++ b/src/iw8/xsk/iw8.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::iw8 { diff --git a/src/iw8/xsk/lexer.cpp b/src/iw8/xsk/lexer.cpp index f51376f..48a0f08 100644 --- a/src/iw8/xsk/lexer.cpp +++ b/src/iw8/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/iw8/xsk/lexer.hpp b/src/iw8/xsk/lexer.hpp index c6b9c62..07c4683 100644 --- a/src/iw8/xsk/lexer.hpp +++ b/src/iw8/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/iw8/xsk/resolver.cpp b/src/iw8/xsk/resolver.cpp index f7f4c83..4543a09 100644 --- a/src/iw8/xsk/resolver.cpp +++ b/src/iw8/xsk/resolver.cpp @@ -19,6 +19,19 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; +std::unordered_map> files; +read_cb_type read_callback = nullptr; +std::set 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 { @@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 190> opcode_list {{ { 0x00, "CAST_FIELD_OBJECT" }, diff --git a/src/iw8/xsk/resolver.hpp b/src/iw8/xsk/resolver.hpp index 139bc97..b918e18 100644 --- a/src/iw8/xsk/resolver.hpp +++ b/src/iw8/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::iw8 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -31,7 +34,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::iw8 diff --git a/src/s1/xsk/compiler.cpp b/src/s1/xsk/compiler.cpp index 1fd9e03..79a2eab 100644 --- a/src/s1/xsk/compiler.cpp +++ b/src/s1/xsk/compiler.cpp @@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; @@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector& auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/s1/xsk/compiler.hpp b/src/s1/xsk/compiler.hpp index 110e59a..0332f57 100644 --- a/src/s1/xsk/compiler.hpp +++ b/src/s1/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/s1/xsk/context.cpp b/src/s1/xsk/context.cpp new file mode 100644 index 0000000..e64c234 --- /dev/null +++ b/src/s1/xsk/context.cpp @@ -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 diff --git a/src/s1/xsk/context.hpp b/src/s1/xsk/context.hpp new file mode 100644 index 0000000..99db73c --- /dev/null +++ b/src/s1/xsk/context.hpp @@ -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 diff --git a/src/s1/xsk/lexer.cpp b/src/s1/xsk/lexer.cpp index af0f0ca..8fccc7b 100644 --- a/src/s1/xsk/lexer.cpp +++ b/src/s1/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/s1/xsk/lexer.hpp b/src/s1/xsk/lexer.hpp index a25c47a..a49e2c8 100644 --- a/src/s1/xsk/lexer.hpp +++ b/src/s1/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/s1/xsk/resolver.cpp b/src/s1/xsk/resolver.cpp index a43243e..890aad8 100644 --- a/src/s1/xsk/resolver.cpp +++ b/src/s1/xsk/resolver.cpp @@ -19,6 +19,19 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; +std::unordered_map> files; +read_cb_type read_callback = nullptr; +std::set 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 { @@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 154> opcode_list {{ { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, diff --git a/src/s1/xsk/resolver.hpp b/src/s1/xsk/resolver.hpp index 15c7c94..7d04731 100644 --- a/src/s1/xsk/resolver.hpp +++ b/src/s1/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::s1 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -31,7 +34,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::s1 diff --git a/src/s1/xsk/s1.hpp b/src/s1/xsk/s1.hpp index 8c3ec3c..567c96e 100644 --- a/src/s1/xsk/s1.hpp +++ b/src/s1/xsk/s1.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::s1 { diff --git a/src/s2/xsk/compiler.cpp b/src/s2/xsk/compiler.cpp index 2b90e4d..b50a286 100644 --- a/src/s2/xsk/compiler.cpp +++ b/src/s2/xsk/compiler.cpp @@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; @@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector& auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/s2/xsk/compiler.hpp b/src/s2/xsk/compiler.hpp index 067ec3a..9d0e1f9 100644 --- a/src/s2/xsk/compiler.hpp +++ b/src/s2/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/s2/xsk/context.cpp b/src/s2/xsk/context.cpp new file mode 100644 index 0000000..2c6546e --- /dev/null +++ b/src/s2/xsk/context.cpp @@ -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 diff --git a/src/s2/xsk/context.hpp b/src/s2/xsk/context.hpp new file mode 100644 index 0000000..1301ee7 --- /dev/null +++ b/src/s2/xsk/context.hpp @@ -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 diff --git a/src/s2/xsk/lexer.cpp b/src/s2/xsk/lexer.cpp index f517700..92dff73 100644 --- a/src/s2/xsk/lexer.cpp +++ b/src/s2/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/s2/xsk/lexer.hpp b/src/s2/xsk/lexer.hpp index 253fb11..edc8fa9 100644 --- a/src/s2/xsk/lexer.hpp +++ b/src/s2/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/s2/xsk/resolver.cpp b/src/s2/xsk/resolver.cpp index 6a962b2..d77c0c3 100644 --- a/src/s2/xsk/resolver.cpp +++ b/src/s2/xsk/resolver.cpp @@ -19,6 +19,19 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; +std::unordered_map> files; +read_cb_type read_callback = nullptr; +std::set 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 { @@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 155> opcode_list {{ { 0x17, "SET_NEW_LOCAL_VARIABLE_FIELD_CACHED0" }, diff --git a/src/s2/xsk/resolver.hpp b/src/s2/xsk/resolver.hpp index d304c1c..3a14c36 100644 --- a/src/s2/xsk/resolver.hpp +++ b/src/s2/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::s2 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -31,7 +34,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::s2 diff --git a/src/s2/xsk/s2.hpp b/src/s2/xsk/s2.hpp index 2e9fda0..c3d8b26 100644 --- a/src/s2/xsk/s2.hpp +++ b/src/s2/xsk/s2.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::s2 { diff --git a/src/s4/xsk/compiler.cpp b/src/s4/xsk/compiler.cpp index 27d39ef..99a69f6 100644 --- a/src/s4/xsk/compiler.cpp +++ b/src/s4/xsk/compiler.cpp @@ -20,29 +20,27 @@ void compiler::compile(const std::string& file, std::vector& data) { filename_ = file; - auto prog = parse_buffer(filename_, data); + auto prog = parse_buffer(filename_, reinterpret_cast(data.data()), data.size()); compile_program(prog); } -void compiler::read_callback(std::function(const std::string&)> func) +void compiler::mode(build mode) { - read_callback_ = func; + mode_ = mode; } -auto compiler::parse_buffer(const std::string& file, std::vector& 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); - resolver::set_reader(read_callback_); - - lexer lexer(file, reinterpret_cast(data.data()), data.size()); + lexer lexer(mode_, file, data, size); parser parser(lexer, result); 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; @@ -50,8 +48,8 @@ auto compiler::parse_buffer(const std::string& file, std::vector& auto compiler::parse_file(const std::string& file) -> ast::program::ptr { - auto buffer = read_callback_(file); - auto result = parse_buffer(file, buffer); + auto data = resolver::file_data(file); + auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); return result; } diff --git a/src/s4/xsk/compiler.hpp b/src/s4/xsk/compiler.hpp index fb4229c..a0607ec 100644 --- a/src/s4/xsk/compiler.hpp +++ b/src/s4/xsk/compiler.hpp @@ -24,7 +24,6 @@ class compiler : public gsc::compiler std::vector includes_; std::vector animtrees_; std::unordered_map constants_; - std::function(const std::string&)> read_callback_; std::vector break_blks_; std::vector continue_blks_; bool can_break_; @@ -32,13 +31,12 @@ class compiler : public gsc::compiler bool developer_thread_; public: - compiler(build mode) : mode_(mode) {} auto output() -> std::vector; void compile(const std::string& file, std::vector& data); - void read_callback(std::function(const std::string&)> func); + void mode(build mode); private: - auto parse_buffer(const std::string& file, std::vector& 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; void compile_program(const ast::program::ptr& program); void emit_include(const ast::include::ptr& include); diff --git a/src/s4/xsk/context.cpp b/src/s4/xsk/context.cpp new file mode 100644 index 0000000..4d98066 --- /dev/null +++ b/src/s4/xsk/context.cpp @@ -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 diff --git a/src/s4/xsk/context.hpp b/src/s4/xsk/context.hpp new file mode 100644 index 0000000..e14d7c5 --- /dev/null +++ b/src/s4/xsk/context.hpp @@ -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 diff --git a/src/s4/xsk/lexer.cpp b/src/s4/xsk/lexer.cpp index 13bf1f2..fb73c4a 100644 --- a/src/s4/xsk/lexer.cpp +++ b/src/s4/xsk/lexer.cpp @@ -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)), - mode_(build::dev), header_top_(0), locs_(std::stack()), readers_(std::stack()) +lexer::lexer(build mode, const std::string& name, const char* data, size_t size) : indev_(false), clean_(true), loc_(location(&name)), + mode_(mode), header_top_(0), locs_(std::stack()), readers_(std::stack()) { reader_.init(data, size); } diff --git a/src/s4/xsk/lexer.hpp b/src/s4/xsk/lexer.hpp index a70a6d0..67be8d2 100644 --- a/src/s4/xsk/lexer.hpp +++ b/src/s4/xsk/lexer.hpp @@ -58,7 +58,7 @@ class lexer bool clean_; 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; void push_header(const std::string& file); void pop_header(); diff --git a/src/s4/xsk/resolver.cpp b/src/s4/xsk/resolver.cpp index f3ad490..f9b776d 100644 --- a/src/s4/xsk/resolver.cpp +++ b/src/s4/xsk/resolver.cpp @@ -19,6 +19,19 @@ std::unordered_map function_map_rev; std::unordered_map method_map_rev; std::unordered_map file_map_rev; std::unordered_map token_map_rev; +std::unordered_map> files; +read_cb_type read_callback = nullptr; +std::set 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 { @@ -206,9 +219,6 @@ auto resolver::make_token(std::string_view str) -> std::string return data; } -std::function(const std::string&)> read_callback = nullptr; -std::unordered_map> files; - auto resolver::file_data(const std::string& name) -> std::tuple { const auto& itr = files.find(name); @@ -230,11 +240,6 @@ auto resolver::file_data(const std::string& name) -> std::tuple(const std::string&)> callback) -{ - read_callback = callback; -} - const std::array, 190> opcode_list {{ { 0x00, "CAST_FIELD_OBJECT" }, diff --git a/src/s4/xsk/resolver.hpp b/src/s4/xsk/resolver.hpp index 1596179..8ef0de6 100644 --- a/src/s4/xsk/resolver.hpp +++ b/src/s4/xsk/resolver.hpp @@ -11,6 +11,9 @@ namespace xsk::gsc::s4 class resolver { public: + static void init(read_cb_type callback); + static void cleanup(); + static auto opcode_id(const std::string& name) -> std::uint8_t; static auto opcode_name(std::uint8_t id) -> std::string; @@ -31,7 +34,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); }; } // namespace xsk::gsc::s4 diff --git a/src/s4/xsk/s4.hpp b/src/s4/xsk/s4.hpp index 216d25d..b35565a 100644 --- a/src/s4/xsk/s4.hpp +++ b/src/s4/xsk/s4.hpp @@ -12,6 +12,7 @@ #include "compiler.hpp" #include "decompiler.hpp" #include "resolver.hpp" +#include "context.hpp" namespace xsk::gsc::s4 { diff --git a/src/t6/xsk/resolver.hpp b/src/t6/xsk/resolver.hpp index 8cdffd5..62c1b41 100644 --- a/src/t6/xsk/resolver.hpp +++ b/src/t6/xsk/resolver.hpp @@ -19,8 +19,6 @@ public: static auto make_token(std::string_view str) -> std::string; static auto file_data(const std::string& name) -> std::tuple; - static void set_reader(std::function(const std::string&)> callback); - static auto fs_to_game_path(const std::filesystem::path& file) -> std::filesystem::path; }; diff --git a/src/tool/xsk/main.cpp b/src/tool/xsk/main.cpp index b1716d8..486c592 100644 --- a/src/tool/xsk/main.cpp +++ b/src/tool/xsk/main.cpp @@ -91,10 +91,7 @@ auto overwrite_prompt(const std::string& file) -> bool namespace gsc { -std::map assemblers; -std::map disassemblers; -std::map compilers; -std::map decompilers; +std::map contexts; std::map> funcs; bool zonetool = false; @@ -129,7 +126,7 @@ void assemble_file(game game, std::string file) { try { - const auto& assembler = assemblers[game]; + auto& assembler = contexts[game]->assembler(); const auto ext = std::string(".gscasm"); 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); - assembler->assemble(file, data); + assembler.assemble(file, data); if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin"))) { if (zonetool) { - 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", assembler.output_script()); + utils::file::save("assembled/" + file + ".cgsc.stack", assembler.output_stack()); std::cout << "assembled " << file << ".cgsc\n"; } else { asset script; - auto uncompressed = assembler->output_stack(); + auto uncompressed = assembler.output_stack(); auto compressed = utils::zlib::compress(uncompressed); script.name = file; - script.bytecode = assembler->output_script(); + script.bytecode = assembler.output_script(); script.buffer = std::move(compressed); script.len = uncompressed.size(); script.compressedLen = script.buffer.size(); @@ -180,7 +177,7 @@ void disassemble_file(game game, std::string file) { try { - const auto& disassembler = disassemblers[game]; + auto& disassembler = contexts[game]->disassembler(); if (zonetool) { @@ -203,7 +200,7 @@ void disassemble_file(game game, std::string file) auto script = utils::file::read(file + ".cgsc"); auto stack = utils::file::read(file + ".cgsc.stack"); - disassembler->disassemble(file, script, stack); + disassembler.disassemble(file, script, stack); } else { @@ -225,14 +222,14 @@ void disassemble_file(game game, std::string file) 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(); 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"; } 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"; } } @@ -262,8 +259,8 @@ void compile_file(game game, std::string file) { try { - const auto& assembler = assemblers[game]; - const auto& compiler = compilers[game]; + auto& assembler = contexts[game]->assembler(); + auto& compiler = contexts[game]->compiler(); const auto ext = std::string(".gsc"); 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); - 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 (zonetool) { - 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", assembler.output_script()); + utils::file::save("compiled/" + file + ".cgsc.stack", assembler.output_stack()); std::cout << "compiled " << file << ".cgsc\n"; } else { asset script; - auto uncompressed = assembler->output_stack(); + auto uncompressed = assembler.output_stack(); auto compressed = utils::zlib::compress(uncompressed); script.name = file; - script.bytecode = assembler->output_script(); + script.bytecode = assembler.output_script(); script.buffer = std::move(compressed); script.len = uncompressed.size(); script.compressedLen = script.buffer.size(); @@ -319,7 +315,7 @@ void decompile_file(game game, std::string file) { try { - const auto& disassembler = disassemblers[game]; + auto& disassembler = contexts[game]->disassembler(); if (zonetool) { @@ -342,7 +338,7 @@ void decompile_file(game game, std::string file) auto script = utils::file::read(file + ".cgsc"); auto stack = utils::file::read(file + ".cgsc.stack"); - disassembler->disassemble(file, script, stack); + disassembler.disassemble(file, script, stack); } else { @@ -364,20 +360,20 @@ void decompile_file(game game, std::string file) 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(); 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"; } 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"; } } @@ -405,42 +401,25 @@ void decompile_file(game game, std::string file) void init() { - assemblers[game::IW5] = std::make_unique(); - assemblers[game::IW6] = std::make_unique(); - assemblers[game::IW7] = std::make_unique(); - assemblers[game::IW8] = std::make_unique(); - assemblers[game::S1] = std::make_unique(); - assemblers[game::S2] = std::make_unique(); - assemblers[game::S4] = std::make_unique(); - assemblers[game::H1] = std::make_unique(); - assemblers[game::H2] = std::make_unique(); - disassemblers[game::IW5] = std::make_unique(); - disassemblers[game::IW6] = std::make_unique(); - disassemblers[game::IW7] = std::make_unique(); - disassemblers[game::IW8] = std::make_unique(); - disassemblers[game::S1] = std::make_unique(); - disassemblers[game::S2] = std::make_unique(); - disassemblers[game::S4] = std::make_unique(); - disassemblers[game::H1] = std::make_unique(); - disassemblers[game::H2] = std::make_unique(); - compilers[game::IW5] = std::make_unique(build::prod); - compilers[game::IW6] = std::make_unique(build::prod); - compilers[game::IW7] = std::make_unique(build::prod); - compilers[game::IW8] = std::make_unique(build::prod); - compilers[game::S1] = std::make_unique(build::prod); - compilers[game::S2] = std::make_unique(build::prod); - compilers[game::S4] = std::make_unique(build::prod); - compilers[game::H1] = std::make_unique(build::prod); - compilers[game::H2] = std::make_unique(build::prod); - decompilers[game::IW5] = std::make_unique(); - decompilers[game::IW6] = std::make_unique(); - decompilers[game::IW7] = std::make_unique(); - decompilers[game::IW8] = std::make_unique(); - decompilers[game::S1] = std::make_unique(); - decompilers[game::S2] = std::make_unique(); - decompilers[game::S4] = std::make_unique(); - decompilers[game::H1] = std::make_unique(); - decompilers[game::H2] = std::make_unique(); + contexts[game::IW5] = std::make_unique(); + contexts[game::IW5]->init(build::prod, utils::file::read); + contexts[game::IW6] = std::make_unique(); + contexts[game::IW6]->init(build::prod, utils::file::read); + contexts[game::IW7] = std::make_unique(); + contexts[game::IW7]->init(build::prod, utils::file::read); + contexts[game::IW8] = std::make_unique(); + contexts[game::IW8]->init(build::prod, utils::file::read); + contexts[game::S1] = std::make_unique(); + contexts[game::S1]->init(build::prod, utils::file::read); + contexts[game::S2] = std::make_unique(); + contexts[game::S2]->init(build::prod, utils::file::read); + contexts[game::S4] = std::make_unique(); + contexts[game::S4]->init(build::prod, utils::file::read); + contexts[game::H1] = std::make_unique(); + contexts[game::H1]->init(build::prod, utils::file::read); + contexts[game::H2] = std::make_unique(); + contexts[game::H2]->init(build::prod, utils::file::read); + funcs[mode::ASM] = assemble_file; funcs[mode::DISASM] = disassemble_file; funcs[mode::COMP] = compile_file; diff --git a/src/utils/xsk/gsc/interfaces/compiler.hpp b/src/utils/xsk/gsc/interfaces/compiler.hpp index 77ea9b2..7363f45 100644 --- a/src/utils/xsk/gsc/interfaces/compiler.hpp +++ b/src/utils/xsk/gsc/interfaces/compiler.hpp @@ -16,7 +16,6 @@ public: virtual ~compiler() = default; virtual auto output() -> std::vector = 0; virtual void compile(const std::string& file, std::vector& data) = 0; - virtual void read_callback(std::function(const std::string&)> func) = 0; }; } // namespace xsk::gsc diff --git a/src/utils/xsk/gsc/interfaces/context.hpp b/src/utils/xsk/gsc/interfaces/context.hpp new file mode 100644 index 0000000..3600cdb --- /dev/null +++ b/src/utils/xsk/gsc/interfaces/context.hpp @@ -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; + + 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 diff --git a/src/utils/xsk/gsc/types.hpp b/src/utils/xsk/gsc/types.hpp index 892ea87..2136166 100644 --- a/src/utils/xsk/gsc/types.hpp +++ b/src/utils/xsk/gsc/types.hpp @@ -8,6 +8,8 @@ namespace xsk::gsc { +using read_cb_type = std::function(const std::string&)>; + enum class build { dev, diff --git a/src/utils/xsk/utils.hpp b/src/utils/xsk/utils.hpp index 2aa2b28..20d1f65 100644 --- a/src/utils/xsk/utils.hpp +++ b/src/utils/xsk/utils.hpp @@ -24,6 +24,7 @@ #include "gsc/interfaces/disassembler.hpp" #include "gsc/interfaces/compiler.hpp" #include "gsc/interfaces/decompiler.hpp" +#include "gsc/interfaces/context.hpp" // ARC Types #include "arc/location.hpp"