Skip to content

Commit

Permalink
Add tuple varargs encode
Browse files Browse the repository at this point in the history
  • Loading branch information
wltsmrz committed Oct 20, 2019
1 parent e402e4c commit 0d45bf1
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 7 deletions.
4 changes: 2 additions & 2 deletions bindings/erl_nif.nim
Expand Up @@ -134,8 +134,8 @@ proc enif_make_string*(a1: ptr ErlNifEnv; string: cstring; a3: ErlNifCharEncodin
proc enif_make_string_len*(a1: ptr ErlNifEnv; string: cstring; a2: csize; a3: ErlNifCharEncoding): ErlNifTerm {. importc: "enif_make_string_len", header: "erl_nif.h".}
proc enif_make_ref*(a1: ptr ErlNifEnv): ErlNifTerm {.importc: "enif_make_ref", header: "erl_nif.h".}
proc enif_make_uint*(a1: ptr ErlNifEnv; a2: cuint): ErlNifTerm {.importc: "enif_make_uint", header: "erl_nif.h".}
proc enif_make_tuple_from_array*(a1: ptr ErlNifEnv; a2: ptr ErlNifTerm; a3: cuint): ErlNifTerm {. importc: "enif_make_tuple_from_array", header: "erl_nif.h".}
proc enif_make_list_from_array*(a1: ptr ErlNifEnv; a2: ptr ErlNifTerm; a3: cuint): ErlNifTerm {.importc: "enif_make_list_from_array", header: "erl_nif.h".}
proc enif_make_tuple_from_array*(a1: ptr ErlNifEnv; a2: openArray[ErlNifTerm]): ErlNifTerm {. importc: "enif_make_tuple_from_array", header: "erl_nif.h".}
proc enif_make_list_from_array*(a1: ptr ErlNifEnv; a2: openArray[ErlNifTerm]): ErlNifTerm {.importc: "enif_make_list_from_array", header: "erl_nif.h".}
proc enif_make_new_binary*(a1: ptr ErlNifEnv; a2: csize; a3: ptr ErlNifTerm): ptr cuchar {.importc: "enif_make_new_binary", header: "erl_nif.h".}
proc enif_system_info*(a1: ptr ErlNifSysInfo; a2: csize) {.importc: "enif_system_info", header: "erl_nif.h".}
proc enif_raise_exception*(a1: ptr ErlNifEnv; a2: ErlNifTerm): ErlNifTerm {.importc: "enif_raise_exception", header: "erl_nif.h".}
Expand Down
11 changes: 11 additions & 0 deletions codec.nim
Expand Up @@ -5,6 +5,8 @@ export options

type ErlAtom* = Buffer
type ErlResult* = tuple[rtype: ErlAtom, rval: ErlNifTerm]
type ErlTuple* = varargs[ErlNifTerm]
type ErlList* = openArray[ErlNifTerm]

const AtomOk* = cast[ErlAtom]("ok")
const AtomErr* = cast[ErlAtom]("error")
Expand Down Expand Up @@ -51,3 +53,12 @@ proc encode*(V: ErlResult, env: ptr ErlNifEnv): ErlNifTerm =
let rtype = enif_make_atom(env, V.rtype)
return enif_make_tuple(env, arity, rtype, V.rval)

########## tuple ##########
proc encode*(V: ErlTuple, env: ptr ErlNifEnv): ErlNifTerm =
return enif_make_tuple_from_array(env, V)

########## list ##########
proc encode*(V: ErlList, env: ptr ErlNifEnv): ErlNifTerm =
return enif_make_list_from_array(env, V)


18 changes: 18 additions & 0 deletions tests/codec/nif.nim
Expand Up @@ -16,6 +16,22 @@ proc codec_atom(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
let a1 = argv[0].decode(env, ErlAtom).get()
return a1.encode(env)

proc codec_varargs_tuple(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
return encode(
enif_make_int(env, cint(1)),
enif_make_int(env, cint(2)),
enif_make_int(env, cint(3)),
env)

proc codec_list(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
return enif_make_int(env, 1)
# pending disambiguation between varargs and openArray
# return encode(ErlList([
# enif_make_int(env, cint(1)),
# enif_make_int(env, cint(2)),
# enif_make_int(env, cint(3)),
# ]), env)

proc codec_result_ok(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
return ResultOk(argv[0]).encode(env)

Expand All @@ -26,6 +42,8 @@ export_nifs("Elixir.NimlerWrapper", @[
("codec_int32", 2, codec_int32),
("codec_uint32", 2, codec_uint32),
("codec_atom", 1, codec_atom),
("codec_varargs_tuple", 0, codec_varargs_tuple),
("codec_list", 0, codec_list),
("codec_result_ok", 1, codec_result_ok),
("codec_result_error", 1, codec_result_error)
])
Expand Down
8 changes: 8 additions & 0 deletions tests/codec/test.exs
Expand Up @@ -29,10 +29,18 @@ defmodule NimlerTest do
end

describe "codec_tuples" do
test "codec_varargs_tuple()", do:
assert({1,2,3} == NimlerWrapper.codec_varargs_tuple())
test "codec_result()", do:
assert({:ok, 1} == NimlerWrapper.codec_result_ok(1))
test "codec_result_err()", do:
assert({:error, 1} == NimlerWrapper.codec_result_error(1))
end

describe "codec_list" do
@tag :skip
test "codec_list()", do:
assert([1,2,3] == NimlerWrapper.codec_list())
end
end

2 changes: 2 additions & 0 deletions tests/codec/wrapper.ex
Expand Up @@ -5,6 +5,8 @@ defmodule NimlerWrapper do
def codec_int32(_a, _b), do: raise "not implemented"
def codec_uint32(_a, _b), do: raise "not implemented"
def codec_atom(_a), do: raise "not implemented"
def codec_varargs_tuple(), do: raise "not implemented"
def codec_result_ok(_a), do: raise "not implemented"
def codec_result_error(_a), do: raise "not implemented"
def codec_list(), do: raise "not implemented"
end
4 changes: 2 additions & 2 deletions tests/dirty_nif/nif.nim
Expand Up @@ -2,11 +2,11 @@ import os
import ../../nimler

proc dirty_cpu(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
os.sleep(1000)
os.sleep(100)
return enif_make_int(env, 1)

proc dirty_io(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
os.sleep(1000)
os.sleep(100)
return enif_make_int(env, 1)

export_nifs("Elixir.NimlerWrapper", [
Expand Down
11 changes: 9 additions & 2 deletions tests/integration/nif.nim
Expand Up @@ -254,6 +254,13 @@ proc make_tuple(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =

return enif_make_tuple(env, tuple_len, t1, t2, t3)

proc make_tuple_from_array(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
return enif_make_tuple_from_array(env, [
enif_make_int(env, cint(1)),
enif_make_int(env, cint(2)),
enif_make_int(env, cint(3))
])

proc make_int(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
return enif_make_int(env, cint(1))

Expand Down Expand Up @@ -347,9 +354,8 @@ proc make_list_from_array(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): Erl
enif_make_int(env, cint(1)),
enif_make_int(env, cint(2))
]
let v = cast[ptr ErlNifTerm](unsafeAddr(values))

return enif_make_list_from_array(env, v, cuint(2))
return enif_make_list_from_array(env, values)

proc make_reverse_list(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
let l1 = make_list(env, argc, argv)
Expand Down Expand Up @@ -435,6 +441,7 @@ export_nifs("Elixir.NimlerWrapper", @[
("enif_make_list_from_array", 0, make_list_from_array),
("enif_make_reverse_list", 0, make_reverse_list),
("enif_make_tuple", 0, make_tuple),
("enif_make_tuple_from_array", 0, make_tuple_from_array),
("enif_make_int", 0, make_int),
("enif_make_long", 0, make_long),
("enif_make_int64", 0, make_int64),
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/test.exs
Expand Up @@ -75,6 +75,8 @@ defmodule NimlerTest do
assert(:test == NimlerWrapper.enif_make_existing_atom_len())
test "make_tuple()", do:
assert({1,2,3} == NimlerWrapper.enif_make_tuple())
test "make_tuple_from_array()", do:
assert({1,2,3} == NimlerWrapper.enif_make_tuple())
test "make_int()", do:
assert(1 == NimlerWrapper.enif_make_int())
test "make_long()", do:
Expand Down
1 change: 1 addition & 0 deletions tests/integration/wrapper.ex
Expand Up @@ -35,6 +35,7 @@ defmodule NimlerWrapper do
def enif_make_list_cell(), do: raise "not implemented"
def enif_make_list_from_array(), do: raise "not implemented"
def enif_make_tuple(), do: raise "not implemented"
def enif_make_tuple_from_array(), do: raise "not implemented"
def enif_make_new_binary(), do: raise "not implemented"
def enif_make_new_map(), do: raise "not implemented"
def enif_make_map_from_arrays(), do: raise "not implemented"
Expand Down
3 changes: 2 additions & 1 deletion tests/resource/nif.nim
@@ -1,9 +1,10 @@
import sharedtables
import ../../nimler

type MyResource = object
thing: int32

var resource_types: seq[pointer] = @[]
var resource_types {.global.}: seq[pointer] = @[]

proc create_resource(env: ptr ErlNifEnv, argc: cint, argv: ErlNifArgs): ErlNifTerm =
let my_resource = MyResource(thing: 123)
Expand Down

0 comments on commit 0d45bf1

Please sign in to comment.