zahl

Log | Files | Refs | README

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:
Mbenchmarks/syracuse.scm | 10++++++----
Msrc/compile.zig | 35+++++++++++++++++++++++++++--------
Msrc/core.zig | 15+++++++++++++++
Msrc/value.zig | 3+++
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 {