003 math builtins cross target

✓ Passing This code compiles and runs correctly.

Code

input.k

Actual

sin 0.4794 cos 0.8776 tan 0.5463
exp 2.7183 exp2 8.0000 log 2.3026 log2 3.0000 log10 3.0000
floor 1.0000 ceil 2.0000 trunc -1.0000 sqrt 1.4142 abs 3.5000
min 1.0000 max 2.5000

Expected output

✓ Zig✓ JavaScript✓ C#
sin 0.4794 cos 0.8776 tan 0.5463
exp 2.7183 exp2 8.0000 log 2.3026 log2 3.0000 log10 3.0000
floor 1.0000 ceil 2.0000 trunc -1.0000 sqrt 1.4142 abs 3.5000
min 1.0000 max 2.5000
Emitted Zig source
// Access compiler flags via the per-user compiler_env module
const CompilerEnv = @import("compiler_env").CompilerEnv;

pub const panic = if (@import("builtin").mode == .Debug)
    @import("std").debug.FullPanic(@import("std").debug.defaultPanic)
else
    @import("std").debug.simple_panic;


const __koru_bare = struct {
    extern fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
    extern fn free(ptr: ?*anyopaque) void;
    fn bareAlloc(_: *anyopaque, len: usize, alignment: @import("std").mem.Alignment, _: usize) ?[*]u8 {
        var p: ?*anyopaque = null;
        const a = @max(alignment.toByteUnits(), @sizeOf(usize));
        if (posix_memalign(&p, a, len) != 0) return null;
        return @ptrCast(p);
    }
    fn bareResize(_: *anyopaque, _: []u8, _: @import("std").mem.Alignment, _: usize, _: usize) bool { return false; }
    fn bareRemap(_: *anyopaque, _: []u8, _: @import("std").mem.Alignment, _: usize, _: usize) ?[*]u8 { return null; }
    fn bareFree(_: *anyopaque, memory: []u8, _: @import("std").mem.Alignment, _: usize) void { free(@ptrCast(memory.ptr)); }
    const vtable = @import("std").mem.Allocator.VTable{ .alloc = bareAlloc, .resize = bareResize, .remap = bareRemap, .free = bareFree };
    const allocator = @import("std").mem.Allocator{ .ptr = undefined, .vtable = &vtable };
};
const __koru_backing = if (@import("builtin").link_libc) @import("std").heap.c_allocator else if (@import("builtin").os.tag == .freestanding) __koru_bare.allocator else @import("std").heap.page_allocator;
var __koru_leak_count: @import("std").atomic.Value(usize) = .init(0);
fn __koru_alloc(ctx: *anyopaque, len: usize, alignment: @import("std").mem.Alignment, ret_addr: usize) ?[*]u8 {
    _ = ctx;
    const r = __koru_backing.rawAlloc(len, alignment, ret_addr);
    if (comptime @import("builtin").mode == .Debug) {
        if (r != null) _ = __koru_leak_count.fetchAdd(1, .monotonic);
    }
    return r;
}
fn __koru_resize(ctx: *anyopaque, memory: []u8, alignment: @import("std").mem.Alignment, new_len: usize, ret_addr: usize) bool {
    _ = ctx;
    return __koru_backing.rawResize(memory, alignment, new_len, ret_addr);
}
fn __koru_remap(ctx: *anyopaque, memory: []u8, alignment: @import("std").mem.Alignment, new_len: usize, ret_addr: usize) ?[*]u8 {
    _ = ctx;
    return __koru_backing.rawRemap(memory, alignment, new_len, ret_addr);
}
fn __koru_free(ctx: *anyopaque, memory: []u8, alignment: @import("std").mem.Alignment, ret_addr: usize) void {
    _ = ctx;
    __koru_backing.rawFree(memory, alignment, ret_addr);
    if (comptime @import("builtin").mode == .Debug) {
        _ = __koru_leak_count.fetchSub(1, .monotonic);
    }
}
const __koru_vtable = @import("std").mem.Allocator.VTable{ .alloc = __koru_alloc, .resize = __koru_resize, .remap = __koru_remap, .free = __koru_free };
pub fn koru_allocator() @import("std").mem.Allocator {
    return .{ .ptr = undefined, .vtable = &__koru_vtable };
}

pub inline fn __koru_intcast(comptime T: type, x: anytype) T {
    if (comptime (@import("builtin").mode == .Debug or @import("builtin").mode == .ReleaseSafe))
        return @as(T, @intCast(x));
    const dst = @typeInfo(T);
    const src = @typeInfo(@TypeOf(x));
    if (comptime (dst == .int and src == .int and dst.int.bits == src.int.bits and dst.int.signedness != src.int.signedness))
        return @as(T, @bitCast(x));
    return @as(T, @intCast(x));
}

