Skip to content

Commit

Permalink
makes more tests pass, up to marshalling
Browse files Browse the repository at this point in the history
  • Loading branch information
ityonemo committed Apr 26, 2024
1 parent fc83f19 commit b4cb211
Show file tree
Hide file tree
Showing 17 changed files with 404 additions and 348 deletions.
4 changes: 2 additions & 2 deletions lib/zig/sema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ defmodule Zig.Sema do

defp integrate_sema(%{"functions" => functions, "types" => types, "decls" => decls}, module) do
%__MODULE__{
functions: Enum.map(functions, &Function.from_json(&1, module)),
types: Enum.map(types, &type_from_json(&1, module)),
functions: Enum.map(functions, &Function.from_json(&1, module.module)),
types: Enum.map(types, &type_from_json(&1, module.module)),
decls: Enum.map(decls, &const_from_json/1)
}
end
Expand Down
2 changes: 1 addition & 1 deletion lib/zig/templates/basic.zig.eex
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn <%= @name %>(env: beam.env, argc: c_int, args: [*c] const e.ErlNifTerm) callc
return result_block: {
const payload_opts = .{
<%= for {index, param} <- @params do %>
<%= Type.render_payload_entry(param, index, needs_make?) %>
<%= Type.render_payload_options(param, index, needs_make?) %>
<% end %>
};

Expand Down
23 changes: 19 additions & 4 deletions lib/zig/type.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,15 @@ defprotocol Zig.Type do
def return_allowed?(type)

# rendered zig code:
@spec render_payload_entry(t, non_neg_integer, boolean) :: iodata
def render_payload_entry(type, index, error_info?)
@spec render_payload_options(t, non_neg_integer, boolean) :: iodata
def render_payload_options(type, index, error_info?)

@spec render_return(t) :: iodata
def render_return(type)

@spec render_zig(t) :: String.T
def render_zig(type)

@typep spec_context :: :param | :return
@spec spec(t, spec_context, keyword) :: Macro.t()
def spec(type, context, opts)
Expand Down Expand Up @@ -225,11 +228,13 @@ after

# defaults

def _default_payload_entry, do: ".{.error_info = &error_info},"
def _default_payload_options, do: ".{.error_info = &error_info},"
def _default_return, do: "break :result_block beam.make(result, .{}).v;"
end

defimpl Zig.Type, for: Atom do

Check warning on line 235 in lib/zig/type.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 25.0 / Elixir 1.13.4

function render_zig/1 required by protocol Zig.Type is not implemented (in module Zig.Type.Atom)

Check warning on line 235 in lib/zig/type.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

function render_zig/1 required by protocol Zig.Type is not implemented (in module Zig.Type.Atom)

Check warning on line 235 in lib/zig/type.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

function render_zig/1 required by protocol Zig.Type is not implemented (in module Zig.Type.Atom)

Check warning on line 235 in lib/zig/type.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.14.5

function render_zig/1 required by protocol Zig.Type is not implemented (in module Zig.Type.Atom)
alias Zig.Type

def marshals_param?(_), do: false
def marshals_return?(_), do: false

Expand All @@ -238,7 +243,17 @@ defimpl Zig.Type, for: Atom do

def return_allowed?(type), do: type in ~w(term erl_nif_term pid void)a

def render_return(:void), do: ""
def render_return(:void), do: "_ = result; break :result_block beam.make(.ok, .{}).v;"
def render_return(_), do: Type._default_return()

def render_payload_options(:erl_nif_term, _, _), do: ".{}"
def render_payload_options(:term, _, _), do: ".{}"

def render_payload_options(type, _, _)
when type in ~w[env stacktrace erl_nif_binary erl_nif_event erl_nif_binary_pointer]a,
do: raise("unreachable")

def render_payload_options(_, _, _), do: Type._default_payload_options()

def spec(:void, :return, _), do: :ok

Expand Down
9 changes: 3 additions & 6 deletions lib/zig/type/array.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ defmodule Zig.Type.Array do
}
end

def return_allowed?(array), do: Type.return_allowed?(array.child)
def marshals_param?(_), do: false
def marshals_return?(_), do: false

def return_allowed?(array), do: Type.return_allowed?(array.child)
def render_payload_options(type, index, _), do: Type._default_payload_options()
def render_return(type), do: Type._default_return()

def spec(%{child: ~t(u8)} = type, :return, opts) do
# u8 defaults to binary
Expand Down Expand Up @@ -113,8 +114,4 @@ defmodule Zig.Type.Array do
def of(type, len, opts \\ []) do
struct(__MODULE__, opts ++ [child: type, len: len])
end

def render_payload_entry(type, index, _), do: Type._default_payload_entry()

def render_return(type), do: Type._default_return()
end
6 changes: 6 additions & 0 deletions lib/zig/type/bool.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,11 @@ defmodule Zig.Type.Bool do

def return_allowed?(_), do: true

def render_payload_options(type, index, _), do: Type._default_payload_options()
def render_return(type), do: Type._default_return()

def marshals_param?(_), do: false
def marshals_return?(_), do: false

def spec(_, _, _), do: Type.spec(:boolean)
end
6 changes: 6 additions & 0 deletions lib/zig/type/cpointer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ defmodule Zig.Type.Cpointer do
end
end

def marshals_param?(_), do: false
def marshals_return?(_), do: false

