aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/field.zig46
-rw-r--r--src/pointer.zig32
2 files changed, 48 insertions, 30 deletions
diff --git a/src/field.zig b/src/field.zig
index 0130848..02bf544 100644
--- a/src/field.zig
+++ b/src/field.zig
@@ -393,35 +393,49 @@ pub const Field = struct {
try std.testing.expectEqual(f.get(8, 2), '2');
try std.testing.expectEqual(f.get(9, 2), ' ');
}
- pub fn step(f: *Field, x: i64, y: i64, dx: i64, dy: i64) struct { x: i64, y: i64 } {
+ pub fn step(f: *Field, x: i64, y: i64, dx: i64, dy: i64, smartAdvance: bool, jumping: bool) struct { x: i64, y: i64 } {
var a = x + dx;
var b = y + dy;
- if (f.isIn(a, b)) return .{ .x = a, .y = b };
- // # We are stepping outside, we need to wrap the Lahey-space
- a = x;
- b = y;
- while (true) {
- var c = a - dx;
- var d = b - dy;
- if (!f.isIn(c, d)) return .{ .x = a, .y = b };
- a = c;
- b = d;
+ if (!f.isIn(a, b)) {
+ // # We are stepping outside, we need to wrap the Lahey-space
+ a = x;
+ b = y;
+ while (true) {
+ var c = a - dx;
+ var d = b - dy;
+ if (!f.isIn(c, d)) break;
+ a = c;
+ b = d;
+ }
+ }
+ if (smartAdvance) {
+ const v = f.get(a, b);
+ if (jumping) {
+ return f.step(a, b, dx, dy, true, v != ';');
+ }
+ if (v == ' ') {
+ return f.step(a, b, dx, dy, true, false);
+ }
+ if (v == ';') {
+ return f.step(a, b, dx, dy, true, true);
+ }
}
+ return .{ .x = a, .y = b };
}
test "step" {
var minimal = std.io.fixedBufferStream("@");
var f = try Field.init(std.testing.allocator);
defer f.deinit();
try f.load(minimal.reader());
- try std.testing.expectEqual(f.step(0, 0, 0, 0), .{ .x = 0, .y = 0 });
- try std.testing.expectEqual(f.step(0, 0, 1, 0), .{ .x = 0, .y = 0 });
+ try std.testing.expectEqual(f.step(0, 0, 0, 0, false, false), .{ .x = 0, .y = 0 });
+ try std.testing.expectEqual(f.step(0, 0, 1, 0, false, false), .{ .x = 0, .y = 0 });
var hello = std.io.fixedBufferStream("64+\"!dlroW ,olleH\">:#,_@\n");
var fHello = try Field.init(std.testing.allocator);
defer fHello.deinit();
try fHello.load(hello.reader());
- try std.testing.expectEqual(fHello.step(3, 0, 0, 0), .{ .x = 3, .y = 0 });
- try std.testing.expectEqual(fHello.step(3, 0, 1, 0), .{ .x = 4, .y = 0 });
- try std.testing.expectEqual(fHello.step(0, 0, -1, 0), .{ .x = 23, .y = 0 });
+ try std.testing.expectEqual(fHello.step(3, 0, 0, 0, false, false), .{ .x = 3, .y = 0 });
+ try std.testing.expectEqual(fHello.step(3, 0, 1, 0, false, false), .{ .x = 4, .y = 0 });
+ try std.testing.expectEqual(fHello.step(0, 0, -1, 0, false, false), .{ .x = 23, .y = 0 });
}
};
diff --git a/src/pointer.zig b/src/pointer.zig
index 653f890..75bc5ae 100644
--- a/src/pointer.zig
+++ b/src/pointer.zig
@@ -40,18 +40,20 @@ pub const Pointer = struct {
switch (c) {
'@' => return pointerReturn{},
'z' => {},
- '#' => p.step(),
+ '#' => {
+ p.step(false);
+ },
'j' => {
var n = p.ss.toss.pop();
var j: usize = 0;
if (n > 0) {
while (j < n) : (j += 1) {
- p.step();
+ p.step(false);
}
} else {
p.reverse();
while (j < -n) : (j += 1) {
- p.step();
+ p.step(false);
}
p.reverse();
}
@@ -61,9 +63,9 @@ pub const Pointer = struct {
const x = p.x;
const y = p.y;
const n = p.ss.toss.pop();
- var v = p.stepAndGet();
+ var v = p.stepAndGet(false);
var jumpingMode = false;
- while (jumpingMode or v == ' ' or v == ';') : (v = p.stepAndGet()) {
+ while (jumpingMode or v == ' ' or v == ';') : (v = p.stepAndGet(false)) {
if (v == ';') jumpingMode = !jumpingMode;
}
if (n > 0) {
@@ -147,9 +149,11 @@ pub const Pointer = struct {
}
},
'"' => p.stringMode = true,
- '\'' => try p.ss.toss.push(p.stepAndGet()),
+ '\'' => {
+ try p.ss.toss.push(p.stepAndGet(false));
+ },
's' => {
- p.step();
+ p.step(false);
try p.field.set(p.x, p.y, p.ss.toss.pop());
},
'$' => _ = p.ss.toss.pop(),
@@ -331,7 +335,7 @@ pub const Pointer = struct {
if (self.stringMode) {
if (self.lastCharWasSpace) {
while (c == ' ') {
- c = self.stepAndGet();
+ c = self.stepAndGet(false);
}
self.lastCharWasSpace = false;
}
@@ -345,11 +349,11 @@ pub const Pointer = struct {
var jumpingMode = false;
while (jumpingMode or c == ' ' or c == ';') {
if (c == ';') jumpingMode = !jumpingMode;
- c = self.stepAndGet();
+ c = self.stepAndGet(false);
}
result = try self.eval(ioContext, c);
}
- self.step();
+ self.step(!self.stringMode);
return result;
}
pub fn init(allocator: std.mem.Allocator, f: *field.Field, timestamp: ?i64, argv: []const []const u8, env: []const [*:0]const u8) !*Pointer {
@@ -423,13 +427,13 @@ pub const Pointer = struct {
p.dx = -p.dx;
p.dy = -p.dy;
}
- inline fn step(self: *Pointer) void {
- const v = self.field.step(self.x, self.y, self.dx, self.dy);
+ inline fn step(self: *Pointer, smartAdvance: bool) void {
+ const v = self.field.step(self.x, self.y, self.dx, self.dy, smartAdvance, false);
self.x = v.x;
self.y = v.y;
}
- inline fn stepAndGet(self: *Pointer) i64 {
- self.step();
+ inline fn stepAndGet(self: *Pointer, smartAdvance: bool) i64 {
+ self.step(smartAdvance);
return self.field.get(self.x, self.y);
}
};