pub fn koru_leak_check() void {
    if (comptime @import("builtin").mode != .Debug) return;
    if (__koru_leak_count.load(.acquire) == 0) return;
    if (comptime @import("builtin").target.os.tag == .freestanding) {
        if (comptime @import("builtin").cpu.arch == .wasm32 or @import("builtin").cpu.arch == .wasm64) {
            @panic("KORU LEAK CHECK FAILED: the produced program leaked");
        } else {
            const __klc = struct { extern var stdout: ?*anyopaque; extern fn fputs(__s: [*:0]const u8, __st: ?*anyopaque) c_int; };
            var __lb: [128]u8 = undefined;
            const __lm = "KORU LEAK CHECK FAILED: allocations still outstanding at end of run: ";
            @memcpy(__lb[0..__lm.len], __lm);
            var __ln: usize = __lm.len;
            var __lv = __koru_leak_count.load(.acquire);
            var __ld: [20]u8 = undefined;
            var __lk: usize = 0;
            while (__lv > 0) : (__lk += 1) { __ld[__lk] = @intCast('0' + __lv % 10); __lv /= 10; }
            for (0..__lk) |__li| { __lb[__ln] = __ld[__lk - 1 - __li]; __ln += 1; }
            __lb[__ln] = '\n'; __ln += 1; __lb[__ln] = 0;
            _ = __klc.fputs(@as([*:0]const u8, @ptrCast(&__lb)), __klc.stdout);
            @trap();
        }
    } else {
        @import("std").debug.print("KORU LEAK CHECK FAILED: the produced program leaked (trace above)\n", .{});
        @import("std").process.exit(1);
    }
}