def render_payload_options(type, index, _), do: Type._default_payload_options()
def render_return(type), do: Type._default_return()

def spec(%{child: child}, :param, _opts) do
has_solo? = match?(%Type.Struct{extern: true}, child)
child_form = Type.spec(child, :param, [])
Expand Down
9 changes: 8 additions & 1 deletion lib/zig/type/enum.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule Zig.Type.Enum do
use Zig.Type
alias Zig.Type
use Type

defstruct [:tags, :name]
@type t :: %__MODULE__{tags: %{optional(atom) => String.t()}, name: String.t()}
Expand All @@ -17,6 +18,12 @@ defmodule Zig.Type.Enum do

def return_allowed?(_), do: true

def marshals_param?(_), do: false
def marshals_return?(_), do: false

def render_payload_options(type, index, _), do: Type._default_payload_options()
def render_return(type), do: Type._default_return()

def spec(%{tags: tags}, _, _opts) do
tags
|> Map.keys()
Expand Down
4 changes: 4 additions & 0 deletions lib/zig/type/float.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ defmodule Zig.Type.Float do
def spec(_, _, _), do: Type.spec(:float)

def return_allowed?(_), do: true
def marshals_param?(_), do: false
def marshals_return?(_), do: false
def render_payload_options(type, index, _), do: Type._default_payload_options()
def render_return(type), do: Type._default_return()
end
12 changes: 11 additions & 1 deletion lib/zig/type/integer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ defmodule Zig.Type.Integer do

def parse(other), do: raise(Zig.Type.ParseError, source: other)

def render_zig(%{bits: :big}), do: raise("not supported yet")
def render_zig(%{signedness: :unsigned, bits: bits}), do: "u#{bits}"
def render_zig(%{signedness: :signed, bits: bits}), do: "i#{bits}"

@signs %{"signed" => :signed, "unsigned" => :unsigned}
def from_json(%{"signedness" => s, "bits" => b}) do
%__MODULE__{signedness: Map.fetch!(@signs, s), bits: b}
Expand Down Expand Up @@ -65,7 +69,7 @@ defmodule Zig.Type.Integer do
guards =
quote bind_quoted: [
variable: variable,
name: to_string(type),
name: Type.render_zig(type),
index: index,
max: max,
min: min
Expand Down Expand Up @@ -219,4 +223,10 @@ defmodule Zig.Type.Integer do
def return_allowed?(_), do: true

def render_return(type), do: Type._default_return()

def marshals_param?(%{bits: bits}), do: bits > 64
def marshals_return?(%{bits: bits}), do: bits > 64

def render_payload_options(type, index, _), do: Type._default_payload_options()
def render_return(type), do: Type._default_return()
end
5 changes: 5 additions & 0 deletions lib/zig/type/manypointer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ defmodule Zig.Type.Manypointer do
def return_allowed?(pointer), do: pointer.has_sentinel? and Type.return_allowed?(pointer.child)
def missing_size?(_), do: true

def marshals_param?(_), do: false
def marshals_return?(_), do: false
def render_payload_options(type, index, _), do: Type._default_payload_options()
def render_return(type), do: Type._default_return()

# only manypointers of [*:0]u8 are allowed to be returned.
def spec(%{child: ~t(u8), has_sentinel?: true}, :return, opts) do
case Keyword.fetch!(opts, :type) do
Expand Down
6 changes: 6 additions & 0 deletions lib/zig/type/optional.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ defmodule Zig.Type.Optional do

def return_allowed?(optional), do: Type.return_allowed?(optional.child)

def marshals_param?(_), do: false
def marshals_return?(_), do: false

def render_payload_options(type, index, _), do: Type._default_payload_options()

Check warning on line 17 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 25.0 / Elixir 1.13.4

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.14.5

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)
def render_return(type), do: Type._default_return()

Check warning on line 18 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 18 in lib/zig/type/optional.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

def spec(%{child: child}, context, opts) do
quote do
unquote(Type.spec(child, context, opts)) | nil
Expand Down
4 changes: 4 additions & 0 deletions lib/zig/type/slice.ex
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ defmodule Zig.Type.Slice do
# ETC

def return_allowed?(slice), do: Type.return_allowed?(slice.child)
def marshals_param?(_), do: false
def marshals_return?(_), do: false
def render_payload_options(type, index, _), do: Type._default_payload_options()
def render_return(type), do: Type._default_return()

def of(child, opts \\ []), do: struct(__MODULE__, [child: child] ++ opts)
end
5 changes: 5 additions & 0 deletions lib/zig/type/struct.ex
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,9 @@ defmodule Zig.Type.Struct do
|> Enum.map(&Type.return_allowed?/1)
|> Enum.all?()
end

def marshals_param?(_), do: false
def marshals_return?(_), do: false
def render_payload_options(type, index, _), do: Type._default_payload_options()

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 25.0 / Elixir 1.13.4

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 25.0 / Elixir 1.13.4

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.14.5

variable "index" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 124 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.14.5

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)
def render_return(type), do: Type._default_return()

Check warning on line 125 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 25.0 / Elixir 1.13.4

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 125 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 125 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 125 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.15.2

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 125 in lib/zig/type/struct.ex

View workflow job for this annotation

GitHub Actions / Linux OTP 26.0 / Elixir 1.14.5

variable "type" is unused (if the variable is not meant to be used, prefix it with an underscore)
end
Loading

0 comments on commit b4cb211

Please sign in to comment.