.{string, fmt, memory} := @use("stn") LogMsg := packed struct {level: LogLevel, string: ^u8, strlen: uint} LogLevel := enum { Error, Warn, Info, Debug, Trace, } $log := fn(level: LogLevel, message: []u8): void { return @eca(3, 1, LogMsg.(level, message.ptr, message.len), @sizeof(LogMsg)) } $error := fn(message: []u8): void return log(LogLevel.Error, message) $warn := fn(message: []u8): void return log(LogLevel.Warn, message) $info := fn(message: []u8): void return log(LogLevel.Info, message) $debug := fn(message: []u8): void return log(LogLevel.Debug, message) $trace := fn(message: []u8): void return log(LogLevel.Trace, message) print_buffer := memory.dangling(u8) print := fn(v: @Any(), opts: fmt.FormatOptions): void { if print_buffer == memory.dangling(u8) { print_buffer = memory.request_page(1) } len := @inline(fmt.format, v, print_buffer[0..memory.PAGE_SIZE], opts) @eca(3, 1, LogMsg.(opts.log, print_buffer, len), @sizeof(LogMsg)) memory.set(u8, &0, print_buffer, len) } printf := fn(str: []u8, v: @Any(), opts: fmt.FormatOptions): void { if print_buffer == memory.dangling(u8) { print_buffer = memory.request_page(1) } len := @inline(fmt.format_with_str, v, str, print_buffer[0..memory.PAGE_SIZE], opts) @eca(3, 1, LogMsg.(opts.log, print_buffer, len), @sizeof(LogMsg)) print(len, .{}) memory.set(u8, &0, print_buffer, len) }