feat: restore sentinel-slice file path interfaces
This commit is contained in:
@@ -29,7 +29,7 @@ main proc() int {
|
|||||||
|
|
||||||
this prints `42`. `main` must be a top-level function with no parameters; nonvoid results are printed, not used as process exit statuses. the current macOS bootstrap obtains arguments from the native startup environment.
|
this prints `42`. `main` must be a top-level function with no parameters; nonvoid results are printed, not used as process exit statuses. the current macOS bootstrap obtains arguments from the native startup environment.
|
||||||
|
|
||||||
source loading uses the supplied `io.Io` for opening, reading, and closing files. `io.open` accepts a borrowed zero-terminated pointer, including paths returned by `process.argument`. `io.read_all(allocator, reader, maximum)` reads to EOF into a caller-owned `ArrayList(u8)`; release it with `arraylist.deinit`. it frees partial storage on error and consumes one extra byte to distinguish an exact-size input from a limit violation. the driver maps `limit_exceeded` to `source_too_large` at its `u32` source-size limit.
|
source loading uses the supplied `io.Io` for opening, reading, and closing files. `io.open` accepts a borrowed zero-terminated slice (`[;0]u8`), including arguments returned by `process.argument` without copying their storage. the bootstrap supports checked sentinel-slice construction with `pointer[..length;0]`. `io.read_all(allocator, reader, maximum)` reads to EOF into a caller-owned `ArrayList(u8)`; release it with `arraylist.deinit`. it frees partial storage on error and consumes one extra byte to distinguish an exact-size input from a limit violation. the driver maps `limit_exceeded` to `source_too_large` at its `u32` source-size limit.
|
||||||
|
|
||||||
the parser supports arithmetic expressions with nested parenthesized groups, such as `a + (b - c) * 2 / 3`. groups control precedence without adding AST nodes; inner expression spans exclude the grouping parentheses. parsing accepts integer division syntax, but type checking requires float operands for `/`.
|
the parser supports arithmetic expressions with nested parenthesized groups, such as `a + (b - c) * 2 / 3`. groups control precedence without adding AST nodes; inner expression spans exclude the grouping parentheses. parsing accepts integer division syntax, but type checking requires float operands for `/`.
|
||||||
|
|
||||||
|
|||||||
+5
-12
@@ -47,7 +47,7 @@ main proc(init process.Init) i32 {
|
|||||||
return command(mem.c_allocator, init.io) catch |err| {
|
return command(mem.c_allocator, init.io) catch |err| {
|
||||||
if (process.argument(2)) |path| {
|
if (process.argument(2)) |path| {
|
||||||
io.print("{s}: infrastructure error: {s}\n", io.stderr(init.io), {
|
io.print("{s}: infrastructure error: {s}\n", io.stderr(init.io), {
|
||||||
argument_text(path), infrastructure_message(err),
|
path, infrastructure_message(err),
|
||||||
}) catch |_| {}
|
}) catch |_| {}
|
||||||
} else {
|
} else {
|
||||||
io.print("honey: infrastructure error: {s}\n", io.stderr(init.io), {
|
io.print("honey: infrastructure error: {s}\n", io.stderr(init.io), {
|
||||||
@@ -82,7 +82,7 @@ command proc(allocator mem.Allocator, runtime io.Io) i32 ! DriverError {
|
|||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
if (process.argument(1)) |operation| {
|
if (process.argument(1)) |operation| {
|
||||||
if (!mem.eql(argument_text(operation), "run")) {
|
if (!mem.eql(operation, "run")) {
|
||||||
try io.print("usage: honey run <file>\n", io.stderr(runtime), {})
|
try io.print("usage: honey run <file>\n", io.stderr(runtime), {})
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
@@ -94,14 +94,7 @@ command proc(allocator mem.Allocator, runtime io.Io) i32 ! DriverError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@hide:file
|
@hide:file
|
||||||
argument_text proc(pointer [*;0]u8) []u8 {
|
read_source proc(allocator mem.Allocator, runtime io.Io, path [;0]u8) arraylist.ArrayList(u8) ! DriverError {
|
||||||
length := usize(0)
|
|
||||||
while (pointer[length] != 0) length += 1
|
|
||||||
return pointer[..length]
|
|
||||||
}
|
|
||||||
|
|
||||||
@hide:file
|
|
||||||
read_source proc(allocator mem.Allocator, runtime io.Io, path [*;0]u8) arraylist.ArrayList(u8) ! DriverError {
|
|
||||||
file :: try io.open(runtime, path, .read_only)
|
file :: try io.open(runtime, path, .read_only)
|
||||||
closing := false
|
closing := false
|
||||||
defer {
|
defer {
|
||||||
@@ -136,7 +129,7 @@ compile proc(allocator mem.Allocator, source []u8, diagnostic_store @mut diagnos
|
|||||||
}
|
}
|
||||||
|
|
||||||
@hide:file
|
@hide:file
|
||||||
run_file proc(allocator mem.Allocator, runtime io.Io, path [*;0]u8) i32 ! DriverError {
|
run_file proc(allocator mem.Allocator, runtime io.Io, path [;0]u8) i32 ! DriverError {
|
||||||
source := try read_source(allocator, runtime, path)
|
source := try read_source(allocator, runtime, path)
|
||||||
defer arraylist.deinit(&source)
|
defer arraylist.deinit(&source)
|
||||||
diagnostic_store := diagnostics.init(allocator)
|
diagnostic_store := diagnostics.init(allocator)
|
||||||
@@ -145,7 +138,7 @@ run_file proc(allocator mem.Allocator, runtime io.Io, path [*;0]u8) i32 ! Driver
|
|||||||
defer ir.deinit(&module)
|
defer ir.deinit(&module)
|
||||||
outcome :: try interpreter.run(allocator, &module, &diagnostic_store)
|
outcome :: try interpreter.run(allocator, &module, &diagnostic_store)
|
||||||
if (outcome.trap == null) try print_result(io.stdout(runtime), outcome.value)
|
if (outcome.trap == null) try print_result(io.stdout(runtime), outcome.value)
|
||||||
try report_diagnostics(allocator, io.stderr(runtime), argument_text(path), source.items, &diagnostic_store, outcome.trap)
|
try report_diagnostics(allocator, io.stderr(runtime), path, source.items, &diagnostic_store, outcome.trap)
|
||||||
if (outcome.trap != null or diagnostics.count(&diagnostic_store) != 0) return 1
|
if (outcome.trap != null or diagnostics.count(&diagnostic_store) != 0) return 1
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -20,7 +20,7 @@ CloseError :: enum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#! open a caller-owned handle from a borrowed zero-terminated path; release it with close.
|
#! open a caller-owned handle from a borrowed zero-terminated path; release it with close.
|
||||||
open proc(io Io, path [*;0]u8, mode FileMode) File ! OpenError {
|
open proc(io Io, path [;0]u8, mode FileMode) File ! OpenError {
|
||||||
handle Handle :: try io.vtable.open(io.context, path, mode)
|
handle Handle :: try io.vtable.open(io.context, path, mode)
|
||||||
return File{ io = io, handle = handle }
|
return File{ io = io, handle = handle }
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ system_write proc(_ ?@mut anyopaque, handle Handle, bytes []u8) usize ! WriteErr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@hide:file
|
@hide:file
|
||||||
system_open proc(_ ?@mut anyopaque, path [*;0]u8, mode FileMode) Handle ! OpenError {
|
system_open proc(_ ?@mut anyopaque, path [;0]u8, mode FileMode) Handle ! OpenError {
|
||||||
flags := c.O_RDONLY
|
flags := c.O_RDONLY
|
||||||
match mode {
|
match mode {
|
||||||
.read_only: flags = c.O_RDONLY
|
.read_only: flags = c.O_RDONLY
|
||||||
@@ -91,7 +91,7 @@ system_open proc(_ ?@mut anyopaque, path [*;0]u8, mode FileMode) Handle ! OpenEr
|
|||||||
.read_write: flags = c.O_RDWR
|
.read_write: flags = c.O_RDWR
|
||||||
}
|
}
|
||||||
while true {
|
while true {
|
||||||
fd c_int :: c.open(ptrcast!(path), flags)
|
fd c_int :: c.open(ptrcast!(path.ptr), flags)
|
||||||
if (fd >= 0) return Handle{ file_desc = fd }
|
if (fd >= 0) return Handle{ file_desc = fd }
|
||||||
if (c.__error()?^ != c.EINTR) return .open_failed
|
if (c.__error()?^ != c.EINTR) return .open_failed
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ Io :: struct {
|
|||||||
IoVTable :: struct {
|
IoVTable :: struct {
|
||||||
read @proc(context ?@mut anyopaque, handle Handle, buffer []mut u8) usize ! ReadError
|
read @proc(context ?@mut anyopaque, handle Handle, buffer []mut u8) usize ! ReadError
|
||||||
write @proc(context ?@mut anyopaque, handle Handle, bytes []u8) usize ! WriteError
|
write @proc(context ?@mut anyopaque, handle Handle, bytes []u8) usize ! WriteError
|
||||||
open @proc(context ?@mut anyopaque, path [*;0]u8, mode FileMode) Handle ! OpenError
|
open @proc(context ?@mut anyopaque, path [;0]u8, mode FileMode) Handle ! OpenError
|
||||||
close @proc(context ?@mut anyopaque, handle Handle) void ! CloseError
|
close @proc(context ?@mut anyopaque, handle Handle) void ! CloseError
|
||||||
stdin @proc(context ?@mut anyopaque) Handle
|
stdin @proc(context ?@mut anyopaque) Handle
|
||||||
stdout @proc(context ?@mut anyopaque) Handle
|
stdout @proc(context ?@mut anyopaque) Handle
|
||||||
|
|||||||
@@ -9,8 +9,11 @@ argument_count proc() usize {
|
|||||||
return usize(_NSGetArgc()^)
|
return usize(_NSGetArgc()^)
|
||||||
}
|
}
|
||||||
|
|
||||||
#! returns a borrowed, zero-terminated argument; storage lasts for the process lifetime.
|
#! returns a borrowed, zero-terminated slice; storage lasts for the process lifetime.
|
||||||
argument proc(index usize) ?[*;0]u8 {
|
argument proc(index usize) ?[;0]u8 {
|
||||||
if (index >= argument_count()) return null
|
if (index >= argument_count()) return null
|
||||||
return _NSGetArgv()^[index]
|
pointer :: _NSGetArgv()^[index]
|
||||||
|
length := usize(0)
|
||||||
|
while (pointer[length] != 0) length += 1
|
||||||
|
return pointer[..length;0]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user