diff --git a/kinda_example/lib/kinda_example_native.ex b/kinda_example/lib/kinda_example_native.ex new file mode 100644 index 0000000..5f511f8 --- /dev/null +++ b/kinda_example/lib/kinda_example_native.ex @@ -0,0 +1,17 @@ +defmodule KindaExample.Native do + def check!({:kind, mod, ref}) when is_atom(mod) and is_reference(ref) do + struct!(mod, %{ref: ref}) + end + + def check!({:error, e}), do: raise(e) + def check!(ret), do: ret + + def to_term(%mod{ref: ref}) do + forward(mod, :primitive, [ref]) + end + + def forward(element_kind, kind_func_name, args) do + apply(KindaExample.NIF, Module.concat(element_kind, kind_func_name), args) + |> check!() + end +end diff --git a/kinda_example/lib/kinda_exmaple_nif.ex b/kinda_example/lib/kinda_example_nif.ex similarity index 84% rename from kinda_example/lib/kinda_exmaple_nif.ex rename to kinda_example/lib/kinda_example_nif.ex index 89d870d..168f522 100644 --- a/kinda_example/lib/kinda_exmaple_nif.ex +++ b/kinda_example/lib/kinda_example_nif.ex @@ -4,8 +4,7 @@ defmodule KindaExample.NIF do root: __MODULE__, forward: KindaExample.Native defmodule CInt do - use Kinda.ResourceKind, - forward_module: KindaExample.Native + use Kinda.ResourceKind, forward_module: KindaExample.Native end for path <- @@ -16,6 +15,10 @@ defmodule KindaExample.NIF do @external_resource path end + defmodule StrInt do + use Kinda.ResourceKind, forward_module: KindaExample.Native + end + @on_load :load_nif def load_nif do diff --git a/kinda_example/lib/kinda_exmaple_native.ex b/kinda_example/lib/kinda_exmaple_native.ex deleted file mode 100644 index 037fd45..0000000 --- a/kinda_example/lib/kinda_exmaple_native.ex +++ /dev/null @@ -1,27 +0,0 @@ -defmodule KindaExample.Native do - def check!(ret) do - case ret do - {:kind, mod, ref} when is_atom(mod) and is_reference(ref) -> - struct!(mod, %{ref: ref}) - - {:error, e} -> - raise e - - _ -> - ret - end - end - - def to_term(%mod{ref: ref}) do - forward(mod, :primitive, [ref]) - end - - def forward( - element_kind, - kind_func_name, - args - ) do - apply(KindaExample.NIF, Module.concat(element_kind, kind_func_name), args) - |> check!() - end -end diff --git a/kinda_example/test/kinda_example_test.exs b/kinda_example/test/kinda_example_test.exs index 72d5c49..be558dc 100644 --- a/kinda_example/test/kinda_example_test.exs +++ b/kinda_example/test/kinda_example_test.exs @@ -1,29 +1,27 @@ defmodule KindaExampleTest do use ExUnit.Case + alias KindaExample.{NIF, Native} + test "add in c" do assert 3 == - KindaExample.NIF.kinda_example_add(1, 2) - |> KindaExample.Native.to_term() + NIF.kinda_example_add(1, 2) |> Native.to_term() assert match?( %Kinda.CallError{message: "Fail to fetch argument #2", error_return_trace: _}, - catch_error(KindaExample.NIF.kinda_example_add(1, "2")) + catch_error(NIF.kinda_example_add(1, "2")) ) end test "custom make" do - assert KindaExample.Native.forward( - KindaExample.NIF.CInt, - :make, - [100] - ) - |> KindaExample.NIF."Elixir.KindaExample.NIF.CInt.primitive"() == 100 + assert 100 == + Native.forward(NIF.CInt, :make, [100]) + |> NIF."Elixir.KindaExample.NIF.CInt.primitive"() - e = catch_error(KindaExample.NIF."Elixir.KindaExample.NIF.StrInt.make"(1)) + e = catch_error(NIF."Elixir.KindaExample.NIF.StrInt.make"(1)) assert Exception.message(e) =~ "Function clause error\n#{IO.ANSI.reset()}" - err = catch_error(KindaExample.NIF."Elixir.KindaExample.NIF.StrInt.make"(1)) + err = catch_error(NIF."Elixir.KindaExample.NIF.StrInt.make"(1)) # only test this on macOS, it will crash on Linux txt = Exception.message(err) @@ -36,8 +34,11 @@ defmodule KindaExampleTest do assert match?(%Kinda.CallError{message: "Function clause error", error_return_trace: _}, err) - assert KindaExample.NIF."Elixir.KindaExample.NIF.StrInt.make"("1") - |> KindaExample.NIF."Elixir.KindaExample.NIF.CInt.primitive"() == - 1 + assert 1 == + NIF."Elixir.KindaExample.NIF.StrInt.make"("1") + |> NIF."Elixir.KindaExample.NIF.CInt.primitive"() + + %NIF.StrInt{ref: ref} = NIF.StrInt.make("1") + assert 1 == ref |> NIF."Elixir.KindaExample.NIF.CInt.primitive"() end end diff --git a/lib/codegen/kind_decl.ex b/lib/codegen/kind_decl.ex index 89b39f1..eea4f7e 100644 --- a/lib/codegen/kind_decl.ex +++ b/lib/codegen/kind_decl.ex @@ -1,7 +1,7 @@ defmodule Kinda.CodeGen.KindDecl do require Logger - @primitive_types for t <- ~w{ + @primitive_types ~w{ bool c_int c_uint @@ -17,8 +17,7 @@ defmodule Kinda.CodeGen.KindDecl do u64 u8 usize - }, - do: String.to_atom(t) + }a @opaque_ptr {:optional_type, {:ref, [:*, :anyopaque]}} @opaque_array {:optional_type, {:ref, [:*, :const, :anyopaque]}} diff --git a/lib/kinda_codegen.ex b/lib/kinda_codegen.ex index 5b6cce9..038ebb2 100644 --- a/lib/kinda_codegen.ex +++ b/lib/kinda_codegen.ex @@ -16,7 +16,7 @@ defmodule Kinda.CodeGen do end end - @callback kinds() :: KindDecl.t() + @callback kinds() :: [KindDecl.t()] @callback nifs() :: [{atom(), integer()}] def kinds(), do: []