Sha256: 3ec74ab7e493583dcb8e11a72df323a3572521fdc2797c6d5912f644aa0e93ad

Contents?: true

Size: 1.03 KB

Versions: 8

Compression:

Stored size: 1.03 KB

Contents

const std = @import("std");
const ruby = @cImport(@cInclude("ruby/ruby.h"));
const testing = std.testing;

// https://rosettacode.org/wiki/Ackermann_function#Zig
pub fn ack(m: c_int, n: c_int) c_int {
    if (m == 0) return n + 1;
    if (n == 0) return ack(m - 1, 1);
    return ack(m - 1, ack(m, n - 1));
}

fn rb_ack(...) callconv(.C) ruby.VALUE {
    var ap = @cVaStart();
    defer @cVaEnd(&ap);

    // first argument is `self` in ruby; discard it
    var self = @cVaArg(&ap, ruby.VALUE); _ = self;

    // back and forth type conversions + delegation
    var m = ruby.NUM2INT(@cVaArg(&ap, ruby.VALUE));
    var n = ruby.NUM2INT(@cVaArg(&ap, ruby.VALUE));
    return ruby.INT2NUM(ack(m, n));
}

export fn Init_libzigrb_ackermann() void {
    ruby.ruby_init();
    var zig_rb_class: ruby.VALUE = ruby.rb_define_class("ZigExample", ruby.rb_cObject);
    _ = ruby.rb_define_method(zig_rb_class, "ack", rb_ack, 2);
}

test "ack(0, 0) passes" {
    try testing.expect(ack(0, 0) == 1);
}

test "ack(3, 4) passes" {
    try testing.expect(ack(3, 4) == 125);
}

Version data entries

8 entries across 8 versions & 1 rubygems

Version Path
zig_example-0.4.0 ext/zigrb_ackermann/src/main.zig
zig_example-0.4.0.pre ext/zigrb_ackermann/src/main.zig
zig_example-0.3.4 ext/zigrb_ackermann/src/main.zig
zig_example-0.3.3.1 ext/zigrb_ackermann/src/main.zig
zig_example-0.3.2 ext/zigrb_ackermann/src/main.zig
zig_example-0.3.1 ext/zigrb_ackermann/src/main.zig
zig_example-0.3.0 ext/zigrb_ackermann/src/main.zig
zig_example-0.2.0 ext/zigrb_ackermann/src/main.zig