Compare commits
7 Commits
2cbd8d1f31
...
685e09412b
Author | SHA1 | Date |
---|---|---|
kayomn | 685e09412b | |
kayomn | c36bf5b76c | |
kayomn | f20e220e35 | |
kayomn | 1e87aa7fcf | |
kayomn | f2694b61cb | |
kayomn | d6ba17c4ab | |
kayomn | a67d7239a4 |
|
@ -2,6 +2,7 @@ module;
|
|||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
export module coral;
|
||||
|
||||
|
@ -282,7 +283,7 @@ export namespace coral {
|
|||
|
||||
optional(optional const & that) : buffer{0} {
|
||||
if (that.has_value()) {
|
||||
(*reinterpret_cast<element *>(this->buffer)) = that.value();
|
||||
(*reinterpret_cast<element *>(this->buffer)) = *that;
|
||||
this->buffer[sizeof(element)] = 1;
|
||||
} else {
|
||||
this->buffer[sizeof(element)] = 0;
|
||||
|
@ -296,6 +297,17 @@ export namespace coral {
|
|||
return this->buffer[sizeof(element)] == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to call `apply` on the contained value, returning a new [optional] of whatever type `apply` returns.
|
||||
*
|
||||
* If the optional is empty, an empty optional will always be returned.
|
||||
*/
|
||||
template<typename functor> std::invoke_result_t<functor, element> map(functor const & apply) const {
|
||||
if (this->has_value()) return apply(**this);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contained value or `fallback` if the optional is empty.
|
||||
*/
|
||||
|
@ -303,25 +315,15 @@ export namespace coral {
|
|||
return this->has_value() ? *reinterpret_cast<element const *>(this->buffer) : fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the contained value.
|
||||
*
|
||||
* *Note*: attempting to access the value of an empty optional will trigger safety-checked
|
||||
* behavior.
|
||||
*/
|
||||
element & value() {
|
||||
element & operator *() {
|
||||
if (!this->has_value()) unreachable();
|
||||
|
||||
return *reinterpret_cast<element *>(this->buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contained value.
|
||||
*
|
||||
* *Note*: attempting to access the value of an empty optional will trigger safety-checked
|
||||
* behavior.
|
||||
*/
|
||||
element const & value() const {
|
||||
element const & operator *() const {
|
||||
if (!this->has_value()) unreachable();
|
||||
|
||||
return *reinterpret_cast<element const *>(this->buffer);
|
||||
}
|
||||
|
||||
|
@ -461,6 +463,13 @@ export namespace coral {
|
|||
|
||||
// Input/output operations.
|
||||
export namespace coral {
|
||||
/**
|
||||
* Returns `value` reinterpreted as a sequence of bytes.
|
||||
*/
|
||||
slice<u8 const> as_bytes(auto const * value) {
|
||||
return {reinterpret_cast<u8 const *>(value), sizeof(value)};
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares `a` and `b`, returning the difference between them or `0` if they are identical.
|
||||
*/
|
||||
|
@ -586,7 +595,7 @@ export namespace coral {
|
|||
for (usize i = 0; i < half_buffer_count; i += 1)
|
||||
swap(buffer[i], buffer[buffer_count - i - 1]);
|
||||
|
||||
return output.write(slice{buffer, buffer_count});
|
||||
return output.write({buffer, buffer_count});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<coral::u64 *>(this->data)) =
|
||||
(*reinterpret_cast<coral::u64 *>(&integer));
|
||||
|
||||
coral::vector2 vector2;
|
||||
this->type = value_type::integer;
|
||||
}
|
||||
|
||||
coral::vector3 vector3;
|
||||
value(coral::f64 scalar) {
|
||||
(*reinterpret_cast<coral::u64 *>(this->data)) =
|
||||
(*reinterpret_cast<coral::u64 *>(&scalar));
|
||||
|
||||
void * object;
|
||||
} as;
|
||||
this->type = value_type::scalar;
|
||||
}
|
||||
|
||||
coral::optional<coral::u16> 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<coral::u64 *>(this->data)) =
|
||||
(*reinterpret_cast<coral::u64 *>(&vector2));
|
||||
|
||||
return static_cast<coral::u16>(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<coral::i64> as_integer() const {
|
||||
if (this->type == value_type::integer)
|
||||
return (*reinterpret_cast<coral::i64 const *>(&this->data));
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
value nil = {
|
||||
.type = value_type::nil,
|
||||
.as = {.object = nullptr},
|
||||
private:
|
||||
coral::u8 data[12]{0};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -57,7 +57,7 @@ struct bytecode {
|
|||
}
|
||||
|
||||
kym::value execute(kym::vm & vm, coral::slice<kym::value const> 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<value const> const & arguments) {
|
||||
return nil;
|
||||
return {};
|
||||
}
|
||||
|
||||
coral::expected<coral::usize, coral::io_error> default_stringify(vm & owning_vm, void * userdata, coral::writer & output) {
|
||||
|
@ -103,7 +103,7 @@ export namespace kym {
|
|||
}
|
||||
|
||||
value get_field(coral::slice<char const> const & field_name) {
|
||||
return nil;
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -139,14 +139,14 @@ export namespace kym {
|
|||
value compile(coral::slice<char const> 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<char const> 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<void(bound_object &)> const & then) {
|
||||
return nil;
|
||||
return {};
|
||||
}
|
||||
|
||||
void with_object(value object_value, coral::callable<void(bound_object &)> const & then) {
|
||||
|
|
|
@ -82,9 +82,8 @@ export namespace oar {
|
|||
|
||||
header const * const archive_header{reinterpret_cast<header const *>(archive_header_buffer)};
|
||||
|
||||
if (!coral::equals(coral::slice{archive_header->signature_magic,
|
||||
signature_identifier_length}, coral::slice{signature_magic,
|
||||
signature_identifier_length})) return open_result::archive_invalid;
|
||||
if (!coral::equals({archive_header->signature_magic, signature_identifier_length},
|
||||
{signature_magic, signature_identifier_length})) return open_result::archive_invalid;
|
||||
|
||||
if (archive_header->signature_magic[signature_identifier_length] !=
|
||||
signature_magic[signature_identifier_length]) return open_result::archive_unsupported;
|
||||
|
|
|
@ -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<coral::i16> {
|
||||
if ((value >= 0) && (value <= coral::u16_max))
|
||||
return static_cast<coral::u16>(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");
|
||||
|
|
Loading…
Reference in New Issue