diff --git a/src/arc.zig b/src/arc.zig index d6a95f252..02f824d6f 100644 --- a/src/arc.zig +++ b/src/arc.zig @@ -28,7 +28,7 @@ pub fn release(vm: *cy.VM, val: cy.Value) void { if (cy.TrackGlobalRC) { if (cy.Trace) { if (vm.refCounts == 0) { - rt.errFmt(vm, "Double free. {}", &.{cy.fmt.v(obj.getTypeId())}); + rt.printErrorFmt(vm, "Double free. {}\n", &.{cy.fmt.v(obj.getTypeId())}); cy.fatal(); } } diff --git a/src/bc_gen.zig b/src/bc_gen.zig index 6d34c0338..50b542026 100644 --- a/src/bc_gen.zig +++ b/src/bc_gen.zig @@ -412,7 +412,7 @@ fn genExpr(c: *Chunk, idx: usize, cstr: Cstr) anyerror!GenValue { .varSym => genVarSym(c, idx, cstr, nodeId), .blockExpr => genBlockExpr(c, idx, cstr, nodeId), else => { - rt.errZFmt(c.vm, "{}", .{code}); + rt.printErrorZFmt(c.vm, "{}\n", .{code}); return error.TODO; } }; diff --git a/src/builtins/builtins.zig b/src/builtins/builtins.zig index 10210a6ea..3d99ec5e7 100644 --- a/src/builtins/builtins.zig +++ b/src/builtins/builtins.zig @@ -516,6 +516,7 @@ pub fn dump(vm: *cy.VM, args: [*]const Value, _: u8) anyerror!Value { const res = try allocToCyon(vm, vm.alloc, args[0]); defer vm.alloc.free(res); rt.print(vm, res); + rt.print(vm, "\n"); return Value.Void; } @@ -976,9 +977,11 @@ pub fn print_c(ctx: cy.Context, arg: rt.Any) callconv(.C) rt.Error { return cy.builtins.prepThrowZError2(ctx, err, @errorReturnTrace()); }; rt.print(ctx, str); + rt.print(ctx, "\n"); } else { const str = arg.type.toPrintString(ctx, arg); rt.print(ctx, str.slice()); + rt.print(ctx, "\n"); ctx.release(str.buf); } return rt.Error.initNull(); diff --git a/src/bytecode.zig b/src/bytecode.zig index a7080a154..be6ab5b1f 100644 --- a/src/bytecode.zig +++ b/src/bytecode.zig @@ -779,6 +779,7 @@ pub fn dumpInst(vm: *cy.VM, pcOffset: u32, code: OpCode, pc: [*]const Inst, opts fmt.print(w, "{}| {}", &.{fmt.repeat(' ', @intCast(ExtraStartCol-len)), v(extra)}); } } + try w.writeByte('\n'); rt.print(vm, vm.getTempString()); } diff --git a/src/capi.zig b/src/capi.zig index c786fb4bf..d253b2cd3 100644 --- a/src/capi.zig +++ b/src/capi.zig @@ -38,8 +38,7 @@ pub const expandTypeTemplate = c.csExpandTypeTemplate; pub const setResolver = c.csSetResolver; pub const setModuleLoader = c.csSetModuleLoader; pub const setPrinter = c.csSetPrinter; -pub const setErrorFn = c.csSetErrorFn; -pub const setLogger = c.csSetLogger; +pub const setErrorPrinter = c.csSetErrorPrinter; pub const setUserData = c.csSetUserData; pub const getUserData = c.csGetUserData; pub const getGlobalRC = c.csGetGlobalRC; @@ -71,7 +70,7 @@ pub fn initValueSlice(slice: []const cy.Value) ValueSlice { pub const FuncFn = c.CsFuncFn; pub const PrintFn = c.CsPrintFn; -pub const ErrorFn = c.CsErrorFn; +pub const PrintErrorFn = c.CsPrintErrorFn; pub const LogFn = c.CsLogFn; pub const FuncInfo = c.CsFuncInfo; pub const FuncResult = c.CsFuncResult; diff --git a/src/cgen.zig b/src/cgen.zig index 43952f218..013456f5a 100644 --- a/src/cgen.zig +++ b/src/cgen.zig @@ -326,7 +326,7 @@ const Chunk = struct { return TypeName.init(name); } } else { - rt.errZFmt(c.sema.compiler.vm, "Unsupported sym type: {}", .{id}); + rt.printErrorZFmt(c.sema.compiler.vm, "Unsupported sym type: {}\n", .{id}); return error.TODO; } } @@ -638,7 +638,7 @@ pub fn gen(self: *cy.Compiler) !cy.compiler.AotCompileResult { defer self.alloc.free(res.stdout); if (res.term != .Exited or res.term.Exited != 0) { - rt.errMsg(self.vm, res.stderr); + rt.printError(self.vm, res.stderr); return error.CCError; } } @@ -917,7 +917,7 @@ fn genExpr(c: *Chunk, loc: usize, cstr: Cstr) anyerror!Value { // .typeSym => genTypeSym(c, idx, cstr, nodeId), // .varSym => genVarSym(c, idx, cstr, nodeId), else => { - rt.errZFmt(c.vm, "{}", .{code}); + rt.printErrorZFmt(c.vm, "{}\n", .{code}); return error.TODO; }, }; diff --git a/src/chunk.zig b/src/chunk.zig index 4b4bd7f25..fa858b0ef 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -637,24 +637,22 @@ pub const Chunk = struct { pub fn dumpLocals(self: *const Chunk, sproc: *sema.Proc) !void { if (cy.Trace) { - if (!cy.silentInternal) { - rt.print(self.vm, "Locals:"); - const params = self.getProcParams(sproc); - for (params) |svar| { - const typeId: types.TypeId = svar.vtype.id; - rt.printFmt(self.vm, "{} (param), local: {}, dyn: {}, rtype: {}, lifted: {}", &.{ - v(svar.name()), v(svar.local), v(svar.vtype.dynamic), v(typeId), - v(svar.inner.local.lifted), - }); - } - const vars = self.getProcVars(sproc); - for (vars) |svar| { - const typeId: types.TypeId = svar.vtype.id; - rt.printFmt(self.vm, "{}, local: {}, dyn: {}, rtype: {}, lifted: {}", &.{ - v(svar.name()), v(svar.local), v(svar.vtype.dynamic), v(typeId), - v(svar.inner.local.lifted), - }); - } + rt.print(self.vm, "Locals:\n"); + const params = self.getProcParams(sproc); + for (params) |svar| { + const typeId: types.TypeId = svar.vtype.id; + rt.printFmt(self.vm, "{} (param), local: {}, dyn: {}, rtype: {}, lifted: {}\n", &.{ + v(svar.name()), v(svar.local), v(svar.vtype.dynamic), v(typeId), + v(svar.inner.local.lifted), + }); + } + const vars = self.getProcVars(sproc); + for (vars) |svar| { + const typeId: types.TypeId = svar.vtype.id; + rt.printFmt(self.vm, "{}, local: {}, dyn: {}, rtype: {}, lifted: {}\n", &.{ + v(svar.name()), v(svar.local), v(svar.vtype.dynamic), v(typeId), + v(svar.inner.local.lifted), + }); } } } diff --git a/src/cli.zig b/src/cli.zig index b1c5febe5..3332b0fbd 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -60,38 +60,33 @@ fn logFn(str: c.Str) callconv(.C) void { } } -fn errorFn(_: ?*c.VM, str: c.Str) callconv(.C) void { - if (cy.silentError) { +fn printError(_: ?*c.VM, str: c.Str) callconv(.C) void { + if (c.silent()) { return; } if (cy.isWasmFreestanding) { os_mod.hostFileWrite(2, str.buf, str.len); - os_mod.hostFileWrite(2, "\n", 1); } else { const w = std.io.getStdErr().writer(); - w.writeAll(c.strSlice(str)) catch cy.fatal(); - w.writeByte('\n') catch cy.fatal(); + w.writeAll(c.fromStr(str)) catch cy.fatal(); } } fn print(_: ?*c.VM, str: c.Str) callconv(.C) void { if (cy.isWasmFreestanding) { os_mod.hostFileWrite(1, str.buf, str.len); - os_mod.hostFileWrite(1, "\n", 1); } else { // Temporarily redirect to error for tests to avoid hanging the Zig runner. if (builtin.is_test) { const w = std.io.getStdErr().writer(); const slice = c.strSlice(str); w.writeAll(slice) catch cy.fatal(); - w.writeByte('\n') catch cy.fatal(); return; } const w = std.io.getStdOut().writer(); const slice = c.strSlice(str); w.writeAll(slice) catch cy.fatal(); - w.writeByte('\n') catch cy.fatal(); } } diff --git a/src/debug.zig b/src/debug.zig index 5ca8e4347..39db4c955 100644 --- a/src/debug.zig +++ b/src/debug.zig @@ -112,7 +112,7 @@ pub fn printTraceAtNode(c: *cy.Chunk, nodeId: cy.NodeId) !void { pub fn printTraceAtPc(vm: *cy.VM, pc: u32, title: []const u8, msg: []const u8) !void { if (pc == cy.NullId) { - rt.errFmt(vm, "{}: {} (external)", &.{v(title), v(msg)}); + rt.printErrorFmt(vm, "{}: {} (external)\n", &.{v(title), v(msg)}); return; } if (getIndexOfDebugSym(vm, pc)) |idx| { @@ -121,7 +121,7 @@ pub fn printTraceAtPc(vm: *cy.VM, pc: u32, title: []const u8, msg: []const u8) ! const node = chunk.ast.node(sym.loc); try printUserError(vm, title, msg, sym.file, node.srcPos); } else { - rt.errFmt(vm, "{}: {}\nMissing debug sym for {}, pc: {}.", &.{ + rt.printErrorFmt(vm, "{}: {}\nMissing debug sym for {}, pc: {}.\n", &.{ v(title), v(msg), v(vm.ops[pc].opcode()), v(pc)}); } } @@ -137,9 +137,8 @@ pub fn printLastUserPanicError(vm: *cy.VM) !void { if (cy.silentError) { return; } - const w = vm.clearTempString(); + var w = rt.ErrorWriter{ .c = vm }; try writeLastUserPanicError(vm, w); - rt.errMsg(vm, vm.getTempString()); } fn writeLastUserPanicError(vm: *const cy.VM, w: anytype) !void { @@ -186,15 +185,14 @@ pub fn printUserError(vm: *cy.VM, title: []const u8, msg: []const u8, chunkId: u if (cy.silentError) { return; } - const w = vm.clearTempString(); - try writeUserError(vm, w, title, msg, chunkId, pos); - rt.errMsg(vm, vm.getTempString()); + var w = rt.ErrorWriter{ .c = vm }; + try writeUserError(vm.compiler, w, title, msg, chunkId, pos); } /// Reduced to using writer so printed errors can be tested. -pub fn writeUserError(vm: *const cy.VM, w: anytype, title: []const u8, msg: []const u8, chunkId: u32, pos: u32) !void { +pub fn writeUserError(c: *const cy.Compiler, w: anytype, title: []const u8, msg: []const u8, chunkId: u32, pos: u32) !void { if (chunkId != cy.NullId) { - const chunk = vm.compiler.chunks.items[chunkId]; + const chunk = c.chunks.items[chunkId]; if (pos != NullId) { var line: u32 = undefined; var col: u32 = undefined; @@ -510,14 +508,14 @@ pub fn dumpBytecode(vm: *cy.VM, opts: DumpBytecodeOptions) !void { // const sblock = &chunk.semaBlocks.items[funcDecl.semaBlockId]; // try chunk.dumpLocals(sblock); } - rt.print(vm, ""); + rt.print(vm, "\n"); const node = chunk.ast.node(sym.loc); const msg = try std.fmt.allocPrint(vm.alloc, "pc={} op={s} node={s}", .{ pcContext, @tagName(pc[pcContext].opcode()), @tagName(node.type()) }); defer vm.alloc.free(msg); try printUserError(vm, "Trace", msg, sym.file, node.srcPos); - rt.print(vm, "Bytecode:"); + rt.print(vm, "Bytecode:\n"); const ContextSize = 40; const startSymIdx = if (idx >= ContextSize) idx - ContextSize else 0; pcOffset = debugTable[startSymIdx].pc; @@ -570,7 +568,7 @@ pub fn dumpBytecode(vm: *cy.VM, opts: DumpBytecodeOptions) !void { } } } else { - rt.print(vm, "Bytecode:"); + rt.print(vm, "Bytecode:\n"); var curMarkerIdx: u32 = if (vm.compiler.buf.debugMarkers.items.len > 0) 0 else cy.NullId; var nextMarkerPc: u32 = if (curMarkerIdx == 0) vm.compiler.buf.debugMarkers.items[curMarkerIdx].pc else cy.NullId; @@ -588,11 +586,11 @@ pub fn dumpBytecode(vm: *cy.VM, opts: DumpBytecodeOptions) !void { instIdx += 1; } - rt.printFmt(vm, "\nConstants ({}):", &.{v(vm.compiler.buf.mconsts.len)}); + rt.printFmt(vm, "\nConstants ({}):\n", &.{v(vm.compiler.buf.mconsts.len)}); for (vm.compiler.buf.mconsts) |extra| { const val = cy.Value{ .val = extra.val }; const str = try vm.bufPrintValueShortStr(&vm.tempBuf, val); - rt.printFmt(vm, "{}", &.{v(str)}); + rt.printFmt(vm, "{}\n", &.{v(str)}); } } } @@ -601,13 +599,13 @@ fn dumpMarkerAdvance(vm: *cy.VM, curMarkerIdx: *u32, nextMarkerPc: *u32) void { const marker = vm.compiler.buf.debugMarkers.items[curMarkerIdx.*]; switch (marker.etype()) { .label => { - rt.printFmt(vm, "{}:", &.{v(marker.getLabelName())}); + rt.printFmt(vm, "{}:\n", &.{v(marker.getLabelName())}); }, .funcStart => { - rt.printFmt(vm, "---- func begin: {}", &.{v(marker.data.funcStart.func.name())}); + rt.printFmt(vm, "---- func begin: {}\n", &.{v(marker.data.funcStart.func.name())}); }, .funcEnd => { - rt.printFmt(vm, "---- func end: {}", &.{v(marker.data.funcEnd.func.name())}); + rt.printFmt(vm, "---- func end: {}\n", &.{v(marker.data.funcEnd.func.name())}); }, } curMarkerIdx.* += 1; diff --git a/src/include/cyber.h b/src/include/cyber.h index 861a05eb9..beea7e3db 100644 --- a/src/include/cyber.h +++ b/src/include/cyber.h @@ -255,13 +255,13 @@ typedef struct CsModuleLoaderResult { // set symbol loaders, and return true. Otherwise, return false. typedef bool (*CsModuleLoaderFn)(CsVM* vm, CsStr resolvedSpec, CsModuleLoaderResult* out); -// Handler for the builtin `print`. +// Handler for printing. The builtin `print` would invoke this. // The default behavior is a no-op. typedef void (*CsPrintFn)(CsVM* vm, CsStr str); -// Handler for VM errors. +// Handler for printing errors. // The default behavior is a no-op. -typedef void (*CsErrorFn)(CsVM* vm, CsStr str); +typedef void (*CsPrintErrorFn)(CsVM* vm, CsStr str); // Handler for compiler and runtime logs. // The default behavior is a no-op. diff --git a/src/runtime.zig b/src/runtime.zig index fe0b11f66..c82cf3e14 100644 --- a/src/runtime.zig +++ b/src/runtime.zig @@ -502,47 +502,72 @@ pub fn getSymName(c: Context, id: u32) []const u8 { } } -pub fn errMsg(c: Context, str: []const u8) void { +pub const ErrorWriter = struct { + c: Context, + + pub fn write(self: ErrorWriter, bytes: []const u8) !void { + return self.writeAll(bytes); + } + + pub fn writeAll(self: ErrorWriter, bytes: []const u8) !void { + printError(self.c, bytes); + } + + pub fn writeByte(self: ErrorWriter, byte: u8) !void { + const array = [1]u8{byte}; + return self.writeAll(&array); + } + + pub fn writeByteNTimes(self: ErrorWriter, byte: u8, n: usize) !void { + var bytes: [256]u8 = undefined; + @memset(bytes[0..], byte); + + var remaining = n; + while (remaining > 0) { + const to_write = @min(remaining, bytes.len); + try self.writeAll(bytes[0..to_write]); + remaining -= to_write; + } + } +}; + +pub fn printError(c: Context, str: []const u8) void { if (build_options.rt == .vm) { - c.errorFn.?(@ptrCast(c), api.initStr(str)); + c.print_err.?(@ptrCast(c), api.toStr(str)); } else { const w = std.io.getStdErr().writer(); w.writeAll(str) catch cy.fatal(); - w.writeByte('\n') catch cy.fatal(); } } -pub fn errFmt(c: Context, format: []const u8, args: []const cy.fmt.FmtValue) void { +pub fn printErrorFmt(c: Context, format: []const u8, args: []const cy.fmt.FmtValue) void { if (build_options.rt == .vm) { const w = c.clearTempString(); cy.fmt.print(w, format, args); - c.errorFn.?(@ptrCast(c), api.initStr(c.getTempString())); + c.print_err.?(@ptrCast(c), api.toStr(c.getTempString())); } else { const w = std.io.getStdErr().writer(); cy.fmt.print(w, format, args); - w.writeByte('\n') catch cy.fatal(); } } -pub fn errZFmt(c: Context, comptime format: []const u8, args: anytype) void { +pub fn printErrorZFmt(c: Context, comptime format: []const u8, args: anytype) void { if (build_options.rt == .vm) { const w = c.clearTempString(); std.fmt.format(w, format, args) catch cy.fatal(); - c.errorFn.?(@ptrCast(c), api.initStr(c.getTempString())); + c.print_err.?(@ptrCast(c), api.toStr(c.getTempString())); } else { const w = std.io.getStdErr().writer(); std.fmt.format(w, format, args) catch cy.fatal(); - w.writeByte('\n') catch cy.fatal(); } } pub fn print(c: Context, str: []const u8) void { if (build_options.rt == .vm) { - c.printFn.?(@ptrCast(c), api.initStr(str)); + c.print.?(@ptrCast(c), api.toStr(str)); } else { const w = std.io.getStdOut().writer(); w.writeAll(str) catch cy.fatal(); - w.writeByte('\n') catch cy.fatal(); } } @@ -550,11 +575,10 @@ pub fn printFmt(c: Context, format: []const u8, args: []const cy.fmt.FmtValue) v if (build_options.rt == .vm) { const w = c.clearTempString(); cy.fmt.print(w, format, args); - c.printFn.?(@ptrCast(c), api.initStr(c.getTempString())); + c.print.?(@ptrCast(c), api.toStr(c.getTempString())); } else { const w = std.io.getStdOut().writer(); cy.fmt.print(w, format, args); - w.writeByte('\n') catch cy.fatal(); } } @@ -562,17 +586,16 @@ pub fn printZFmt(c: Context, comptime format: []const u8, args: anytype) void { if (build_options.rt == .vm) { const w = c.clearTempString(); std.fmt.format(w, format, args); - c.printFn.?(@ptrCast(c), api.initStr(c.getTempString())); + c.print.?(@ptrCast(c), api.toStr(c.getTempString())); } else { const w = std.io.getStdOut().writer(); std.fmt.format(w, format, args); - w.writeByte('\n') catch cy.fatal(); } } pub fn log(str: []const u8) void { if (build_options.rt == .vm) { - cy.log.logFn.?(api.initStr(str)); + cy.log.logFn.?(api.toStr(str)); } else { const w = std.io.getStdErr().writer(); w.writeAll(str) catch cy.fatal(); diff --git a/src/std/test.zig b/src/std/test.zig index 30bdbeef7..766ed66ac 100644 --- a/src/std/test.zig +++ b/src/std/test.zig @@ -83,8 +83,8 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { const exp_t = exp.getTypeId(); if (act_t != exp_t) { - rt.errFmt(c, "Types do not match:", &.{}); - rt.errFmt(c, "actual: {} != {}", &.{v(rt.getTypeName(c, act_t)), v(rt.getTypeName(c, exp_t))}); + rt.printErrorFmt(c, "Types do not match:\n", &.{}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(rt.getTypeName(c, act_t)), v(rt.getTypeName(c, exp_t))}); return false; } @@ -119,7 +119,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (act.asInteger() == exp.asInteger()) { return true; } else { - rt.errFmt(c, "actual: {} != {}", &.{v(act.asInteger()), v(exp.asInteger())}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(act.asInteger()), v(exp.asInteger())}); return false; } }, @@ -127,7 +127,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (act.asF64() == exp.asF64()) { return true; } else { - rt.errFmt(c, "actual: {} != {}", &.{v(act.asF64()), v(exp.asF64())}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(act.asF64()), v(exp.asF64())}); return false; } }, @@ -137,7 +137,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (std.mem.eql(u8, actStr, expStr)) { return true; } else { - rt.errFmt(c, "actual: '{}' != '{}'", &.{v(actStr), v(expStr)}); + rt.printErrorFmt(c, "actual: '{}' != '{}'\n", &.{v(actStr), v(expStr)}); return false; } }, @@ -147,7 +147,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (std.mem.eql(u8, actStr, expStr)) { return true; } else { - rt.errFmt(c, "actual: '{}' != '{}'", &.{v(actStr), v(expStr)}); + rt.printErrorFmt(c, "actual: '{}' != '{}'\n", &.{v(actStr), v(expStr)}); return false; } }, @@ -157,7 +157,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (actPtr == expPtr) { return true; } else { - rt.errFmt(c, "actual: {} != {}", &.{v(actPtr), v(expPtr)}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(actPtr), v(expPtr)}); return false; } }, @@ -167,7 +167,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (actv == expv) { return true; } else { - rt.errFmt(c, "actual: {} != {}", &.{v(actv), v(expv)}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(actv), v(expv)}); return false; } }, @@ -177,7 +177,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (actv == expv) { return true; } else { - rt.errFmt(c, "actual: {} != {}", &.{v(rt.getSymName(c, actv)), v(rt.getSymName(c, expv))}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(rt.getSymName(c, actv)), v(rt.getSymName(c, expv))}); return false; } }, @@ -189,7 +189,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { } else { const actName: []const u8 = if (act.isInterrupt()) "Interrupt" else rt.getSymName(c, actv); const expName: []const u8 = if (exp.isInterrupt()) "Interrupt" else rt.getSymName(c, expv); - rt.errFmt(c, "actual: error.{} != error.{}", &.{v(actName), v(expName)}); + rt.printErrorFmt(c, "actual: error.{} != error.{}\n", &.{v(actName), v(expName)}); return false; } }, @@ -199,7 +199,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (std.meta.eql(actv, expv)) { return true; } else { - rt.errFmt(c, "actual: {} != {}", &.{v(actv.type), v(expv.type)}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(actv.type), v(expv.type)}); return false; } }, @@ -210,7 +210,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (actv == expv) { return true; } else { - rt.errFmt(c, "actual: {} != {}", &.{v(actv), v(expv)}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(actv), v(expv)}); return false; } }, @@ -223,7 +223,7 @@ fn eq2(c: cy.Context, act: rt.Any, exp: rt.Any) bool { if (actv == expv) { return true; } else { - rt.errFmt(c, "actual: {} != {}", &.{v(actv), v(expv)}); + rt.printErrorFmt(c, "actual: {} != {}\n", &.{v(actv), v(expv)}); return false; } } @@ -236,7 +236,7 @@ pub fn assert(vm: *cy.VM, args: [*]const Value, _: u8) anyerror!Value { if (args[0].asBool()) { return Value.Void; } else { - rt.errFmt(vm, "Assertion failed.", &.{}); + rt.printError(vm, "Assertion failed.\n"); return rt.prepThrowError(vm, .AssertError); } } @@ -252,16 +252,16 @@ pub fn eqNear(vm: *cy.VM, args: [*]const Value, _: u8) anyerror!Value { if (std.math.approxEqAbs(f64, act.asF64(), exp.asF64(), 1e-5)) { return Value.True; } else { - rt.errFmt(vm, "actual: {} != {}", &.{v(act.asF64()), v(exp.asF64())}); + rt.printErrorFmt(vm, "actual: {} != {}\n", &.{v(act.asF64()), v(exp.asF64())}); return rt.prepThrowError(vm, .AssertError); } } else { - rt.errFmt(vm, "Expected float, actual: {}", &.{v(actType)}); + rt.printErrorFmt(vm, "Expected float, actual: {}\n", &.{v(actType)}); return rt.prepThrowError(vm, .AssertError); } } else { - rt.errFmt(vm, "Types do not match:", &.{}); - rt.errFmt(vm, "actual: {} != {}", &.{v(actType), v(expType)}); + rt.printErrorFmt(vm, "Types do not match:\n", &.{}); + rt.printErrorFmt(vm, "actual: {} != {}\n", &.{v(actType), v(expType)}); return rt.prepThrowError(vm, .AssertError); } } @@ -282,22 +282,22 @@ pub fn eqList(vm: *cy.VM, args: [*]const Value, _: u8) anyerror!Value { const expItems = expo.list.items(); while (i < acto.list.list.len) : (i += 1) { if (!eq2(vm, actItems[i], expItems[i])) { - rt.errFmt(vm, "Item mismatch at idx: {}", &.{v(i)}); + rt.printErrorFmt(vm, "Item mismatch at idx: {}\n", &.{v(i)}); return rt.prepThrowError(vm, .AssertError); } } return Value.True; } else { - rt.errFmt(vm, "actual list len: {} != {}", &.{v(acto.list.list.len), v(expo.list.list.len)}); + rt.printErrorFmt(vm, "actual list len: {} != {}\n", &.{v(acto.list.list.len), v(expo.list.list.len)}); return rt.prepThrowError(vm, .AssertError); } } else { - rt.errFmt(vm, "Expected list, actual: {}", &.{v(actType)}); + rt.printErrorFmt(vm, "Expected list, actual: {}\n", &.{v(actType)}); return rt.prepThrowError(vm, .AssertError); } } else { - rt.errFmt(vm, "Types do not match:", &.{}); - rt.errFmt(vm, "actual: {} != {}", &.{v(actType), v(expType)}); + rt.printErrorFmt(vm, "Types do not match:\n", &.{}); + rt.printErrorFmt(vm, "actual: {} != {}\n", &.{v(actType), v(expType)}); return rt.prepThrowError(vm, .AssertError); } } \ No newline at end of file diff --git a/src/vm.h b/src/vm.h index 7c863522c..c646bb49c 100644 --- a/src/vm.h +++ b/src/vm.h @@ -922,8 +922,8 @@ typedef struct VM { Compiler* compiler; Sema* sema; void* userData; - void* printFn; - void* errorFn; + void* print; + void* print_err; #if TRACE ZHashMap objectTraceMap; #endif diff --git a/src/vm.zig b/src/vm.zig index caba00ea7..a9e757a39 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -132,9 +132,9 @@ pub const VM = struct { /// User data ptr. Useful for embedders. userData: ?*anyopaque, - /// Host print callback. - printFn: cc.PrintFn, - errorFn: cc.ErrorFn, + /// Host write hook. + print: cc.PrintFn, + print_err: cc.PrintErrorFn, /// Object to pc of instruction that allocated it. objectTraceMap: if (cy.Trace) std.AutoHashMapUnmanaged(*HeapObject, debug.ObjectTrace) else void, @@ -236,8 +236,8 @@ pub const VM = struct { .userData = null, .expGlobalRC = 0, .varSymExtras = .{}, - .printFn = defaultPrint, - .errorFn = defaultErrorFn, + .print = defaultPrint, + .print_err = defaultPrintError, .countFrees = if (cy.Trace) false else {}, .numFreed = if (cy.Trace) 0 else {}, .tempBuf = undefined, @@ -1751,8 +1751,8 @@ test "vm internals." { try t.eq(@offsetOf(VM, "compactTrace"), @offsetOf(vmc.VM, "compactTrace")); try t.eq(@offsetOf(VM, "compiler"), @offsetOf(vmc.VM, "compiler")); try t.eq(@offsetOf(VM, "userData"), @offsetOf(vmc.VM, "userData")); - try t.eq(@offsetOf(VM, "printFn"), @offsetOf(vmc.VM, "printFn")); - try t.eq(@offsetOf(VM, "errorFn"), @offsetOf(vmc.VM, "errorFn")); + try t.eq(@offsetOf(VM, "print"), @offsetOf(vmc.VM, "print")); + try t.eq(@offsetOf(VM, "print_err"), @offsetOf(vmc.VM, "print_err")); try t.eq(@offsetOf(VM, "httpClient"), @offsetOf(vmc.VM, "httpClient")); try t.eq(@offsetOf(VM, "stdHttpClient"), @offsetOf(vmc.VM, "stdHttpClient")); try t.eq(@offsetOf(VM, "emptyString"), @offsetOf(vmc.VM, "emptyString")); @@ -4681,11 +4681,11 @@ pub var dummyCyclableHead = DummyCyclableNode{ }; pub fn defaultPrint(_: ?*cc.VM, _: cc.Str) callconv(.C) void { - // Default print is a nop. + // Default is a nop. } -pub fn defaultErrorFn(_: ?*cc.VM, _: cc.Str) callconv(.C) void { - // Default errorFn is a nop. +pub fn defaultPrintError(_: ?*cc.VM, _: cc.Str) callconv(.C) void { + // Default is a nop. } export fn zDeoptBinOp(vm: *VM, pc: [*]cy.Inst) [*]cy.Inst {