const erl = @cImport({ @cInclude("erl_nif.h"); }); pub export fn hello(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{ _ = argv; _ = argc; //const ERL_NIF_LATIN1 = @as(c_uint, 1); return erl.enif_make_string(env, "Hello world!", 1); // ERL_NIF_LATIN1); } fn u128_to_buf(value: u128, buffer: *align(1) [40]u8) usize{ if(value == 0){ buffer[0] = '0'; return 1; } var i: usize = 0; var n = value; while(n > 0){ buffer[i] = @as(u8, @intCast('0' + (n % 10)) ); n /= 10; i += 1; } var j: usize = 0; while(j < i / 2) : (j += 1){ const temp = buffer[j]; buffer[j] = buffer[i - 1 - j]; buffer[i - 1 - j] = temp; } return i; } pub export fn factorial(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{ if(argc != 1){ return erl.enif_make_badarg(env); } var n: c_long = undefined; if(erl.enif_get_long(env, argv[0], &n) == 0 or n < 0){ return erl.enif_make_badarg(env); } if(n > 34){ // max n for max factorial for u128 return erl.enif_make_tuple2(env, erl.enif_make_atom(env, "error"), erl.enif_make_string(env, "input too large, max is 34", 1) ); } var result: u128 = 1; var i = @as(u128, @intCast(n) ); //var i = n; while(i > 1) : (i -= 1){ result *= i; } var buf: [40]u8 = undefined; const len = u128_to_buf(result, &buf); return erl.enif_make_string_len(env, buf[0..len].ptr, len, 1); // , ERL_NIF_LATIN1); } const nif_funcs = [_]erl.ErlNifFunc{ .{ .name = "hello", .arity = 0, .fptr = hello, .flags = 0, }, .{ .name = "factorial", .arity = 1, .fptr = factorial, .flags = 0, }, }; export fn nif_init() ?*erl.ErlNifEntry{ return &nif_entry; } var nif_entry: erl.ErlNifEntry = .{ .major = 2, .minor = 16, .name = "niftest", .num_of_funcs = nif_funcs.len, .funcs = @constCast(&nif_funcs), .load = null, .reload = null, .upgrade = null, .unload = null, .vm_variant = "beam.vanilla", .options = 1, // 0, .sizeof_ErlNifResourceTypeInit = @sizeOf(erl.ErlNifResourceTypeInit), .min_erts = "erts-12.0", // .entry_version = 3, };