zahl

Log | Files | Refs | README

core.zig (2365B)


      1 const std = @import("std");
      2 const v = @import("value.zig");
      3 
      4 fn sqr(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
      5     var newval = try v.Int.init(all);
      6 
      7     if (!args[0].isA(.number)) {
      8         return v.NativeError.InvalidType;
      9     }
     10 
     11     try newval.sqr(&args[0].val.number);
     12 
     13     return try v.Value.newInt(all, newval);
     14 }
     15 
     16 fn sqrt(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
     17     if (!args[0].isA(.number) or !args[0].val.number.isPositive()) {
     18         return v.NativeError.InvalidType;
     19     }
     20 
     21     var newval = try v.Int.init(all);
     22 
     23     try newval.sqrt(&args[0].val.number);
     24 
     25     return try v.Value.newInt(all, newval);
     26 }
     27 
     28 fn isOdd(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
     29     if (!args[0].isA(.number)) {
     30         return v.NativeError.InvalidType;
     31     }
     32 
     33     return try v.Value.newBool(all, args[0].val.number.isOdd());
     34 }
     35 
     36 fn isEven(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
     37     if (!args[0].isA(.number)) {
     38         return v.NativeError.InvalidType;
     39     }
     40 
     41     return try v.Value.newBool(all, args[0].val.number.isEven());
     42 }
     43 
     44 // r = 0 * 1 + 2
     45 fn fma(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
     46     if (!args[0].isA(.number) or !args[1].isA(.number) or !args[2].isA(.number)) {
     47         return v.NativeError.InvalidType;
     48     }
     49 
     50     var new = try v.Int.init(all);
     51     try new.mul(&args[0].val.number, &args[1].val.number);
     52     try new.add(&new, &args[2].val.number);
     53     return try v.Value.newInt(all, new);
     54 }
     55 
     56 // r = gcd 0 1
     57 fn gcd(args: []*v.Value, all: std.mem.Allocator) !*v.Value {
     58     if (!args[0].isA(.number) or !args[1].isA(.number)) {
     59         return v.NativeError.InvalidType;
     60     }
     61 
     62     var new = try v.Int.init(all);
     63 
     64     try new.gcd(&args[0].val.number, &args[1].val.number);
     65 
     66     return try v.Value.newInt(all, new);
     67 }
     68 
     69 pub const mapping = enum(usize) {
     70     sqr = 0,
     71     sqrt = 1,
     72     isOdd = 2,
     73     isEven = 3,
     74     fma = 4,
     75     gcd = 5,
     76 };
     77 
     78 pub const funcs: []const v.NativeFunction = &.{
     79     .{ .arity = 1, .name = "sqr", .code = sqr },
     80     .{ .arity = 1, .name = "sqrt", .code = sqrt },
     81     .{ .arity = 1, .name = "odd?", .code = isOdd },
     82     .{ .arity = 1, .name = "even?", .code = isEven },
     83     .{ .arity = 3, .name = "fma", .code = fma },
     84     .{ .arity = 2, .name = "gcd", .code = gcd },
     85 };
     86 
     87 pub inline fn getIntrinsic(index: mapping) v.NativeFunction {
     88     return funcs[@intFromEnum(index)];
     89 }