pub const main_module = struct {
    // >>> FLOW: tests/regression/200_COMPILER_FEATURES/230_CODEGEN/230_003_math_builtins_cross_target/input.k:8  ~std.io:print.impl()
    pub fn flow0() void {
        (struct { fn __kout(__fd: i32, __b: []const u8) void { if (@import("builtin").os.tag == .freestanding) { const __kc = struct { extern var stdout: ?*anyopaque; extern var stderr: ?*anyopaque; extern fn fputs(__s: [*:0]const u8, __st: ?*anyopaque) c_int; }; var __kt: [4096]u8 = undefined; for (0..(__b.len + __kt.len - 2) / (__kt.len - 1)) |__ki| { const __kn = @min(__kt.len - 1, __b.len - __ki * (__kt.len - 1)); @memcpy(__kt[0..__kn], __b[__ki * (__kt.len - 1)..][0..__kn]); __kt[__kn] = 0; @import("std").mem.doNotOptimizeAway(__kc.fputs(@as([*:0]const u8, @ptrCast(&__kt)), if (__fd == 2) __kc.stderr else __kc.stdout)); } } else { @import("std").mem.doNotOptimizeAway(@import("std").posix.write(__fd, __b) catch @as(usize, 0)); } } fn __kw(comptime __f: []const u8, __a: anytype) void { var __kb: [65536]u8 = undefined; const __ks = @import("std").fmt.bufPrint(&__kb, __f, __a) catch __kb[0..0]; __kout(1, __ks); } }).__kw("sin {d:.4} cos {d:.4} tan {d:.4}\n", .{@sin(0.5), @cos(0.5), @tan(0.5)});
    }
    // >>> FLOW: tests/regression/200_COMPILER_FEATURES/230_CODEGEN/230_003_math_builtins_cross_target/input.k:9  ~std.io:print.impl()
    pub fn flow1() void {
        (struct { fn __kout(__fd: i32, __b: []const u8) void { if (@import("builtin").os.tag == .freestanding) { const __kc = struct { extern var stdout: ?*anyopaque; extern var stderr: ?*anyopaque; extern fn fputs(__s: [*:0]const u8, __st: ?*anyopaque) c_int; }; var __kt: [4096]u8 = undefined; for (0..(__b.len + __kt.len - 2) / (__kt.len - 1)) |__ki| { const __kn = @min(__kt.len - 1, __b.len - __ki * (__kt.len - 1)); @memcpy(__kt[0..__kn], __b[__ki * (__kt.len - 1)..][0..__kn]); __kt[__kn] = 0; @import("std").mem.doNotOptimizeAway(__kc.fputs(@as([*:0]const u8, @ptrCast(&__kt)), if (__fd == 2) __kc.stderr else __kc.stdout)); } } else { @import("std").mem.doNotOptimizeAway(@import("std").posix.write(__fd, __b) catch @as(usize, 0)); } } fn __kw(comptime __f: []const u8, __a: anytype) void { var __kb: [65536]u8 = undefined; const __ks = @import("std").fmt.bufPrint(&__kb, __f, __a) catch __kb[0..0]; __kout(1, __ks); } }).__kw("exp {d:.4} exp2 {d:.4} log {d:.4} log2 {d:.4} log10 {d:.4}\n", .{@exp(1.0), @exp2(3.0), @log(10.0), @log2(8.0), @log10(1000.0)});
    }
    // >>> FLOW: tests/regression/200_COMPILER_FEATURES/230_CODEGEN/230_003_math_builtins_cross_target/input.k:10  ~std.io:print.impl()
    pub fn flow2() void {
        (struct { fn __kout(__fd: i32, __b: []const u8) void { if (@import("builtin").os.tag == .freestanding) { const __kc = struct { extern var stdout: ?*anyopaque; extern var stderr: ?*anyopaque; extern fn fputs(__s: [*:0]const u8, __st: ?*anyopaque) c_int; }; var __kt: [4096]u8 = undefined; for (0..(__b.len + __kt.len - 2) / (__kt.len - 1)) |__ki| { const __kn = @min(__kt.len - 1, __b.len - __ki * (__kt.len - 1)); @memcpy(__kt[0..__kn], __b[__ki * (__kt.len - 1)..][0..__kn]); __kt[__kn] = 0; @import("std").mem.doNotOptimizeAway(__kc.fputs(@as([*:0]const u8, @ptrCast(&__kt)), if (__fd == 2) __kc.stderr else __kc.stdout)); } } else { @import("std").mem.doNotOptimizeAway(@import("std").posix.write(__fd, __b) catch @as(usize, 0)); } } fn __kw(comptime __f: []const u8, __a: anytype) void { var __kb: [65536]u8 = undefined; const __ks = @import("std").fmt.bufPrint(&__kb, __f, __a) catch __kb[0..0]; __kout(1, __ks); } }).__kw("floor {d:.4} ceil {d:.4} trunc {d:.4} sqrt {d:.4} abs {d:.4}\n", .{@floor(1.7), @ceil(1.2), @trunc(-1.7), @sqrt(2.0), @abs(-3.5)});
    }
    // >>> FLOW: tests/regression/200_COMPILER_FEATURES/230_CODEGEN/230_003_math_builtins_cross_target/input.k:11  ~std.io:print.impl()
    pub fn flow3() void {
        (struct { fn __kout(__fd: i32, __b: []const u8) void { if (@import("builtin").os.tag == .freestanding) { const __kc = struct { extern var stdout: ?*anyopaque; extern var stderr: ?*anyopaque; extern fn fputs(__s: [*:0]const u8, __st: ?*anyopaque) c_int; }; var __kt: [4096]u8 = undefined; for (0..(__b.len + __kt.len - 2) / (__kt.len - 1)) |__ki| { const __kn = @min(__kt.len - 1, __b.len - __ki * (__kt.len - 1)); @memcpy(__kt[0..__kn], __b[__ki * (__kt.len - 1)..][0..__kn]); __kt[__kn] = 0; @import("std").mem.doNotOptimizeAway(__kc.fputs(@as([*:0]const u8, @ptrCast(&__kt)), if (__fd == 2) __kc.stderr else __kc.stdout)); } } else { @import("std").mem.doNotOptimizeAway(@import("std").posix.write(__fd, __b) catch @as(usize, 0)); } } fn __kw(comptime __f: []const u8, __a: anytype) void { var __kb: [65536]u8 = undefined; const __ks = @import("std").fmt.bufPrint(&__kb, __f, __a) catch __kb[0..0]; __kout(1, __ks); } }).__kw("min {d:.4} max {d:.4}\n", .{@min(1.0, 2.5), @max(1.0, 2.5)});
    }
    pub fn koru_start_flow() void {
        const result_0 = koru_koru.start_event.handler(.{  });
        const result_0_done = result_0.done;
        _ = &result_0_done;
    }
    pub fn koru_end_flow() void {
        const result_0 = koru_koru.end_event.handler(.{  });
        const result_0_done = result_0.done;
        _ = &result_0_done;
    }
};

pub const koru_koru = struct {
    pub const start_event = struct {
        pub const Input = struct {
        };
        pub const Output = union(enum(u8)) {
            done: struct {
            },
        };
        pub fn handler(__koru_event_input: @This().Input) @This().Output {
            _ = &__koru_event_input;
            return .{ .done = .{} };
        }
    };
    pub const end_event = struct {
        pub const Input = struct {
        };
        pub const Output = union(enum(u8)) {
            done: struct {
            },
        };
        pub fn handler(__koru_event_input: @This().Input) @This().Output {
            _ = &__koru_event_input;
            return .{ .done = .{} };
        }
    };
};
pub fn main() void {
    main_module.koru_start_flow();
    main_module.flow0();
    main_module.flow1();
    main_module.flow2();
    main_module.flow3();
    main_module.koru_end_flow();
    if (comptime @import("builtin").mode == .Debug) koru_leak_check();
}

