diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3cef7be --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +zig-cache/ diff --git a/README.md b/README.md index 9b1e792..f111c52 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ # zigrlang -experimenting zig and erlang together, something like rustler? \ No newline at end of file +**THIS DOES NOT WORK (yet, i suppose)** + +i tried to slap zig and erlang nifs together, didn't work well +mostly because erlang nifs use c macros that are hell on earth to understand +and i reached a `TODO` on zig's translate-c which means i won't be really able +to do many things with this until translate-c is more feature-complete, or +translate-c-2, you get the point. diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..c95549c --- /dev/null +++ b/build.zig @@ -0,0 +1,26 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + const lib = b.addSharedLibrary( + "zigrlang", + "src/main.zig", + b.version(0, 0, 1), + ); + + var step = &lib.step; + + lib.setBuildMode(mode); + + lib.linkSystemLibrary("c"); + lib.addIncludeDir("/lib/erlang/erts-10.4/include"); + + var main_tests = b.addTest("src/main.zig"); + main_tests.setBuildMode(mode); + + const test_step = b.step("test", "Run library tests"); + test_step.dependOn(&main_tests.step); + + b.default_step.dependOn(step); + b.installArtifact(lib); +} diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..c46515c --- /dev/null +++ b/src/main.zig @@ -0,0 +1,64 @@ +const std = @import("std"); +const testing = std.testing; + +const c = @cImport({ + @cInclude("erl_nif.h"); +}); + +// https://andrealeopardi.com/posts/using-c-from-elixir-with-nifs/ + +export fn fast_compare( + env: ?*c.ErlNifEnv, + argc: c_int, + argv: [*c]const c.ERL_NIF_TERM, +) c.ERL_NIF_TERM { + // cool stuff here + var a: c_int = undefined; + var b: c_int = undefined; + var res: c_int = undefined; + + _ = c.enif_get_int(env, argv[0], &a); + _ = c.enif_get_int(env, argv[1], &b); + + if (a == b) { + res = 0; + } else { + if (a > b) { + res = 1; + } else { + res = -1; + } + } + + return c.enif_make_int(env, res); +} + +// this can't be saved +// i hand-translated the ERL_NIF_INIT macro manually, still reached some +// bad spots. +var nif_funcs = []c.ErlNifFunc{c.ErlNifFunc{ + .name = c"fast_compare", + .arity = 2, + .fptr = fast_compare, + .flags = 0, +}}; + +export fn nif_init() *c.ErlNifEntry { + comptime var entry: c.ErlNifEntry = c.ErlNifEntry{ + .major = 10, + .minor = 4, + .name = c"Elixir.FastCompare", + .num_of_funcs = nif_funcs.len, + .funcs = @ptrCast([*c]c.ErlNifFunc, &nif_funcs), + .load = null, + .reload = null, + .upgrade = null, + .unload = null, + .vm_variant = c"beam.vanilla", + .options = 1, + .sizeof_ErlNifResourceTypeInit = @sizeOf(c.ErlNifResourceTypeInit), + .min_erts = c"erts-10.4", + }; + + return &entry; +}