commit 5da00b05c4b95ffcce926ccabf9c36adb12f089c
parent bd9e2497b188e79cc89ca8719a52f7b63d3008d3
Author: Thomas Vigouroux <thomas.vigouroux@univ-grenoble-alpes.fr>
Date: Fri, 14 Jun 2024 08:55:05 +0200
feat: more instrinsics
Diffstat:
4 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/benchmakrs/fib.scm b/benchmarks/fib.scm
diff --git a/benchmarks/syracuse.scm b/benchmarks/syracuse.scm
@@ -0,0 +1,5 @@
+(defn! syracuse (n)
+ (cons n (if (= n 1) (list)
+ (if (= (% n 2) 0)
+ (syracuse (/ n 2))
+ (syracuse (+ (* 3 n) 1))))))
diff --git a/src/compile.zig b/src/compile.zig
@@ -123,6 +123,14 @@ pub const Compiler = struct {
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});
+ try self.compileIntrinsic(.isOdd);
+ } 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 });
+ try self.compileIntrinsic(.fma);
} else switch (val.val) {
inline .function, .native => |_| @panic("Unreachable"),
.symbol => |sym| {
diff --git a/src/core.zig b/src/core.zig
@@ -41,11 +41,24 @@ fn isEven(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
return try v.Value.newBool(all, args[0].val.number.isEven());
}
+// r = 0 * 1 + 2
+fn fma(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
+ if (!args[0].isA(.number) or !args[1].isA(.number) or !args[2].isA(.number)) {
+ return v.NativeError.InvalidType;
+ }
+
+ var new = try v.Int.init(all);
+ try new.mul(&args[0].val.number, &args[1].val.number);
+ try new.add(&new, &args[2].val.number);
+ return try v.Value.newInt(all, new);
+}
+
pub const mapping = enum(usize) {
sqr = 0,
sqrt = 1,
isOdd = 2,
isEven = 3,
+ fma = 4,
};
pub const funcs: []const v.NativeFunction = &.{
@@ -53,6 +66,7 @@ pub const funcs: []const v.NativeFunction = &.{
.{ .arity = 1, .name = "sqrt", .code = sqrt },
.{ .arity = 1, .name = "odd?", .code = isOdd },
.{ .arity = 1, .name = "even?", .code = isEven },
+ .{ .arity = 3, .name = "fma", .code = fma },
};
pub inline fn getIntrinsic(index: mapping) v.NativeFunction {