aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--README.md8
-rw-r--r--build.zig79
m---------lib/spoon0
-rw-r--r--src/field.zig69
-rw-r--r--src/io.zig6
-rw-r--r--src/main.zig12
-rw-r--r--src/pointer.zig19
-rw-r--r--src/stack.zig4
-rw-r--r--src/stackStack.zig8
-rw-r--r--src/tui.zig48
10 files changed, 151 insertions, 102 deletions
diff --git a/README.md b/README.md
index a3e7b63..113b3a6 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Current limitations are :
## Dependencies
-zig is required. Only zig version >= 0.10.1 on linux amd64 (Gentoo) is being regularly tested.
+zig is required. Only zig version 0.11 on linux amd64 (Gentoo) is being regularly tested.
## Quick Install
@@ -58,7 +58,7 @@ zig build
For a non debug build, use either one of:
```sh
-zig build -Drelease-safe
-zig build -Drelease-small
-zig build -Drelease-fast
+zig build -Doptimize=ReleaseSafe
+zig build -Doptimize=ReleaseSmall
+zig build -Doptimize=ReleaseFast
```
diff --git a/build.zig b/build.zig
index 3ac3e80..00ea514 100644
--- a/build.zig
+++ b/build.zig
@@ -1,45 +1,32 @@
const std = @import("std");
-pub fn build(b: *std.build.Builder) void {
- // Standard target options allows the person running `zig build` to choose
- // what target to build for. Here we do not override the defaults, which
- // means any target is allowed, and the default is native. Other options
- // for restricting supported target set are available.
+pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
+ const optimize = b.standardOptimizeOption(.{});
- // Standard release options allow the person running `zig build` to select
- // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
- const mode = b.standardReleaseOptions();
-
- const exe = b.addExecutable("zigfunge98", "src/main.zig");
- exe.setTarget(target);
- exe.setBuildMode(mode);
- exe.install();
-
- const run_cmd = exe.run();
+ const exe = b.addExecutable(.{
+ .name = "zigfunge98",
+ .root_source_file = .{ .path = "src/main.zig" },
+ .target = target,
+ .optimize = optimize,
+ });
+ b.installArtifact(exe);
+ const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
-
- const tui = b.addExecutable("zigfunge98-tui", "src/tui.zig");
- tui.addPackagePath("spoon", "lib/spoon/import.zig");
- tui.setTarget(target);
- tui.setBuildMode(mode);
- tui.install();
-
- const coverage = b.option(bool, "test-coverage", "Generate test coverage") orelse false;
-
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
+ const unit_tests = b.addTest(.{
+ .root_source_file = .{ .path = "src/main.zig" },
+ .target = target,
+ .optimize = optimize,
+ });
- const exe_tests = b.addTest("src/main.zig");
- exe_tests.setTarget(target);
- exe_tests.setBuildMode(mode);
-
+ const coverage = b.option(bool, "test-coverage", "Generate test coverage") orelse false;
// Code coverage with kcov, we need an allocator for the setup
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
- defer _ = general_purpose_allocator.deinit();
const gpa = general_purpose_allocator.allocator();
// We want to exclude the $HOME/.zig path
const home = std.process.getEnvVarOwned(gpa, "HOME") catch "";
@@ -47,7 +34,8 @@ pub fn build(b: *std.build.Builder) void {
const exclude = std.fmt.allocPrint(gpa, "--exclude-path={s}/.zig/", .{home}) catch "";
defer gpa.free(exclude);
if (coverage) {
- exe_tests.setExecCmd(&[_]?[]const u8{
+ unit_tests.test_runner = "/usr/bin/kcov";
+ unit_tests.setExecCmd(&[_]?[]const u8{
"kcov",
exclude,
//"--path-strip-level=3", // any kcov flags can be specified here
@@ -56,6 +44,35 @@ pub fn build(b: *std.build.Builder) void {
});
}
+ const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
- test_step.dependOn(&exe_tests.step);
+ test_step.dependOn(&run_unit_tests.step);
+
+ // ----- TUI --------------------------------------------------------------
+ const tui = b.addExecutable(.{
+ .name = "zigfunge98-tui",
+ .root_source_file = .{ .path = "src/tui.zig" },
+ .target = target,
+ .optimize = optimize,
+ });
+ const spoon = b.createModule(.{
+ .source_file = .{ .path = "lib/spoon/import.zig" },
+ });
+ tui.addModule("spoon", spoon);
+ b.installArtifact(tui);
+ const tui_cmd = b.addRunArtifact(tui);
+ tui_cmd.step.dependOn(b.getInstallStep());
+ if (b.args) |args| {
+ tui_cmd.addArgs(args);
+ }
+ const tui_step = b.step("run-tui", "Run the app");
+ tui_step.dependOn(&tui_cmd.step);
+ const tui_unit_tests = b.addTest(.{
+ .root_source_file = .{ .path = "src/tui.zig" },
+ .target = target,
+ .optimize = optimize,
+ });
+ const tui_run_unit_tests = b.addRunArtifact(tui_unit_tests);
+ const tui_test_step = b.step("test-tui", "Run tui unit tests");
+ tui_test_step.dependOn(&tui_run_unit_tests.step);
}
diff --git a/lib/spoon b/lib/spoon
-Subproject 75dbab71771ca2ee5aadcd5ab7a4c503a953603
+Subproject 9fa5bb1eafc30b3ff0cbe297a3e0f51dbc90383
diff --git a/src/field.zig b/src/field.zig
index ef5e6ea..bf170fb 100644
--- a/src/field.zig
+++ b/src/field.zig
@@ -5,17 +5,17 @@ const Line = struct {
x: i64 = 0,
data: std.ArrayList(i64),
fn blank(l: *Line, x: i64) void {
- const lx = @intCast(i64, l.len());
+ const lx: i64 = @intCast(l.len());
if (x < l.x or x > l.x + lx - 1) { // outside the field
return;
} else if (x > l.x and x < l.x + lx - 1) { // just set the value
- l.data.items[@intCast(usize, x - l.x)] = ' ';
+ l.data.items[@intCast(x - l.x)] = ' ';
} else if (lx == 1) { // this was the last character on the line
l.data.items.len = 0;
} else if (x == l.x) { // we need to remove leading spaces
var i: usize = 1;
while (l.data.items[i] == ' ') : (i += 1) {}
- l.x += @intCast(i64, i);
+ l.x += @intCast(i);
std.mem.copy(i64, l.data.items[0 .. l.len() - i], l.data.items[i..]);
l.data.items.len -= i;
} else { // we need to remove trailing spaces
@@ -66,7 +66,8 @@ const Line = struct {
self.allocator.destroy(self);
}
fn get(l: *Line, x: i64) i64 {
- if (x >= l.x and x < l.x + @intCast(i64, l.len())) return l.data.items[@intCast(usize, x - @intCast(i64, l.x))];
+ const ll: i64 = @intCast(l.len());
+ if (x >= l.x and x < l.x + ll) return l.data.items[@intCast(x - l.x)];
return ' ';
}
fn init(allocator: std.mem.Allocator) !*Line {
@@ -84,10 +85,10 @@ const Line = struct {
try l.data.append(v);
return;
}
- const lx = @intCast(i64, l.len());
+ const lx: i64 = @intCast(l.len());
if (x >= l.x) {
if (x < l.x + lx) { // just set the value
- l.data.items[@intCast(usize, x - l.x)] = v;
+ l.data.items[@intCast(x - l.x)] = v;
} else { // we need to add trailing spaces
var i: usize = l.len();
while (i < x - l.x) : (i += 1) {
@@ -97,12 +98,12 @@ const Line = struct {
}
} else { // we need to shift right and add leading spaces
const oldLen = l.len();
- l.data.items.len += @intCast(usize, l.x - x);
+ l.data.items.len += @intCast(l.x - x);
try l.data.ensureUnusedCapacity(l.len());
- std.mem.copyBackwards(i64, l.data.items[@intCast(usize, l.x - x)..], l.data.items[0..oldLen]);
+ std.mem.copyBackwards(i64, l.data.items[@intCast(l.x - x)..], l.data.items[0..oldLen]);
l.data.items[0] = v;
var i: usize = 1;
- while (i < @intCast(usize, l.x - x)) : (i += 1) {
+ while (i < l.x - x) : (i += 1) {
l.data.items[i] = ' ';
}
l.x = x;
@@ -150,10 +151,11 @@ pub const Field = struct {
lines: std.ArrayList(*Line),
lx: usize = 0,
pub fn blank(f: *Field, x: i64, y: i64) !void {
- const ly = @intCast(i64, f.lines.items.len);
+ const ly = f.lines.items.len;
if (ly == 0) return error.EmptyFieldError;
- if (y < f.y or y >= f.y + ly) return; // outside the field
- var l = f.lines.items[@intCast(usize, y - f.y)];
+ const lly: i64 = @intCast(ly);
+ if (y < f.y or y >= f.y + lly) return; // outside the field
+ var l = f.lines.items[@intCast(y - f.y)];
if (l.len() == 0) return; // the line is already empty
l.blank(x);
if (l.len() == 0) {
@@ -165,27 +167,29 @@ pub const Field = struct {
while (f.lines.items[i].len() == 0) : (i += 1) {
f.lines.items[i].deinit();
}
- f.y += @intCast(i64, i);
+ f.y += @intCast(i);
std.mem.copy(*Line, f.lines.items[0 .. f.lines.items.len - i], f.lines.items[i..]);
f.lines.items.len -= i;
- } else if (y == f.y + ly - 1) { // we need to remove trailing lines
+ } else if (y == f.y + lly - 1) { // we need to remove trailing lines
l.deinit();
- var i: usize = @intCast(usize, ly) - 2;
+ var i: usize = ly - 2;
while (f.lines.items[i].len() == 0) : (i -= 1) {
f.lines.items[i].deinit();
}
f.lines.items.len = i + 1;
}
}
- if (x == f.x or x == f.x + @intCast(i64, f.lx) - 1) { // recalculate boundaries
+ const flx: i64 = @intCast(f.lx);
+ if (x == f.x or x == f.x + flx - 1) { // recalculate boundaries
f.x = std.math.maxInt(i64);
var x2: i64 = std.math.minInt(i64);
for (f.lines.items) |line| {
if (line.len() == 0) continue;
if (f.x > line.x) f.x = line.x;
- if (x2 < line.x + @intCast(i64, line.len())) x2 = line.x + @intCast(i64, line.len());
+ const ll: i64 = @intCast(line.len());
+ if (x2 < line.x + ll) x2 = line.x + ll;
}
- f.lx = @intCast(usize, x2 - f.x);
+ f.lx = @intCast(x2 - f.x);
}
}
test "blank" {
@@ -241,11 +245,12 @@ pub const Field = struct {
self.allocator.destroy(self);
}
pub fn get(f: *Field, x: i64, y: i64) i64 {
- if (y >= f.y and y < f.y + @intCast(i64, f.lines.items.len)) return f.lines.items[@intCast(usize, y - @intCast(i64, f.y))].get(x);
+ const fl: i64 = @intCast(f.lines.items.len);
+ if (y >= f.y and y < f.y + fl) return f.lines.items[@intCast(y - f.y)].get(x);
return ' ';
}
pub fn getSize(f: Field) [4]i64 {
- return [4]i64{ f.x, f.y, @intCast(i64, f.lx), @intCast(i64, f.lines.items.len) };
+ return [4]i64{ f.x, f.y, @intCast(f.lx), @intCast(f.lines.items.len) };
}
fn init(allocator: std.mem.Allocator) !*Field {
var f = try allocator.create(Field);
@@ -266,7 +271,9 @@ pub const Field = struct {
return f;
}
inline fn isIn(f: *Field, x: i64, y: i64) bool {
- return x >= f.x and y >= f.y and x < f.x + @intCast(i64, f.lx) and y < f.y + @intCast(i64, f.lines.items.len);
+ const fl: i64 = @intCast(f.lines.items.len);
+ const flx: i64 = @intCast(f.lx);
+ return x >= f.x and y >= f.y and x < f.x + flx and y < f.y + fl;
}
fn load(f: *Field, reader: anytype) !void {
if (f.lines.items.len > 1 or f.lx > 0) return error.FIELD_NOT_EMPTY;
@@ -334,8 +341,9 @@ pub const Field = struct {
pub fn set(f: *Field, x: i64, y: i64, v: i64) !void {
if (v == ' ') return f.blank(x, y);
if (y >= f.y) {
- if (y < f.y + @intCast(i64, f.lines.items.len)) { // the line exists
- try f.lines.items[@intCast(usize, y - f.y)].set(x, v);
+ const fl: i64 = @intCast(f.lines.items.len);
+ if (y < f.y + fl) { // the line exists
+ try f.lines.items[@intCast(y - f.y)].set(x, v);
} else { // append lines
var i: usize = f.lines.items.len;
while (i < y - f.y) : (i += 1) {
@@ -347,27 +355,30 @@ pub const Field = struct {
}
} else { // preprend lines
const oldLen = f.lines.items.len;
- f.lines.items.len += @intCast(usize, f.y - y);
+ const dl: usize = @intCast(f.y - y);
+ f.lines.items.len += dl;
try f.lines.ensureUnusedCapacity(f.lines.items.len);
- std.mem.copyBackwards(*Line, f.lines.items[@intCast(usize, f.y - y)..], f.lines.items[0..oldLen]);
+ std.mem.copyBackwards(*Line, f.lines.items[dl..], f.lines.items[0..oldLen]);
var l = try Line.init(f.allocator);
try l.set(x, v);
f.lines.items[0] = l;
var i: usize = 1;
- while (i < @intCast(usize, f.y - y)) : (i += 1) {
+ while (i < f.y - y) : (i += 1) {
f.lines.items[i] = try Line.init(f.allocator);
}
f.y = y;
}
- if (x < f.x or x >= f.x + @intCast(i64, f.lx)) { // recalculate boundaries
+ const flx: i64 = @intCast(f.lx);
+ if (x < f.x or x >= f.x + flx) { // recalculate boundaries
f.x = std.math.maxInt(i64);
var x2: i64 = std.math.minInt(i64);
for (f.lines.items) |line| {
if (line.len() == 0) continue;
if (f.x > line.x) f.x = line.x;
- if (x2 < line.x + @intCast(i64, line.len())) x2 = line.x + @intCast(i64, line.len());
+ const ll: i64 = @intCast(line.len());
+ if (x2 < line.x + ll) x2 = line.x + ll;
}
- f.lx = @intCast(usize, x2 - f.x);
+ f.lx = @intCast(x2 - f.x);
}
return;
}
diff --git a/src/io.zig b/src/io.zig
index 54abcfc..2cc0047 100644
--- a/src/io.zig
+++ b/src/io.zig
@@ -60,7 +60,11 @@ pub fn Context(comptime readerType: anytype, comptime writerType: anytype) type
try std.testing.expectEqual(ioContext.decimalInput(), error.IOError);
}
pub fn characterOutput(self: Self, v: i64) !void {
- try self.writer.print("{c}", .{@intCast(u8, v)});
+ var vv: u8 = '?';
+ if (v >= 0 and v <= 255) {
+ vv = @intCast(v);
+ }
+ try self.writer.print("{c}", .{vv});
return;
}
pub fn decimalOutput(self: Self, v: i64) !void {
diff --git a/src/main.zig b/src/main.zig
index 7337100..920d306 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -3,10 +3,10 @@ const interpreter = @import("interpreter.zig");
const io = @import("io.zig");
pub fn main() anyerror!void {
- var gpa = std.heap.GeneralPurposeAllocator(.{}){};
- defer std.debug.assert(!gpa.deinit());
- var args = try std.process.argsAlloc(gpa.allocator());
- defer std.process.argsFree(gpa.allocator(), args);
+ var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
+ const gpa = general_purpose_allocator.allocator();
+ var args = try std.process.argsAlloc(gpa);
+ defer std.process.argsFree(gpa, args);
if (args.len < 2) {
std.debug.print("Usage: {s} <b98_file_to_run>\n", .{args[0]});
std.os.exit(1);
@@ -16,11 +16,11 @@ pub fn main() anyerror!void {
defer file.close();
const env: []const [*:0]const u8 = std.os.environ;
- var i = try interpreter.Interpreter.init(gpa.allocator(), file.reader(), null, args, env[0..]);
+ var i = try interpreter.Interpreter.init(gpa, file.reader(), null, args, env[0..]);
defer i.deinit();
var ioContext = io.context(std.io.getStdIn().reader(), std.io.getStdOut().writer());
- std.os.exit(@intCast(u8, try i.run(&ioContext)));
+ std.os.exit(@intCast(try i.run(&ioContext)));
}
const testTimestamp: i64 = 1660681247;
diff --git a/src/pointer.zig b/src/pointer.zig
index 75bc5ae..eeb1204 100644
--- a/src/pointer.zig
+++ b/src/pointer.zig
@@ -245,21 +245,26 @@ pub const Pointer = struct {
// 18
i = 0;
while (i < p.ss.data.items.len) : (i += 1) {
- try p.ss.toss.push(@intCast(i64, p.ss.data.items[i].data.items.len));
+ try p.ss.toss.push(@intCast(p.ss.data.items[i].data.items.len));
}
- try p.ss.toss.push(@intCast(i64, height));
+ try p.ss.toss.push(@intCast(height));
// 17
- try p.ss.toss.push(@intCast(i64, p.ss.data.items.len) + 1);
+ try p.ss.toss.push(@intCast(p.ss.data.items.len + 1));
// 16
const ts = if (p.timestamp) |v| v else std.time.timestamp();
- const now = std.time.epoch.EpochSeconds{ .secs = @intCast(u64, ts) };
+ const now = std.time.epoch.EpochSeconds{ .secs = @intCast(ts) };
const epochDay = now.getEpochDay();
const daySeconds = now.getDaySeconds();
- try p.ss.toss.push(@intCast(i64, daySeconds.getHoursIntoDay()) * 256 * 256 + @intCast(i64, daySeconds.getMinutesIntoHour()) * 256 + @intCast(i64, daySeconds.getSecondsIntoMinute()));
+ const hours: i64 = @intCast(daySeconds.getHoursIntoDay());
+ const minutes: i64 = @intCast(daySeconds.getMinutesIntoHour());
+ const seconds: i64 = @intCast(daySeconds.getSecondsIntoMinute());
+ try p.ss.toss.push(hours * 256 * 256 + minutes * 256 + seconds);
// 15
const yearAndDay = epochDay.calculateYearDay();
+ const year: i64 = @intCast(yearAndDay.year);
const monthAndDay = yearAndDay.calculateMonthDay();
- try p.ss.toss.push(@intCast(i64, yearAndDay.year - 1900) * 256 * 256 + @intCast(i64, monthAndDay.month.numeric()) * 256 + @intCast(i64, monthAndDay.day_index));
+ const month: i64 = @intCast(monthAndDay.month.numeric());
+ try p.ss.toss.push((year - 1900) * 256 * 256 + month * 256 + monthAndDay.day_index);
// 14
try p.ss.toss.pushVector([2]i64{ fieldSize[2] - 1, fieldSize[3] - 1 });
// 13
@@ -289,7 +294,7 @@ pub const Pointer = struct {
// 1
try p.ss.toss.push(0b00000); // TODO update when implementing t, i, o and =
if (n > 0) {
- try p.ss.toss.yCommandPick(@intCast(usize, n), height);
+ try p.ss.toss.yCommandPick(@intCast(n), height);
}
},
'(' => {
diff --git a/src/stack.zig b/src/stack.zig
index c1f8696..dd76af1 100644
--- a/src/stack.zig
+++ b/src/stack.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const vector = std.meta.Vector(2, i64);
+const vector = @Vector(2, i64);
pub const Stack = struct {
allocator: std.mem.Allocator,
@@ -78,7 +78,7 @@ pub const Stack = struct {
// (aka begin) and '}' (aka end) stackstack commands
try toss.data.ensureUnusedCapacity(n);
var i: usize = n;
- while (i >= std.math.min(soss.data.items.len, n) + 1) : (i -= 1) {
+ while (i >= @min(soss.data.items.len, n) + 1) : (i -= 1) {
toss.data.appendAssumeCapacity(0);
}
while (i >= 1) : (i -= 1) {
diff --git a/src/stackStack.zig b/src/stackStack.zig
index a76d304..d846429 100644
--- a/src/stackStack.zig
+++ b/src/stackStack.zig
@@ -28,7 +28,7 @@ pub const StackStack = struct {
const n = soss.pop();
self.toss = try stack.Stack.init(self.allocator);
if (n > 0) {
- try self.toss.transfert(soss, @intCast(u64, n));
+ try self.toss.transfert(soss, @intCast(n));
} else if (n < 0) {
var i: usize = 0;
while (i < -n) : (i += 1) {
@@ -85,9 +85,11 @@ pub const StackStack = struct {
const n = self.toss.pop();
const v = soss.popVector();
if (n > 0) {
- try soss.transfert(self.toss, @intCast(u64, n));
+ const nn: usize = @intCast(n);
+ try soss.transfert(self.toss, nn);
} else {
- soss.discard(@intCast(u64, -n));
+ const nn: usize = @intCast(-n);
+ soss.discard(nn);
}
self.toss.deinit();
self.toss = soss;
diff --git a/src/tui.zig b/src/tui.zig
index 8d60bce..8c4145f 100644
--- a/src/tui.zig
+++ b/src/tui.zig
@@ -9,10 +9,10 @@ var intp: *interpreter.Interpreter = undefined;
pub fn main() anyerror!void {
//--- befunge initialization ----------------------------------------------
- var gpa = std.heap.GeneralPurposeAllocator(.{}){};
- defer std.debug.assert(!gpa.deinit());
- args = try std.process.argsAlloc(gpa.allocator());
- defer std.process.argsFree(gpa.allocator(), args);
+ var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
+ const gpa = general_purpose_allocator.allocator();
+ args = try std.process.argsAlloc(gpa);
+ defer std.process.argsFree(gpa, args);
if (args.len < 2) {
std.debug.print("Usage: {s} <b98_file_to_run>\n", .{args[0]});
std.os.exit(1);
@@ -22,7 +22,7 @@ pub fn main() anyerror!void {
defer file.close();
const env: []const [*:0]const u8 = std.os.environ;
- intp = try interpreter.Interpreter.init(gpa.allocator(), file.reader(), null, args, env[0..]);
+ intp = try interpreter.Interpreter.init(gpa, file.reader(), null, args, env[0..]);
defer intp.deinit();
var ioContext = io.context(std.io.getStdIn().reader(), std.io.getStdOut().writer()); // TODO io functions for tui
@@ -38,11 +38,13 @@ pub fn main() anyerror!void {
}, null);
var fds: [1]std.os.pollfd = undefined;
- fds[0] = .{
- .fd = term.tty.handle,
- .events = std.os.POLL.IN,
- .revents = undefined,
- };
+ if (term.tty) |tty| {
+ fds[0] = .{
+ .fd = tty,
+ .events = std.os.POLL.IN,
+ .revents = undefined,
+ };
+ }
try term.uncook(.{});
defer term.cook() catch {};
@@ -68,9 +70,8 @@ pub fn main() anyerror!void {
term.deinit();
intp.deinit();
file.close();
- std.process.argsFree(gpa.allocator(), args);
- std.debug.assert(!gpa.deinit());
- std.os.exit(@intCast(u8, code));
+ std.process.argsFree(gpa, args);
+ std.os.exit(@intCast(code));
}
try render();
}
@@ -110,7 +111,8 @@ fn render() !void {
var s = rc.restrictedPaddingWriter(16);
const v = intp.pointer.ss.toss.data.items[n];
if (v >= 32 and v < 127) {
- try s.writer().print("{c} - {d}", .{ @intCast(u8, v), v });
+ const tv: u8 = @intCast(v);
+ try s.writer().print("{c} - {d}", .{ tv, v });
} else {
try s.writer().print("{d}", .{v});
}
@@ -119,28 +121,36 @@ fn render() !void {
try rc.moveCursorTo(2, 18);
try rc.setAttribute(.{ .fg = .blue, .reverse = true });
var fieldTitle = rc.restrictedPaddingWriter(term.width - 17);
- const size = intp.field.getSize();
+ const sizei = intp.field.getSize();
+ const size = [4]usize{ @intCast(sizei[0]), @intCast(sizei[1]), @intCast(sizei[2]), @intCast(sizei[3]) };
try fieldTitle.writer().print("Funge field | top left corner:({d},{d}) size:{d}x{d}", .{ size[0], size[1], size[2], size[3] });
try fieldTitle.pad();
try rc.setAttribute(.{ .fg = .blue, .reverse = false });
var y: usize = 0; // TODO negative lines
- while (y < @min(@intCast(usize, size[3]), term.height - 3)) : (y += 1) {
+ while (y < @min(size[3], term.height - 3)) : (y += 1) {
var field = rc.restrictedPaddingWriter(term.width - 17);
const line = intp.field.lines.items[y];
var x: usize = 0;
if (line.x >= 0) {
- try rc.moveCursorTo(y + 3, 18 + @intCast(usize, line.x));
+ const lx: usize = @intCast(line.x);
+ try rc.moveCursorTo(y + 3, 18 + lx);
} else {
try rc.moveCursorTo(y + 3, 18); // TODO negative columns
}
while (x < @min(line.data.items.len, term.width - 18)) : (x += 1) {
var reset = false;
- if (x + @intCast(usize, line.x) == intp.pointer.x and y == intp.pointer.y) { // TODO negatives
+ const xx: i64 = @intCast(x);
+ if (xx + line.x == intp.pointer.x and y == intp.pointer.y) { // TODO negatives
try rc.setAttribute(.{ .fg = .red, .reverse = true });
reset = true;
}
if (line.data.items[x] >= 32 and line.data.items[x] < 127) {
- try field.writer().print("{c}", .{@intCast(u8, line.data.items[x])});
+ const v = line.data.items[x];
+ var vv: u8 = '?';
+ if (v >= 32 and v < 127) {
+ vv = @intCast(v);
+ }
+ try field.writer().print("{c}", .{vv});
} else {
try field.writer().writeAll("®");
}