Fix loading of script files in Ona
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
1dc0c7f225
commit
fc1848d2c1
|
@ -49,6 +49,11 @@ pub fn Functor(comptime Output: type, comptime Input: type) type {
|
||||||
|
|
||||||
pub const Reader = Functor(?usize, []u8);
|
pub const Reader = Functor(?usize, []u8);
|
||||||
|
|
||||||
|
pub const StreamError = error {
|
||||||
|
ReadFailure,
|
||||||
|
WriteFailure,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn Tag(comptime Element: type) type {
|
pub fn Tag(comptime Element: type) type {
|
||||||
return switch (@typeInfo(Element)) {
|
return switch (@typeInfo(Element)) {
|
||||||
.Enum => |info| info.tag_type,
|
.Enum => |info| info.tag_type,
|
||||||
|
@ -57,18 +62,18 @@ pub fn Tag(comptime Element: type) type {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const WritableMemory = struct {
|
pub const FixedBuffer = struct {
|
||||||
slice: []u8,
|
slice: []u8,
|
||||||
|
|
||||||
pub fn as_writer(self: *WritableMemory) Writer {
|
pub fn as_writer(self: *FixedBuffer) Writer {
|
||||||
return Writer.bind(self, struct {
|
return Writer.bind(self, struct {
|
||||||
fn write(writable_memory: *WritableMemory, data: []const u8) ?usize {
|
fn write(writable_memory: *FixedBuffer, data: []const u8) ?usize {
|
||||||
return writable_memory.write(data);
|
return writable_memory.write(data);
|
||||||
}
|
}
|
||||||
}.write);
|
}.write);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put(self: *WritableMemory, byte: u8) bool {
|
pub fn put(self: *FixedBuffer, byte: u8) bool {
|
||||||
if (self.slice.len == 0) {
|
if (self.slice.len == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +84,7 @@ pub const WritableMemory = struct {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(self: *WritableMemory, bytes: []const u8) usize {
|
pub fn write(self: *FixedBuffer, bytes: []const u8) usize {
|
||||||
const writable = math.min(self.slice.len, bytes.len);
|
const writable = math.min(self.slice.len, bytes.len);
|
||||||
|
|
||||||
copy(self.slice, bytes);
|
copy(self.slice, bytes);
|
||||||
|
@ -90,6 +95,47 @@ pub const WritableMemory = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const GrowingBuffer = struct {
|
||||||
|
allocator: Allocator,
|
||||||
|
appender: Appender,
|
||||||
|
|
||||||
|
const AppendOptions = struct {
|
||||||
|
allocator: Allocator,
|
||||||
|
bytes: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Appender = Functor(AllocationError!void, AppendOptions);
|
||||||
|
|
||||||
|
pub fn as_writer(self: *GrowingBuffer) Writer {
|
||||||
|
return Writer.bind(GrowingBuffer, self, struct {
|
||||||
|
fn write(growing_buffer: *GrowingBuffer, bytes: []const u8) ?usize {
|
||||||
|
growing_buffer.write(bytes) catch return null;
|
||||||
|
|
||||||
|
return bytes.len;
|
||||||
|
}
|
||||||
|
}.write);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(comptime State: type, allocator: Allocator, state: *State, comptime appender: fn (capture: *State, allocator: Allocator, bytes: []const u8) AllocationError!void) GrowingBuffer {
|
||||||
|
return .{
|
||||||
|
.appender = Appender.bind(State, state, struct {
|
||||||
|
fn append(self: *State, options: AppendOptions) AllocationError!void {
|
||||||
|
return appender(self, options.allocator, options.bytes);
|
||||||
|
}
|
||||||
|
}.append),
|
||||||
|
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(self: GrowingBuffer, bytes: []const u8) AllocationError!void {
|
||||||
|
return self.appender.invoke(.{
|
||||||
|
.allocator = self.allocator,
|
||||||
|
.bytes = bytes,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const Writer = Functor(?usize, []const u8);
|
pub const Writer = Functor(?usize, []const u8);
|
||||||
|
|
||||||
pub fn allocate_many(comptime Type: type, amount: usize, allocator: Allocator) AllocationError![]Type {
|
pub fn allocate_many(comptime Type: type, amount: usize, allocator: Allocator) AllocationError![]Type {
|
||||||
|
@ -254,13 +300,13 @@ pub fn sentinel_index(comptime element: type, comptime sentinel: element, sequen
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stream(output: Writer, input: Reader, buffer: []u8) ?u64 {
|
pub fn stream(output: Writer, input: Reader, buffer: []u8) StreamError!u64 {
|
||||||
var total_written: u64 = 0;
|
var total_written: u64 = 0;
|
||||||
var read = input.invoke(buffer) orelse return null;
|
var read = input.invoke(buffer) orelse return error.ReadFailure;
|
||||||
|
|
||||||
while (read != 0) {
|
while (read != 0) {
|
||||||
total_written += output.invoke(buffer[0..read]) orelse return null;
|
total_written += output.invoke(buffer[0..read]) orelse return error.WriteFailure;
|
||||||
read = input.invoke(buffer) orelse return null;
|
read = input.invoke(buffer) orelse return error.ReadFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
return total_written;
|
return total_written;
|
||||||
|
|
|
@ -17,6 +17,19 @@ pub fn Stack(comptime Value: type) type {
|
||||||
///
|
///
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns a [io.GrowableBuffer] bound to `self` and `allocator`.
|
||||||
|
///
|
||||||
|
/// The returned buffer may be used to write to the stack without needing to explicitly pass an allocator
|
||||||
|
/// context, as well decay further into a generic [io.Writer] type.
|
||||||
|
///
|
||||||
|
/// *Note* `allocator` must reference the same allocation strategy as the one originally used to initialize
|
||||||
|
/// `self`.
|
||||||
|
///
|
||||||
|
pub fn as_buffer(self: *Self, allocator: io.Allocator) io.GrowingBuffer {
|
||||||
|
return io.GrowingBuffer.bind(Self, allocator, self, push_all);
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Clears all elements from `self` while preserving the current internal buffer.
|
/// Clears all elements from `self` while preserving the current internal buffer.
|
||||||
///
|
///
|
||||||
|
@ -192,73 +205,3 @@ pub fn Stack(comptime Value: type) type {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// Generic, byte-writable interface for all list types supported by the module.
|
|
||||||
///
|
|
||||||
/// As the type is only a thin wrapper around other resources, it does not manage any memory nor is it permitted to
|
|
||||||
/// outlive the resources it references.
|
|
||||||
///
|
|
||||||
pub const Writable = struct {
|
|
||||||
allocator: io.Allocator,
|
|
||||||
|
|
||||||
list: union (enum) {
|
|
||||||
stack: *ByteStack,
|
|
||||||
},
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Stack of bytes.
|
|
||||||
///
|
|
||||||
const ByteStack = Stack(u8);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Binds and returns `self` as a [io.Writer].
|
|
||||||
///
|
|
||||||
pub fn as_writer(self: *Writable) io.Writer {
|
|
||||||
return io.Writer.bind(Writable, self, struct {
|
|
||||||
fn write(writable: *Writable, buffer: []const u8) ?usize {
|
|
||||||
writable.write(buffer) catch |allocation_error| switch (allocation_error) {
|
|
||||||
error.OutOfMemory => return null,
|
|
||||||
};
|
|
||||||
|
|
||||||
return buffer.len;
|
|
||||||
}
|
|
||||||
}.write);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns a new [Writable] from wrapping `stack` and `allocator`.
|
|
||||||
///
|
|
||||||
/// *Note* `allocator` must reference the same allocation strategy as the one originally used to initialize `stack`.
|
|
||||||
///
|
|
||||||
pub fn from_stack(allocator: io.Allocator, stack: *ByteStack) Writable {
|
|
||||||
return .{
|
|
||||||
.allocator = allocator,
|
|
||||||
.list = .{.stack = stack},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Attempts to write the singular `byte` to the list referenced by `self`.
|
|
||||||
///
|
|
||||||
/// The function returns [io.AllocationError] if `allocator` could not commit the memory required by the internal
|
|
||||||
/// list.
|
|
||||||
///
|
|
||||||
pub fn put(self: *Writable, byte: u8) io.AllocationError!void {
|
|
||||||
try switch (self.list) {
|
|
||||||
.stack => |stack| stack.push_one(self.allocator, byte),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Attempst to write all of `bytes` to the list referenced by `self`.
|
|
||||||
///
|
|
||||||
/// The function returns [io.AllocationError] if `allocator` could not commit the memory required by the internal
|
|
||||||
/// list.
|
|
||||||
///
|
|
||||||
pub fn write(self: *Writable, bytes: []const u8) io.AllocationError!void {
|
|
||||||
try switch (self.list) {
|
|
||||||
.stack => |stack| stack.push_all(self.allocator, bytes),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub const Path = extern struct {
|
||||||
var path = Path{};
|
var path = Path{};
|
||||||
|
|
||||||
{
|
{
|
||||||
var writable_slice = coral.io.WritableMemory{.slice = &path.data};
|
var writable_slice = coral.io.FixedBuffer{.slice = &path.data};
|
||||||
|
|
||||||
for (components) |component| {
|
for (components) |component| {
|
||||||
if (writable_slice.write(component) != component.len) {
|
if (writable_slice.write(component) != component.len) {
|
||||||
|
@ -64,7 +64,7 @@ pub const Path = extern struct {
|
||||||
var path = Path{};
|
var path = Path{};
|
||||||
|
|
||||||
{
|
{
|
||||||
var writable = coral.io.WritableMemory{.slice = &path.data};
|
var writable = coral.io.FixedBuffer{.slice = &path.data};
|
||||||
var written = @as(usize, 0);
|
var written = @as(usize, 0);
|
||||||
|
|
||||||
for (&self.data) |byte| {
|
for (&self.data) |byte| {
|
||||||
|
@ -111,6 +111,14 @@ pub const ReadError = error {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Readable = opaque {
|
pub const Readable = opaque {
|
||||||
|
pub fn as_reader(self: *Readable) coral.io.Reader {
|
||||||
|
return coral.io.Reader.bind(Readable, self, struct {
|
||||||
|
fn read(readable: *Readable, buffer: []u8) ?usize {
|
||||||
|
return readable.read(buffer) catch null;
|
||||||
|
}
|
||||||
|
}.read);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn close(self: *Readable) void {
|
pub fn close(self: *Readable) void {
|
||||||
if (ext.SDL_RWclose(rw_ops_cast(self)) != 0) {
|
if (ext.SDL_RWclose(rw_ops_cast(self)) != 0) {
|
||||||
@panic("Failed to close file");
|
@panic("Failed to close file");
|
||||||
|
@ -121,8 +129,9 @@ pub const Readable = opaque {
|
||||||
ext.SDL_ClearError();
|
ext.SDL_ClearError();
|
||||||
|
|
||||||
const bytes_read = ext.SDL_RWread(rw_ops_cast(self), buffer.ptr, @sizeOf(u8), buffer.len);
|
const bytes_read = ext.SDL_RWread(rw_ops_cast(self), buffer.ptr, @sizeOf(u8), buffer.len);
|
||||||
|
const error_message = ext.SDL_GetError();
|
||||||
|
|
||||||
if ((bytes_read == 0) and (ext.SDL_GetError() != null)) {
|
if (bytes_read == 0 and error_message != null and error_message.* != 0) {
|
||||||
return error.FileUnavailable;
|
return error.FileUnavailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ const tokens = @import("./tokens.zig");
|
||||||
|
|
||||||
env: *Environment,
|
env: *Environment,
|
||||||
message_name_len: usize,
|
message_name_len: usize,
|
||||||
message_buffer: Buffer,
|
message_data: Buffer,
|
||||||
bytecode_buffer: Buffer,
|
bytecode_buffer: Buffer,
|
||||||
|
|
||||||
const Buffer = coral.list.Stack(u8);
|
const Buffer = coral.list.Stack(u8);
|
||||||
|
@ -45,8 +45,8 @@ const Opcode = enum (u8) {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
fn clear_error_details(self: *Self) void {
|
fn clear_error_details(self: *Self) void {
|
||||||
coral.debug.assert(self.message_buffer.values.len >= self.message_name_len);
|
coral.debug.assert(self.message_data.values.len >= self.message_name_len);
|
||||||
coral.debug.assert(self.message_buffer.drop(self.message_buffer.values.len - self.message_name_len));
|
coral.debug.assert(self.message_data.drop(self.message_data.values.len - self.message_name_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(self: *Self, data: []const u8) types.RuntimeError!void {
|
pub fn compile(self: *Self, data: []const u8) types.RuntimeError!void {
|
||||||
|
@ -75,10 +75,10 @@ pub fn compile(self: *Self, data: []const u8) types.RuntimeError!void {
|
||||||
.invalid => |invalid| {
|
.invalid => |invalid| {
|
||||||
self.clear_error_details();
|
self.clear_error_details();
|
||||||
|
|
||||||
try self.message_buffer.push_all(self.env.allocator, "@(");
|
try self.message_data.push_all(self.env.allocator, "@(");
|
||||||
|
|
||||||
var writable_message = coral.list.Writable.from_stack(self.env.allocator, &self.message_buffer);
|
var message_buffer = self.message_data.as_buffer(self.env.allocator);
|
||||||
const message_writer = writable_message.as_writer();
|
const message_writer = message_buffer.as_writer();
|
||||||
|
|
||||||
coral.utf8.print_int(@typeInfo(usize).Int, message_writer, tokenizer.lines_stepped) catch {
|
coral.utf8.print_int(@typeInfo(usize).Int, message_writer, tokenizer.lines_stepped) catch {
|
||||||
return error.OutOfMemory;
|
return error.OutOfMemory;
|
||||||
|
@ -175,7 +175,7 @@ pub fn compile_expression(self: *Self, expression: ast.Expression) types.Runtime
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
self.bytecode_buffer.deinit(self.env.allocator);
|
self.bytecode_buffer.deinit(self.env.allocator);
|
||||||
self.message_buffer.deinit(self.env.allocator);
|
self.message_data.deinit(self.env.allocator);
|
||||||
|
|
||||||
self.message_name_len = 0;
|
self.message_name_len = 0;
|
||||||
}
|
}
|
||||||
|
@ -197,9 +197,9 @@ pub fn emit_opcode(self: *Self, opcode: Opcode) coral.io.AllocationError!void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error_details(self: Self) []const u8 {
|
pub fn error_details(self: Self) []const u8 {
|
||||||
coral.debug.assert(self.message_buffer.values.len >= self.message_name_len);
|
coral.debug.assert(self.message_data.values.len >= self.message_name_len);
|
||||||
|
|
||||||
return self.message_buffer.values[self.message_name_len .. ];
|
return self.message_data.values[self.message_name_len .. ];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(env: *Environment, chunk_name: []const u8) coral.io.AllocationError!Self {
|
pub fn init(env: *Environment, chunk_name: []const u8) coral.io.AllocationError!Self {
|
||||||
|
@ -207,15 +207,15 @@ pub fn init(env: *Environment, chunk_name: []const u8) coral.io.AllocationError!
|
||||||
|
|
||||||
errdefer bytecode_buffer.deinit(env.allocator);
|
errdefer bytecode_buffer.deinit(env.allocator);
|
||||||
|
|
||||||
var message_buffer = try Buffer.init(env.allocator, chunk_name.len);
|
var message_data = try Buffer.init(env.allocator, chunk_name.len);
|
||||||
|
|
||||||
errdefer message_buffer.deinit(env.allocator);
|
errdefer message_data.deinit(env.allocator);
|
||||||
|
|
||||||
message_buffer.push_all(env.allocator, chunk_name) catch unreachable;
|
message_data.push_all(env.allocator, chunk_name) catch unreachable;
|
||||||
|
|
||||||
return Self{
|
return Self{
|
||||||
.env = env,
|
.env = env,
|
||||||
.message_buffer = message_buffer,
|
.message_data = message_data,
|
||||||
.bytecode_buffer = bytecode_buffer,
|
.bytecode_buffer = bytecode_buffer,
|
||||||
.message_name_len = chunk_name.len,
|
.message_name_len = chunk_name.len,
|
||||||
};
|
};
|
||||||
|
@ -230,7 +230,7 @@ pub fn intern(self: *Self, string: []const u8) coral.io.AllocationError!types.Ob
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self: Self) []const u8 {
|
pub fn name(self: Self) []const u8 {
|
||||||
coral.debug.assert(self.message_buffer.values.len >= self.message_name_len);
|
coral.debug.assert(self.message_data.values.len >= self.message_name_len);
|
||||||
|
|
||||||
return self.message_buffer.values[0 .. self.message_name_len];
|
return self.message_data.values[0 .. self.message_name_len];
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub const DataSource = struct {
|
||||||
data: []const u8,
|
data: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ExecuteFileError = file.System.OpenError || file.ReadError || types.CompileError;
|
pub const ExecuteFileError = file.System.OpenError || coral.io.StreamError || file.ReadError || types.RuntimeError;
|
||||||
|
|
||||||
pub const InitOptions = struct {
|
pub const InitOptions = struct {
|
||||||
values_max: u32,
|
values_max: u32,
|
||||||
|
@ -201,7 +201,7 @@ pub fn discard(self: *Self, val: types.Val) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_data(self: *Self, source: DataSource) ExecuteFileError!types.Val {
|
pub fn execute_data(self: *Self, source: DataSource) types.RuntimeError!types.Val {
|
||||||
const typeid = "<chunk>";
|
const typeid = "<chunk>";
|
||||||
|
|
||||||
const Behaviors = struct {
|
const Behaviors = struct {
|
||||||
|
@ -235,10 +235,20 @@ pub fn execute_file(self: *Self, fs: file.System, file_path: file.Path) ExecuteF
|
||||||
|
|
||||||
defer readable_file.close();
|
defer readable_file.close();
|
||||||
|
|
||||||
var file_source = try coral.list.Stack(u8).init(self.allocator, (try fs.query_info(file_path)).size);
|
const file_size = (try fs.query_info(file_path)).size;
|
||||||
|
var file_source = try coral.list.Stack(u8).init(self.allocator, file_size);
|
||||||
|
|
||||||
defer file_source.deinit(self.allocator);
|
defer file_source.deinit(self.allocator);
|
||||||
|
|
||||||
|
{
|
||||||
|
var file_buffer = file_source.as_buffer(self.allocator);
|
||||||
|
var stream_buffer = [_]u8{0} ** 4096;
|
||||||
|
|
||||||
|
if ((try coral.io.stream(file_buffer.as_writer(), readable_file.as_reader(), &stream_buffer)) != file_size) {
|
||||||
|
return error.ReadFailure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return try self.execute_data(.{
|
return try self.execute_data(.{
|
||||||
.name = try file_path.to_string(),
|
.name = try file_path.to_string(),
|
||||||
.data = file_source.values,
|
.data = file_source.values,
|
||||||
|
|
|
@ -4,12 +4,6 @@ pub const CheckError = error {
|
||||||
CheckFailed
|
CheckFailed
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CompileError = coral.io.AllocationError || RuntimeError || error {
|
|
||||||
UnexpectedEnd,
|
|
||||||
UnexpectedToken,
|
|
||||||
UndefinedLocal,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Float = f32;
|
pub const Float = f32;
|
||||||
|
|
||||||
pub const Integer = i32;
|
pub const Integer = i32;
|
||||||
|
|
Loading…
Reference in New Issue