commit 132494ba62ffb033d10925a38f2aea573a022e84
parent 5da00b05c4b95ffcce926ccabf9c36adb12f089c
Author: Thomas Vigouroux <thomas.vigouroux@univ-grenoble-alpes.fr>
Date: Fri, 14 Jun 2024 09:09:34 +0200
feat: do and sequence program
Diffstat:
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/benchmarks/syracuse.scm b/benchmarks/syracuse.scm
@@ -1,5 +1,7 @@
(defn! syracuse (n)
- (cons n (if (= n 1) (list)
- (if (= (% n 2) 0)
- (syracuse (/ n 2))
- (syracuse (+ (* 3 n) 1))))))
+ (do
+ (print! n)
+ (if (= n 1) n
+ (if (= (% n 2) 0)
+ (syracuse (/ n 2))
+ (syracuse (+ (* 3 n) 1))))))
diff --git a/src/compile.zig b/src/compile.zig
@@ -78,7 +78,7 @@ pub const Compiler = struct {
v.Value.Tag => {
return val.isA(desc);
},
- else => {}
+ else => {},
}
switch (@typeInfo(rootT)) {
@@ -120,13 +120,13 @@ pub const Compiler = struct {
fn compileInner(self: *Self, val: *v.Value, astate: CompileState) CompileError!void {
var state = astate;
- if (Compiler.checkMatch(.{v.Special.@"=", .{ v.Special.@"%", .any, 2}, 0}, val)) {
- try self.compileInner(val.val.list[1].val.list[1], .{.return_this = false});
+ if (Compiler.checkMatch(.{ v.Special.@"=", .{ v.Special.@"%", .any, 2 }, 0 }, val)) {
+ try self.compileInner(val.val.list[1].val.list[1], .{ .return_this = false });
try self.compileIntrinsic(.isEven);
- } else if (Compiler.checkMatch(.{v.Special.@"=", .{ v.Special.@"%", .any, 2}, 1}, val)) {
- try self.compileInner(val.val.list[1].val.list[1], .{.return_this = false});
+ } else if (Compiler.checkMatch(.{ v.Special.@"=", .{ v.Special.@"%", .any, 2 }, 1 }, val)) {
+ try self.compileInner(val.val.list[1].val.list[1], .{ .return_this = false });
try self.compileIntrinsic(.isOdd);
- } else if (Compiler.checkMatch(.{v.Special.@"+", .{ v.Special.@"*", .any, .any }, .any}, val)) {
+ } else if (Compiler.checkMatch(.{ v.Special.@"+", .{ v.Special.@"*", .any, .any }, .any }, val)) {
try self.compileInner(val.val.list[1].val.list[1], .{ .return_this = false });
try self.compileInner(val.val.list[1].val.list[2], .{ .return_this = false });
try self.compileInner(val.val.list[2], .{ .return_this = false });
@@ -376,6 +376,17 @@ pub const Compiler = struct {
try self.getChunk().write(.print);
},
+ // (do expr...)
+ .do => if (lst.len > 1) {
+ for (lst[1 .. lst.len - 1]) |ival| {
+ try self.compileInner(ival, .{ .return_this = false });
+ try self.getChunk().write(.pop);
+ }
+ try self.compileInner(lst[lst.len - 1], state);
+
+ return .{ .return_this = false };
+ },
+
.cons => {
try self.compileInner(lst[2], .{ .return_this = false });
try self.compileInner(lst[1], .{ .return_this = false });
@@ -437,7 +448,11 @@ test "Simple match" {
var val = try scanner.readValue(&offset);
defer val.unref();
- try std.testing.expect(Compiler.checkMatch(.{ v.Special.@"%", 2, 3, }, val));
+ try std.testing.expect(Compiler.checkMatch(.{
+ v.Special.@"%",
+ 2,
+ 3,
+ }, val));
}
test "Nested match" {
@@ -456,5 +471,9 @@ test "Nested match" {
var val = try scanner.readValue(&offset);
defer val.unref();
- try std.testing.expect(Compiler.checkMatch(.{ v.Special.@"=", .{ v.Special.@"%", .any, 2}, 0, }, val));
+ try std.testing.expect(Compiler.checkMatch(.{
+ v.Special.@"=",
+ .{ v.Special.@"%", .any, 2 },
+ 0,
+ }, val));
}
diff --git a/src/core.zig b/src/core.zig
@@ -53,12 +53,26 @@ fn fma(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
return try v.Value.newInt(all, new);
}
+// r = gcd 0 1
+fn gcd(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
+ if (!args[0].isA(.number) or !args[1].isA(.number)) {
+ return v.NativeError.InvalidType;
+ }
+
+ var new = try v.Int.init(all);
+
+ try new.gcd(&args[0].val.number, &args[1].val.number);
+
+ return try v.Value.newInt(all, new);
+}
+
pub const mapping = enum(usize) {
sqr = 0,
sqrt = 1,
isOdd = 2,
isEven = 3,
fma = 4,
+ gcd = 5,
};
pub const funcs: []const v.NativeFunction = &.{
@@ -67,6 +81,7 @@ pub const funcs: []const v.NativeFunction = &.{
.{ .arity = 1, .name = "odd?", .code = isOdd },
.{ .arity = 1, .name = "even?", .code = isEven },
.{ .arity = 3, .name = "fma", .code = fma },
+ .{ .arity = 2, .name = "gcd", .code = gcd },
};
pub inline fn getIntrinsic(index: mapping) v.NativeFunction {
diff --git a/src/value.zig b/src/value.zig
@@ -26,6 +26,9 @@ pub const Special = enum {
fst,
rest,
list,
+
+ // somewhat imperative programming ?
+ do,
};
pub const Function = struct {