ona/source/kym/environment.cpp

145 lines
3.0 KiB
C++
Raw Normal View History

2023-02-18 04:34:40 +01:00
export module kym.environment;
import core;
import core.sequence;
import kym;
export namespace kym {
struct vm;
}
enum class token_kind {
end,
};
struct token {
core::slice<char const> text;
token_kind kind;
};
using tokenizable = core::callable<token()>;
struct bytecode {
bytecode(core::allocator * allocator) : error_message_buffer{allocator} {
}
bool compile(tokenizable const & bytecode_tokenizable) {
for (;;) {
token const initial_token = bytecode_tokenizable();
switch (initial_token.kind) {
case token_kind::end: return true;
default: core::unreachable();
}
}
}
kym::value execute(kym::vm & vm, core::slice<kym::value> const & arguments) {
return kym::nil;
}
core::slice<char const> error_message() const {
return this->error_message_buffer.as_slice();
}
private:
core::stack<char> error_message_buffer;
};
export namespace kym {
struct bound_object {
core::callable<void()> cleanup;
core::callable<value(core::slice<value>)> call;
value get_field(core::slice<char const> const & field_name) {
return nil;
}
bool is_string() {
return false;
}
core::usize stringify(core::writable const & writable) {
return 0;
}
};
struct vm {
struct init_options {
core::u16 datastack_size;
core::u16 callstack_size;
};
vm(core::allocator * allocator, auto log) : allocator{allocator}, log{log}, data_stack{} {}
~vm() {
if (this->data_stack.pointer != nullptr)
this->allocator->deallocate(this->data_stack.pointer);
}
bool init(init_options const & options) {
core::u8 * const data_stack_buffer = this->allocator->reallocate(reinterpret_cast
<core::u8 *>(this->data_stack.pointer), options.datastack_size * sizeof(value));
if (data_stack_buffer == nullptr) return false;
this->data_stack = {
reinterpret_cast<value * >(data_stack_buffer), options.datastack_size};
return true;
}
value compile(core::slice<char const> const & source) {
bytecode * source_bytecode = new (*this->allocator) bytecode{allocator};
if (source_bytecode == nullptr) return nil;
core::usize cursor = 0;
if (source_bytecode->compile([]() {
return token{
};
})) {
this->log(source_bytecode->error_message());
this->allocator->deallocate(source_bytecode);
return nil;
}
return this->new_object([this, source_bytecode](bound_object & object) {
object.cleanup = [this, source_bytecode]() {
this->allocator->deallocate(source_bytecode);
};
object.call = [this, source_bytecode](core::slice<value> const & arguments) {
return source_bytecode->execute(*this, arguments);
};
this->allocator->deallocate(source_bytecode);
});
}
value new_object(core::callable<void(bound_object &)> const & then) {
return nil;
}
void with_object(value object_value, core::callable<void(bound_object &)> const & then) {
}
private:
core::slice<value> data_stack;
core::callable<void(core::slice<char const>)> log;
core::allocator * allocator;
};
}