test {
    @import("std").testing.refAllDeclsRecursive(@This());
}
Emitted C# source
static class main_module {
  public static void __koru_stdout_write(dynamic s) => global::System.Console.Out.Write(s);
  public static void __koru_stderr_write(dynamic s) => global::System.Console.Error.Write(s);
  // The mutable handle carrier — `*String`-style resources are
  // `new __KoruBox { data = … }` because C# anonymous types are
  // read-only: `s.data = …` (std/string append/clear, handle
  // mutation generally) needs a settable member.
  public class __KoruBox { public dynamic data; }
  // Textification for `{{ … }}` operands: C# bool ToStrings as
  // `True` where Koru prints `true`, and the operand's static type
  // is unknown at this boundary — a `(x) is bool` inline test would
  // be a compile error on statically-typed operands instead. Generic
  // on purpose: `dynamic` boxed every value-type operand — measured
  // ~1s/10M elements on 012_threat_scanner — while T specializes to
  // the operand's own ToString() with no box.
  public static string __koru_str<T>(T v) => v is bool b ? (b ? "true" : "false") : v?.ToString();
  public static class std_io_print_impl_event {
    public struct Input {
      public dynamic expr;
    }
    public static dynamic handler(dynamic __koru_input) {
      throw new global::System.Exception("std.io:impl has no C# implementation — its body resolves only to a non-cs target (|zig / [comptime]), directly or through a callee");
    }
  }
  public static class koru_start_event {
    public struct Input {
    }
    public struct Output {
      public string tag;
      public dynamic done;
    }
    public static Output handler(Input __koru_input) => new Output { tag = "done" };
  }
  public static class koru_end_event {
    public struct Input {
    }
    public struct Output {
      public string tag;
      public dynamic done;
    }
    public static Output handler(Input __koru_input) => new Output { tag = "done" };
  }
  public static void flow0() {
__koru_stdout_write("sin " + (global::System.Math.Sin(0.5)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " cos " + (global::System.Math.Cos(0.5)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " tan " + (global::System.Math.Tan(0.5)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + "\n");
  }
  public static void flow1() {
__koru_stdout_write("exp " + (global::System.Math.Exp(1.0)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " exp2 " + (global::System.Math.Pow(2, 3.0)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " log " + (global::System.Math.Log(10.0)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " log2 " + (global::System.Math.Log2(8.0)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " log10 " + (global::System.Math.Log10(1000.0)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + "\n");
  }
  public static void flow2() {
__koru_stdout_write("floor " + (global::System.Math.Floor(1.7)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " ceil " + (global::System.Math.Ceiling(1.2)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " trunc " + (global::System.Math.Truncate(-1.7)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " sqrt " + (global::System.Math.Sqrt(2.0)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " abs " + (global::System.Math.Abs(-3.5)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + "\n");
  }
  public static void flow3() {
__koru_stdout_write("min " + (global::System.Math.Min(1.0, 2.5)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + " max " + (global::System.Math.Max(1.0, 2.5)).ToString("F4", global::System.Globalization.CultureInfo.InvariantCulture) + "\n");
  }
  public static void flow4() {
    main_module.koru_start_event.handler(new koru_start_event.Input { });
  }
  public static void flow5() {
    main_module.koru_end_event.handler(new koru_end_event.Input { });
  }
}

static class Program {
  static void Main() {
    main_module.flow4();
    main_module.flow0();
    main_module.flow1();
    main_module.flow2();
    main_module.flow3();
    main_module.flow5();
  }
}

Flows

flow ~print click a branch to expand · @labels scroll to their anchor
print (expr: "sin {{ @sin(0.5):d:.4 }} cos {{ @cos(0.5):d:.4 }} tan {{ @tan(0.5):d:.4 }}\n")
flow ~print click a branch to expand · @labels scroll to their anchor
print (expr: "exp {{ @exp(1.0):d:.4 }} exp2 {{ @exp2(3.0):d:.4 }} log {{ @log(10.0):d:.4 }} log2 {{ @log2(8.0):d:.4 }} log10 {{ @log10(1000.0):d:.4 }}\n")
flow ~print click a branch to expand · @labels scroll to their anchor
print (expr: "floor {{ @floor(1.7):d:.4 }} ceil {{ @ceil(1.2):d:.4 }} trunc {{ @trunc(-1.7):d:.4 }} sqrt {{ @sqrt(2.0):d:.4 }} abs {{ @abs(-3.5):d:.4 }}\n")
flow ~print click a branch to expand · @labels scroll to their anchor
print (expr: "min {{ @min(1.0, 2.5):d:.4 }} max {{ @max(1.0, 2.5):d:.4 }}\n")

Test Configuration

MUST_RUN LANGUAGES: zig js cs