diff --git a/source/kym.cpp b/source/kym.cpp index 7d43d11..ed4e1d0 100644 --- a/source/kym.cpp +++ b/source/kym.cpp @@ -15,35 +15,50 @@ export namespace kym { }; struct value { - value_type type; + value_type type{value_type::nil}; - union { - bool boolean; + value() = default; - coral::i64 integer; + value(bool boolean) { + this->data[1] = 0xff * boolean; + this->type = value_type::boolean; + } - coral::f64 scalar; + value(coral::i64 integer) { + (*reinterpret_cast(this->data)) = + (*reinterpret_cast(&integer)); - coral::vector2 vector2; + this->type = value_type::integer; + } - coral::vector3 vector3; + value(coral::f64 scalar) { + (*reinterpret_cast(this->data)) = + (*reinterpret_cast(&scalar)); - void * object; - } as; + this->type = value_type::scalar; + } - coral::optional as_u16() const { - if ((this->type == value_type::integer) && - (this->as.integer >= 0) && (this->as.integer <= coral::u16_max)) { + value(coral::vector2 vector2) { + (*reinterpret_cast(this->data)) = + (*reinterpret_cast(&vector2)); - return static_cast(this->as.integer); - } + this->type = value_type::vector2; + } + + value(coral::vector3 const & vector3) { + coral::copy(this->data, coral::as_bytes(&vector3)); + + this->type = value_type::vector3; + } + + coral::optional as_integer() const { + if (this->type == value_type::integer) + return (*reinterpret_cast(&this->data)); return {}; } - }; - value nil = { - .type = value_type::nil, - .as = {.object = nullptr}, + private: + coral::u8 data[12]{0}; }; }; diff --git a/source/kym/environment.cpp b/source/kym/environment.cpp index f668ae8..b437ddc 100644 --- a/source/kym/environment.cpp +++ b/source/kym/environment.cpp @@ -57,7 +57,7 @@ struct bytecode { } kym::value execute(kym::vm & vm, coral::slice const & arguments) { - return kym::nil; + return {}; } private: @@ -66,7 +66,7 @@ struct bytecode { export namespace kym { value default_call(vm & owning_vm, void * userdata, coral::slice const & arguments) { - return nil; + return {}; } coral::expected default_stringify(vm & owning_vm, void * userdata, coral::writer & output) { @@ -103,7 +103,7 @@ export namespace kym { } value get_field(coral::slice const & field_name) { - return nil; + return {}; } private: @@ -139,14 +139,14 @@ export namespace kym { value compile(coral::slice const & source) { bytecode * source_bytecode = new (*this->allocator) bytecode{allocator}; - if (source_bytecode == nullptr) return nil; + if (source_bytecode == nullptr) return {}; if (!source_bytecode->compile(tokenizer{source}, [&](coral::slice error_message) { this->log(error_message); })) { this->allocator->deallocate(source_bytecode); - return nil; + return {}; } return this->new_object([this, source_bytecode](bound_object & object) { @@ -165,7 +165,7 @@ export namespace kym { } value new_object(coral::callable const & then) { - return nil; + return {}; } void with_object(value object_value, coral::callable const & then) { diff --git a/source/runtime.cpp b/source/runtime.cpp index 9aaf4da..05a93ed 100644 --- a/source/runtime.cpp +++ b/source/runtime.cpp @@ -38,13 +38,22 @@ extern "C" int main(int argc, char const * const * argv) { } vm.with_object(vm.compile(coral::slice{script_source.begin(), script_source.end()}.as_chars()), [&](kym::bound_object & script) { - vm.with_object(script.call({}), [&](kym::bound_object & config) { - coral::u16 const width{config.get_field("width").as_u16().value_or(0)}; + vm.with_object(script.call({}), [&](kym::bound_object config) { + constexpr auto as_u16 = [](coral::i64 value) -> coral::optional { + if ((value >= 0) && (value <= coral::u16_max)) + return static_cast(value); + + return {}; + }; + + coral::u16 const width{config.get_field("width"). + as_integer().map(as_u16).value_or(0)}; if (width == 0) return system.log(app::log_level::error, "failed to decode `width` property of config"); - coral::u16 const height{config.get_field("height").as_u16().value_or(0)}; + coral::u16 const height{config.get_field("height"). + as_integer().map(as_u16).value_or(0)}; if (height == 0) return system.log(app::log_level::error, "failed to decode `height` property of config");