niftest.zig 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. const erl = @cImport({
  2. @cInclude("erl_nif.h");
  3. });
  4. pub export fn hello(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{
  5. _ = argv;
  6. _ = argc;
  7. //const ERL_NIF_LATIN1 = @as(c_uint, 1);
  8. return erl.enif_make_string(env, "Hello world!", 1); // ERL_NIF_LATIN1);
  9. }
  10. fn u128_to_buf(value: u128, buffer: *align(1) [40]u8) usize{
  11. if(value == 0){
  12. buffer[0] = '0';
  13. return 1;
  14. }
  15. var i: usize = 0;
  16. var n = value;
  17. while(n > 0){
  18. buffer[i] = @as(u8, @intCast('0' + (n % 10)) );
  19. n /= 10;
  20. i += 1;
  21. }
  22. var j: usize = 0;
  23. while(j < i / 2) : (j += 1){
  24. const temp = buffer[j];
  25. buffer[j] = buffer[i - 1 - j];
  26. buffer[i - 1 - j] = temp;
  27. }
  28. return i;
  29. }
  30. pub export fn factorial(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{
  31. if(argc != 1){
  32. return erl.enif_make_badarg(env);
  33. }
  34. var n: c_long = undefined;
  35. if(erl.enif_get_long(env, argv[0], &n) == 0 or n < 0){
  36. return erl.enif_make_badarg(env);
  37. }
  38. if(n > 34){ // max n for max factorial for u128
  39. return erl.enif_make_tuple2(env,
  40. erl.enif_make_atom(env, "error"),
  41. erl.enif_make_string(env, "input too large, max is 34", 1)
  42. );
  43. }
  44. var result: u128 = 1;
  45. var i = @as(u128, @intCast(n) );
  46. //var i = n;
  47. while(i > 1) : (i -= 1){
  48. result *= i;
  49. }
  50. var buf: [40]u8 = undefined;
  51. const len = u128_to_buf(result, &buf);
  52. return erl.enif_make_string_len(env, buf[0..len].ptr, len, 1); // , ERL_NIF_LATIN1);
  53. }
  54. const nif_funcs = [_]erl.ErlNifFunc{
  55. .{
  56. .name = "hello",
  57. .arity = 0,
  58. .fptr = hello,
  59. .flags = 0,
  60. },
  61. .{
  62. .name = "factorial",
  63. .arity = 1,
  64. .fptr = factorial,
  65. .flags = 0,
  66. },
  67. };
  68. export fn nif_init() ?*erl.ErlNifEntry{
  69. return &nif_entry;
  70. }
  71. var nif_entry: erl.ErlNifEntry = .{
  72. .major = 2,
  73. .minor = 16,
  74. .name = "niftest",
  75. .num_of_funcs = nif_funcs.len,
  76. .funcs = @constCast(&nif_funcs),
  77. .load = null,
  78. .reload = null,
  79. .upgrade = null,
  80. .unload = null,
  81. .vm_variant = "beam.vanilla",
  82. .options = 1, // 0,
  83. .sizeof_ErlNifResourceTypeInit = @sizeOf(erl.ErlNifResourceTypeInit),
  84. .min_erts = "erts-12.0", // .entry_version = 3,
  85. };