zig 0.11 changes
This commit is contained in:
parent
8b3b7582c2
commit
83af8ab124
10 changed files with 152 additions and 103 deletions
|
@ -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
|
||||
```
|
||||
|
|
79
build.zig
79
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);
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 75dbab71771ca2ee5aadcd5ab7a4c503a9536031
|
||||
Subproject commit 9fa5bb1eafc30b3ff0cbe297a3e0f51dbc903831
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
12
src/main.zig
12
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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
},
|
||||
'(' => {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
48
src/tui.zig
48
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("®");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue