aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Spartan322 <Megacake1234@gmail.com>2024-08-09 01:42:33 +0200
committer Spartan322 <Megacake1234@gmail.com>2024-08-09 01:42:33 +0200
commitd40a80dba258ca6b59f860196af93f93facecb93 (patch)
treed8afdf2548126a3a1cb53534a6960973728b1aa8
parentc9eacf63113e15ef20ff3732d5de5189e81a2d7d (diff)
-rw-r--r--src/openvic-simulation/vm/Builtin.cpp117
-rw-r--r--src/openvic-simulation/vm/Builtin.hpp77
-rw-r--r--src/openvic-simulation/vm/Codegen.cpp143
-rw-r--r--src/openvic-simulation/vm/Codegen.hpp34
-rw-r--r--src/openvic-simulation/vm/VirtualMachine.hpp8
5 files changed, 309 insertions, 70 deletions
diff --git a/src/openvic-simulation/vm/Builtin.cpp b/src/openvic-simulation/vm/Builtin.cpp
index c5c62e9..2ba8457 100644
--- a/src/openvic-simulation/vm/Builtin.cpp
+++ b/src/openvic-simulation/vm/Builtin.cpp
@@ -1,20 +1,21 @@
#include "vm/Builtin.hpp"
-#include "InstanceManager.hpp"
-#include "vm/Codegen.hpp"
+#include "GameManager.hpp"
+#include <lauf/asm/type.h>
#include <lauf/runtime/builtin.h>
#include <lauf/runtime/memory.h>
#include <lauf/runtime/process.h>
#include <lauf/runtime/value.h>
-OpenVic::Asm::scope_variant*
-get_keyword_scope(OpenVic::InstanceManager* instance_manager, const char* keyword, OpenVic::Vm::Codegen::scope_type type) {
- // TODO: get scope native pointer from name and type
+OpenVic::Asm::scope_store_variant* create_scope( //
+ OpenVic::GameManager* instance_manager, const char* scope_name, OpenVic::Asm::scope_store_variant* relative_scope
+) {
+ // TODO: create scope based on scope_name and relative_scope
return nullptr;
}
bool execute_effect(
- OpenVic::InstanceManager* instance_manager, const char* effect_id, OpenVic::Asm::scope_variant& scope,
+ OpenVic::GameManager* instance_manager, const char* effect_id, OpenVic::Asm::scope_store_variant& scope,
OpenVic::Asm::argument* arguments, std::size_t arg_count
) {
// TODO: execute effect based on id, scope, and arguments
@@ -22,7 +23,7 @@ bool execute_effect(
}
bool execute_trigger(
- OpenVic::InstanceManager* instance_manager, const char* trigger_id, OpenVic::Asm::scope_variant& scope,
+ OpenVic::GameManager* instance_manager, const char* trigger_id, OpenVic::Asm::scope_store_variant& scope,
OpenVic::Asm::argument* arguments, std::size_t arg_count, bool* result
) {
// TODO: execute trigger based on id, scope, and arguments
@@ -37,7 +38,7 @@ LAUF_RUNTIME_BUILTIN(call_effect, 3, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "call_effe
auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data);
auto effect_name_addr = vstack_ptr[0].as_address;
- auto scope_ptr = static_cast<OpenVic::Asm::scope_variant*>(vstack_ptr[1].as_native_ptr);
+ auto scope_def_ptr = static_cast<OpenVic::Asm::scope_store_variant*>(vstack_ptr[1].as_native_ptr);
auto argument_array_addr = vstack_ptr[2].as_address;
auto effect_name = lauf_runtime_get_cstr(process, effect_name_addr);
@@ -55,7 +56,7 @@ LAUF_RUNTIME_BUILTIN(call_effect, 3, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "call_effe
auto argument_array =
static_cast<OpenVic::Asm::argument*>(lauf_runtime_get_mut_ptr(process, argument_array_addr, { 1, 1 }));
- if (!execute_effect(vm_data->instance_manager, effect_name, *scope_ptr, argument_array, count)) {
+ if (!execute_effect(vm_data->game_manager, effect_name, *scope_def_ptr, argument_array, count)) {
return lauf_runtime_panic(process, "effect could not be found");
}
@@ -92,8 +93,8 @@ LAUF_RUNTIME_BUILTIN(call_trigger, 3, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "call_tri
bool trigger_result;
if (!execute_trigger(
- static_cast<OpenVic::InstanceManager*>(user_data), effect_name,
- *static_cast<OpenVic::Asm::scope_variant*>(scope_ptr), argument_array, count, &trigger_result
+ vm_data->game_manager, effect_name, *static_cast<OpenVic::Asm::scope_store_variant*>(scope_ptr), argument_array,
+ count, &trigger_result
)) {
return lauf_runtime_panic(process, "trigger could not be found");
}
@@ -134,7 +135,9 @@ LAUF_RUNTIME_BUILTIN(
LAUF_RUNTIME_BUILTIN_DISPATCH;
}
-LAUF_RUNTIME_BUILTIN(load_scope_ptr, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_scope_ptr", &translate_address_to_string) {
+LAUF_RUNTIME_BUILTIN(
+ load_static_scope_ptr, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_static_scope_ptr", &translate_address_to_string
+) {
auto user_data = lauf_runtime_get_vm_user_data(process);
if (user_data == nullptr) {
return lauf_runtime_panic(process, "invalid user data");
@@ -143,11 +146,97 @@ LAUF_RUNTIME_BUILTIN(load_scope_ptr, 1, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_s
auto scope_ref_position = vstack_ptr[0].as_uint;
- if (scope_ref_position >= vm_data->scope_references.size()) {
+ if (scope_ref_position >= vm_data->scope_refs.size()) {
return lauf_runtime_panic(process, "invalid scope reference value");
}
- vstack_ptr[0].as_native_ptr = &vm_data->scope_references[scope_ref_position];
+ vstack_ptr[0].as_native_ptr = &vm_data->scope_refs[scope_ref_position];
+
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}
+
+LAUF_RUNTIME_BUILTIN(
+ load_relative_scope_ptr, 2, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_relative_scope_ptr", &load_static_scope_ptr
+) {
+ auto user_data = lauf_runtime_get_vm_user_data(process);
+ if (user_data == nullptr) {
+ return lauf_runtime_panic(process, "invalid user data");
+ }
+ auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data);
+
+ auto scope_name_addr = vstack_ptr[0].as_address;
+ auto vstack_1 = vstack_ptr[1];
+ auto relative_scope = static_cast<OpenVic::Asm::scope_store_variant*>(vstack_ptr[1].as_native_ptr);
+
+ auto scope_name = lauf_runtime_get_cstr(process, scope_name_addr);
+ if (scope_name == nullptr) {
+ return lauf_runtime_panic(process, "invalid scope name address");
+ }
+
+ vstack_ptr++;
+
+ auto scope = create_scope(vm_data->game_manager, scope_name, relative_scope);
+
+ if (scope == nullptr) {
+ return lauf_runtime_panic(process, "could not create scope");
+ }
+
+ vm_data->scope_refs.emplace_back(std::move(*scope));
+ delete scope;
+
+ vstack_ptr[0].as_native_ptr = &vm_data->scope_refs.back();
+
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}
+
+LAUF_RUNTIME_BUILTIN(push_current_scope, 1, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "push_current_scope", &load_relative_scope_ptr) {
+ auto user_data = lauf_runtime_get_vm_user_data(process);
+ if (user_data == nullptr) {
+ return lauf_runtime_panic(process, "invalid user data");
+ }
+ auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data);
+
+ auto current_scope = static_cast<OpenVic::Asm::scope_store_variant*>(vstack_ptr[0].as_native_ptr);
+
+ vm_data->scope_stack.push(current_scope);
+
+ vstack_ptr++;
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}
+
+LAUF_RUNTIME_BUILTIN(pop_current_scope, 0, 0, LAUF_RUNTIME_BUILTIN_DEFAULT, "pop_current_scope", &push_current_scope) {
+ auto user_data = lauf_runtime_get_vm_user_data(process);
+ if (user_data == nullptr) {
+ return lauf_runtime_panic(process, "invalid user data");
+ }
+ auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data);
+
+ if (vm_data->scope_stack.empty()) {
+ return lauf_runtime_panic(process, "scope stack empty");
+ }
+
+ if (vm_data->scope_stack.size() == 1) {
+ return lauf_runtime_panic(process, "attempt to pop last scope in stack");
+ }
+
+ vm_data->scope_stack.pop();
+
+ LAUF_RUNTIME_BUILTIN_DISPATCH;
+}
+
+LAUF_RUNTIME_BUILTIN(load_current_scope, 0, 1, LAUF_RUNTIME_BUILTIN_DEFAULT, "load_current_scope", &pop_current_scope) {
+ auto user_data = lauf_runtime_get_vm_user_data(process);
+ if (user_data == nullptr) {
+ return lauf_runtime_panic(process, "invalid user data");
+ }
+ auto vm_data = static_cast<OpenVic::Vm::VmUserData*>(user_data);
+
+ if (vm_data->scope_stack.empty()) {
+ return lauf_runtime_panic(process, "scope stack empty");
+ }
+
+ vstack_ptr--;
+ vstack_ptr[0].as_native_ptr = vm_data->scope_stack.top();
LAUF_RUNTIME_BUILTIN_DISPATCH;
}
diff --git a/src/openvic-simulation/vm/Builtin.hpp b/src/openvic-simulation/vm/Builtin.hpp
index 9f72350..342acee 100644
--- a/src/openvic-simulation/vm/Builtin.hpp
+++ b/src/openvic-simulation/vm/Builtin.hpp
@@ -1,10 +1,31 @@
#pragma once
#include <cstdint>
+#include <stack>
#include <variant>
-#include "InstanceManager.hpp"
+#include "GameManager.hpp"
+#include "country/CountryDefinition.hpp"
+#include "economy/BuildingType.hpp"
+#include "map/Crime.hpp"
+#include "map/ProvinceDefinition.hpp"
+#include "map/State.hpp"
+#include "military/Leader.hpp"
+#include "military/LeaderTrait.hpp"
+#include "military/UnitType.hpp"
+#include "misc/Event.hpp"
+#include "misc/Modifier.hpp"
+#include "politics/Government.hpp"
+#include "politics/Ideology.hpp"
+#include "politics/Issue.hpp"
+#include "politics/NationalValue.hpp"
+#include "pop/Culture.hpp"
+#include "pop/Pop.hpp"
+#include "pop/Religion.hpp"
+#include "research/Technology.hpp"
#include "types/fixed_point/FixedPoint.hpp"
+#include <lauf/runtime/memory.h>
+#include <lauf/runtime/value.h>
extern "C" {
typedef struct lauf_runtime_builtin lauf_runtime_builtin;
@@ -28,24 +49,55 @@ extern "C" {
// As above, but translates to a C string.
extern const lauf_runtime_builtin translate_address_to_string;
- // This builtin takes three arguments:
+ // This builtin takes one argument:
// * vstack_ptr[0] is a uint for the position of the pointer variant in scope_references
// Returns scope native pointer
- extern const lauf_runtime_builtin load_scope_ptr;
+ extern const lauf_runtime_builtin load_static_scope_ptr;
+
+ // This builtin takes two arguments:
+ // * vstack_ptr[0] is an address for the name of the scope
+ // * vstack_ptr[1] is the native pointer for the relative scope
+ // Returns scope native pointer
+ extern const lauf_runtime_builtin load_relative_scope_ptr;
+
+ // This builtin takes one argument:
+ // * vstack_ptr[0] is the native pointer to push to the scope stack
+ extern const lauf_runtime_builtin push_current_scope;
+
+ // This builtin takes no arguments and pops the current off the stack
+ extern const lauf_runtime_builtin pop_current_scope;
+
+ // This builtin takes no arguments
+ // Returns scope native pointer
+ extern const lauf_runtime_builtin load_current_scope;
}
namespace OpenVic::Asm {
- using scope_variant = std::variant<std::monostate>;
+ using scope_store_variant = std::variant<
+ std::monostate, //
+ // Actual scopes
+ const OpenVic::CountryDefinition*, const OpenVic::Region*, const OpenVic::ProvinceDefinition*, OpenVic::Pop*, //
+ // Variant data for scope-like behavior
+ const OpenVic::Continent*, const OpenVic::PopType*, const OpenVic::UnitType*, const OpenVic::BuildingType*, //
+ const OpenVic::Crime*, const OpenVic::Culture*, const OpenVic::Religion*, const OpenVic::ReformGroup*,
+ const OpenVic::IssueGroup*, const OpenVic::Issue*, const OpenVic::Ideology*, const OpenVic::CountryParty*,
+ OpenVic::LeaderBase*, const OpenVic::LeaderTrait*, const OpenVic::Event* /*, trade good, resource*/, //
+ const OpenVic::Technology*, const OpenVic::GovernmentType* /*, casus belli */,
+ const OpenVic::NationalValue*
+ /*, variable, global flag, country flag */,
+ const OpenVic::Modifier* /*, province flag */
+ >;
struct argument {
const char* key;
union {
const char* as_cstr;
- const scope_variant* as_scope;
+ const scope_store_variant* as_scope;
std::uint64_t as_uint;
std::int64_t as_int;
const void* as_ptr;
+ lauf_runtime_function_address as_function_address;
} value;
enum class type_t : std::uint8_t { //
@@ -54,6 +106,7 @@ namespace OpenVic::Asm {
uint,
int_,
ptr,
+ function_address,
fixed_point
} type;
@@ -64,7 +117,7 @@ namespace OpenVic::Asm {
return value.as_cstr;
}
- const scope_variant* val_scope() const {
+ const scope_store_variant* val_scope() const {
if (type != type_t::scope) {
return nullptr;
}
@@ -92,6 +145,13 @@ namespace OpenVic::Asm {
return value.as_ptr;
}
+ lauf_runtime_function_address val_func_addr() const {
+ if (type != type_t::function_address) {
+ return lauf_runtime_function_address_null;
+ }
+ return value.as_function_address;
+ }
+
OpenVic::fixed_point_t val_fixed() const {
if (type != type_t::fixed_point) {
return 0;
@@ -103,7 +163,8 @@ namespace OpenVic::Asm {
namespace OpenVic::Vm {
struct VmUserData {
- std::vector<Asm::scope_variant> scope_references;
- InstanceManager* instance_manager;
+ std::vector<Asm::scope_store_variant> scope_refs;
+ std::stack<Asm::scope_store_variant*> scope_stack;
+ GameManager* game_manager;
};
}
diff --git a/src/openvic-simulation/vm/Codegen.cpp b/src/openvic-simulation/vm/Codegen.cpp
index a31f6c5..a754e53 100644
--- a/src/openvic-simulation/vm/Codegen.cpp
+++ b/src/openvic-simulation/vm/Codegen.cpp
@@ -6,6 +6,7 @@
#include <cstring>
#include <string_view>
#include <unordered_map>
+#include <variant>
#include <openvic-dataloader/detail/SymbolIntern.hpp>
#include <openvic-dataloader/detail/Utility.hpp>
@@ -20,6 +21,7 @@
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/algorithm/reverse.hpp>
+#include "GameManager.hpp"
#include "types/fixed_point/FixedPoint.hpp"
#include "vm/Builtin.hpp"
#include <lauf/asm/builder.h>
@@ -40,15 +42,15 @@ bool ichar_equals(char a, char b) {
}
Codegen::Codegen(
- ovdl::v2script::Parser const& parser, OpenVic::InstanceManager* instance_manager, const char* module_name,
+ ovdl::v2script::Parser const& parser, OpenVic::GameManager* game_manager, const char* module_name,
lauf_asm_build_options options
)
- : _parser(parser), _instance_manager(instance_manager), _module(module_name), _builder(options) {}
+ : _parser(parser), _game_manager(game_manager), _module(module_name), _builder(options) {}
Codegen::Codegen(
- ovdl::v2script::Parser const& parser, OpenVic::InstanceManager* instance_manager, Module&& module, AsmBuilder&& builder
+ ovdl::v2script::Parser const& parser, OpenVic::GameManager* game_manager, Module&& module, AsmBuilder&& builder
)
- : _parser(parser), _instance_manager(instance_manager), _module(std::move(module)), _builder(std::move(builder)) {}
+ : _parser(parser), _game_manager(game_manager), _module(std::move(module)), _builder(std::move(builder)) {}
static constexpr auto any_ = "any_"sv;
static constexpr auto all_ = "all_"sv;
@@ -72,8 +74,7 @@ Codegen::scope_type Codegen::get_scope_type_for(scope_execution_type execution_t
if (_parser.find_intern(#NAME##sv) == name) \
return SCOPE_TYPE
- FIND_SCOPE(Generic, THIS);
- FIND_SCOPE(Generic, FROM);
+ FIND_SCOPE(Generic, this);
FIND_SCOPE(Generic, from);
// Country and Pop Scope
@@ -120,29 +121,74 @@ Codegen::scope_type Codegen::get_scope_type_for(scope_execution_type execution_t
return None;
}
-void Codegen::generate_effect_from(scope_type type, Node* node) {
+OpenVic::Asm::scope_store_variant Codegen::get_static_scope( //
+ scope_execution_type execution_type, scope_type active_scope_type, ovdl::symbol<char> name
+) const {
+ auto name_sv = name.view();
+
+ auto country =
+ _game_manager->get_definition_manager().get_country_definition_manager().get_country_definition_by_identifier(name_sv);
+ if (country != nullptr) {
+ return country;
+ }
+
+ auto state_region = _game_manager->get_definition_manager().get_map_definition().get_region_by_identifier(name_sv);
+ if (state_region != nullptr) {
+ return state_region;
+ }
+
+ auto province = _game_manager->get_definition_manager().get_map_definition().get_province_definition_by_identifier(name_sv);
+ if (province != nullptr) {
+ return province;
+ }
+
+ return {};
+}
+
+static constexpr auto random_ = "random_"sv;
+
+bool Codegen::supports_limit(scope_execution_type execution_type, scope_type active_scope_type, ovdl::symbol<char> name) const {
+ if (is_iterative_scope(execution_type, active_scope_type, name)) {
+ return true;
+ }
+
+ if (std::strncmp(name.c_str(), random_.data(), random_.size()) == 0) {
+ return true;
+ }
+
+ // TODO: decide limit support
+ return false;
+}
+
+void Codegen::generate_effect_from(scope_type type, const Node* node) {
struct current_scope_t {
scope_type type;
ovdl::symbol<char> symbol;
} current_scope { .type = type, .symbol = {} };
bool is_arguments = false;
- std::unordered_map<ovdl::symbol<char>, FlatValue const*, symbol_hash> named_arguments;
+ std::unordered_map<ovdl::symbol<char>, const Node*, symbol_hash> named_arguments;
Asm::argument::type_t ov_asm_type;
dryad::visit_tree(
node, //
[&](dryad::child_visitor<NodeKind> visitor, const AssignStatement* statement) {
- auto const* left = dryad::node_try_cast<FlatValue>(statement->left());
+ using enum Codegen::scope_execution_type;
+
+ const auto* left = dryad::node_try_cast<FlatValue>(statement->left());
if (!left) {
return;
}
- auto const* right = dryad::node_try_cast<FlatValue>(statement->right());
+ const auto* right = dryad::node_try_cast<FlatValue>(statement->right());
if (is_arguments) {
if (right) {
named_arguments.insert_or_assign(left->value(), right);
return;
+ } else if (supports_limit(Effect, current_scope.type, current_scope.symbol) &&
+ _parser.find_intern("limit"sv) == left->value()) {
+ named_arguments.insert_or_assign(left->value(), statement->right());
+ return;
}
// Boils war's attacker_goal = { casus_belli = [casus belli] } down to attacker_goal = [casus belli]
@@ -163,7 +209,16 @@ void Codegen::generate_effect_from(scope_type type, Node* node) {
lauf_asm_local* arguments = nullptr;
if (!right) {
- using enum Codegen::scope_execution_type;
+ if (_parser.find_intern("random"sv) == left->value()) {
+ // TODO: implement random
+ return;
+ }
+
+ if (_parser.find_intern("random_list"sv) == left->value()) {
+ // TODO: implement random_list
+ return;
+ }
+
is_arguments = current_scope.type >> get_scope_type_for(Effect, left->value());
if (!is_arguments) {
current_scope_t previous_scope = current_scope;
@@ -211,7 +266,7 @@ void Codegen::generate_effect_from(scope_type type, Node* node) {
// Load arguments address (vstack[2])
lauf_asm_inst_local_addr(*this, arguments);
// Load scope address in lauf (vstack[1])
- push_instruction_for_keyword_scope(scope_execution_type::Effect, current_scope.type, current_scope.symbol);
+ push_instruction_for_scope(scope_execution_type::Effect, current_scope.type, current_scope.symbol);
// Create effect name literal (vstack[0])
auto effect_name = lauf_asm_build_string_literal(*this, left->value().c_str());
lauf_asm_inst_global_addr(*this, effect_name);
@@ -228,7 +283,7 @@ void Codegen::generate_effect_from(scope_type type, Node* node) {
return;
}
- if (push_instruction_for_keyword_scope(scope_execution_type::Effect, current_scope.type, value->value())) {
+ if (push_instruction_for_scope(scope_execution_type::Effect, current_scope.type, value->value())) {
ov_asm_type = scope;
return;
}
@@ -259,16 +314,25 @@ void Codegen::generate_effect_from(scope_type type, Node* node) {
}
// Create argument string literal
- auto argument_str = lauf_asm_build_string_literal(*this, value->value().c_str());
+ auto argument_str =
+ lauf_asm_build_data_literal(*this, reinterpret_cast<const unsigned char*>(view.data()), view.size());
lauf_asm_inst_global_addr(*this, argument_str);
ov_asm_type = cstring;
+ },
+ [&](dryad::child_visitor<NodeKind> visitor, const ListValue* value) {
+ if (!is_arguments) {
+ visitor(value);
+ return;
+ }
- // TODO: find/create and insert value here
+ auto limit_function = create_condition_function(current_scope.type, value);
+ lauf_asm_inst_function_addr(*this, limit_function);
+ ov_asm_type = Asm::argument::type_t::function_address;
}
);
}
-void Codegen::generate_condition_from(scope_type type, Node* node) {
+void Codegen::generate_condition_from(scope_type type, const Node* node) {
struct current_scope_t {
scope_type type;
ovdl::symbol<char> symbol;
@@ -306,25 +370,47 @@ void Codegen::generate_condition_from(scope_type type, Node* node) {
);
}
-bool Codegen::push_instruction_for_keyword_scope(
+bool Codegen::push_instruction_for_scope(
scope_execution_type execution_type, scope_type type, ovdl::symbol<char> scope_symbol
) {
if (type >> get_scope_type_for(execution_type, scope_symbol)) {
- lauf_asm_inst_uint(*this, _scope_references.size());
- _scope_references.push_back(get_scope_for(execution_type, type, scope_symbol));
- // TODO: push scope into _scope_references
- lauf_asm_inst_call_builtin(*this, load_scope_ptr);
+ if (auto static_scope = get_static_scope(execution_type, type, scope_symbol);
+ !std::holds_alternative<std::monostate>(static_scope)) {
+ lauf_asm_inst_uint(*this, _scope_definitions.size());
+ _scope_definitions.push_back(std::move(static_scope));
+ lauf_asm_inst_call_builtin(*this, load_static_scope_ptr);
+ return true;
+ }
+
+#define SCOPE_LIST(END) \
+ X(from) \
+ X(this) \
+ X(year) \
+ X(month) \
+ X(has_global_flag) \
+ X(is_canal_enabled) \
+ END
+
+#define X(SCOPE_NAME) _parser.find_intern(#SCOPE_NAME##sv) == scope_symbol ||
+
+ if (SCOPE_LIST(false)) {
+ lauf_asm_inst_null(*this);
+ } else {
+ lauf_asm_inst_call_builtin(*this, load_current_scope);
+ }
+
+#undef X
+#undef SCOPE_LIST
+
+ auto scope_str = lauf_asm_build_string_literal(*this, scope_symbol.c_str());
+ lauf_asm_inst_global_addr(*this, scope_str);
+ lauf_asm_inst_call_builtin(*this, load_relative_scope_ptr);
+ return true;
}
return false;
}
-OpenVic::Asm::scope_variant Codegen::get_scope_for( //
- scope_execution_type execution_type, scope_type type, ovdl::symbol<char> scope_symbol
-) const {
- return {};
-}
-
static constexpr lauf_asm_layout ov_asm_argument_layout[] = { LAUF_ASM_NATIVE_LAYOUT_OF(OpenVic::Asm::argument::key),
LAUF_ASM_NATIVE_LAYOUT_OF(OpenVic::Asm::argument::type),
LAUF_ASM_NATIVE_LAYOUT_OF(OpenVic::Asm::argument::value) };
@@ -373,11 +459,14 @@ bool Codegen::inst_store_ov_asm_value_from_vstack(lauf_asm_local* local, std::si
case cstring:
// Translate key literal to cstring
lauf_asm_inst_call_builtin(*this, translate_address_to_string);
+ break;
case ptr:
// Translate address to pointer
lauf_asm_inst_call_builtin(*this, translate_address_to_pointer);
+ break;
case scope:
// Scope pointer is already native
+ case function_address:
case uint:
case int_:
case fixed_point:
diff --git a/src/openvic-simulation/vm/Codegen.hpp b/src/openvic-simulation/vm/Codegen.hpp
index e7caee0..f8629e8 100644
--- a/src/openvic-simulation/vm/Codegen.hpp
+++ b/src/openvic-simulation/vm/Codegen.hpp
@@ -7,7 +7,7 @@
#include <openvic-dataloader/v2script/Parser.hpp>
#include "AsmBuilder.hpp"
-#include "InstanceManager.hpp"
+#include "GameManager.hpp"
#include "Module.hpp"
#include "types/EnumBitfield.hpp"
#include "vm/Builtin.hpp"
@@ -18,11 +18,11 @@
namespace OpenVic::Vm {
struct Codegen {
Codegen(
- ovdl::v2script::Parser const& parser, InstanceManager* instance_manager, const char* module_name,
+ ovdl::v2script::Parser const& parser, GameManager* instance_manager, const char* module_name,
lauf_asm_build_options options = lauf_asm_default_build_options
);
- Codegen(ovdl::v2script::Parser const& parser, InstanceManager* instance_manager, Module&& module, AsmBuilder&& builder);
+ Codegen(ovdl::v2script::Parser const& parser, GameManager* instance_manager, Module&& module, AsmBuilder&& builder);
operator lauf_asm_module*() {
return _module;
@@ -57,7 +57,7 @@ namespace OpenVic::Vm {
}
OpenVicVirtualMachine create_virtual_machine() && {
- return { _instance_manager, std::move(_scope_references) };
+ return { _game_manager, std::move(_scope_definitions) };
}
lauf_asm_block* create_block(size_t input_count) {
@@ -89,24 +89,24 @@ namespace OpenVic::Vm {
is_iterative_scope(scope_execution_type execution_type, scope_type active_scope_type, ovdl::symbol<char> name) const;
scope_type get_scope_type_for(scope_execution_type execution_type, ovdl::symbol<char> name) const;
- lauf_asm_function* create_effect_function(scope_type type, ovdl::v2script::ast::Node* node);
- lauf_asm_function* create_condition_function(scope_type type, ovdl::v2script::ast::Node* node);
+ OpenVic::Asm::scope_store_variant get_static_scope( //
+ scope_execution_type execution_type, scope_type active_scope_type, ovdl::symbol<char> name
+ ) const;
+
+ bool supports_limit(scope_execution_type execution_type, scope_type active_scope_type, ovdl::symbol<char> name) const;
+
+ lauf_asm_function* create_effect_function(scope_type type, const ovdl::v2script::ast::Node* node);
+ lauf_asm_function* create_condition_function(scope_type type, const ovdl::v2script::ast::Node* node);
- void generate_effect_from(scope_type type, ovdl::v2script::ast::Node* node);
- void generate_condition_from(scope_type type, ovdl::v2script::ast::Node* node);
+ void generate_effect_from(scope_type type, const ovdl::v2script::ast::Node* node);
+ void generate_condition_from(scope_type type, const ovdl::v2script::ast::Node* node);
bool inst_store_ov_asm_key_null(lauf_asm_local* local, std::size_t index);
bool inst_store_ov_asm_key(lauf_asm_local* local, std::size_t index, ovdl::symbol<char> key);
bool inst_store_ov_asm_value_from_vstack(lauf_asm_local* local, std::size_t index, std::uint8_t type);
bool inst_store_ov_asm_type(lauf_asm_local* local, std::size_t index, std::uint8_t type);
- bool push_instruction_for_keyword_scope(
- scope_execution_type execution_type, scope_type type, ovdl::symbol<char> scope_symbol
- );
-
- Asm::scope_variant get_scope_for( //
- scope_execution_type execution_type, scope_type type, ovdl::symbol<char> scope_symbol
- ) const;
+ bool push_instruction_for_scope(scope_execution_type execution_type, scope_type type, ovdl::symbol<char> scope_symbol);
// Bytecode instructions //
void inst_push_scope_this();
@@ -193,8 +193,8 @@ namespace OpenVic::Vm {
};
private:
- std::vector<OpenVic::Asm::scope_variant> _scope_references;
- InstanceManager* _instance_manager;
+ std::vector<OpenVic::Asm::scope_store_variant> _scope_definitions;
+ GameManager* _game_manager;
Module _module;
AsmBuilder _builder;
ovdl::v2script::Parser const& _parser;
diff --git a/src/openvic-simulation/vm/VirtualMachine.hpp b/src/openvic-simulation/vm/VirtualMachine.hpp
index b92fb6c..482c649 100644
--- a/src/openvic-simulation/vm/VirtualMachine.hpp
+++ b/src/openvic-simulation/vm/VirtualMachine.hpp
@@ -2,7 +2,7 @@
#include <vector>
-#include "InstanceManager.hpp"
+#include "GameManager.hpp"
#include "RuntimeProcess.hpp"
#include "Utility.hpp"
#include "vm/Builtin.hpp"
@@ -33,15 +33,15 @@ namespace OpenVic::Vm {
using VirtualMachine::operator=;
OpenVicVirtualMachine(
- InstanceManager* instance_manager, std::vector<Asm::scope_variant>&& scope_references,
+ GameManager* game_manager, std::vector<Asm::scope_store_variant>&& scope_references,
lauf_vm_options options = lauf_default_vm_options
)
: VirtualMachine([&] {
options.user_data = &user_data;
return options;
}()) {
- user_data.scope_references = std::move(scope_references);
- user_data.instance_manager = instance_manager;
+ user_data.scope_dict_refs = std::move(scope_references);
+ user_data.game_manager = game_manager;
}
private: