Current section
Files
Jump to
Current section
Files
lib/rex.ex
defmodule Rex do
defmacro __using__(_) do
quote do
import Rex
import Rex.Stack
import Rex.Control
import Rex.Math
end
end
import Rex.Core
@doc ~S"""
Define a new Rex function.
You can call `drex` in two ways, the first is
to define a new _word_ that *operates on the stack*,
here for example `double` is a partial application multiplying by two:
drex double 2 ~> Kernel.*/2
The second way is to define a _word_ for *stack shuffling*,
ie, for example `Rex.Stack.swap/1` is defined like:
drex swap(a, b) (b, a)
"""
defmacro drex({{name, _, patterns}, _, exprs}) when length(patterns) > 0 do
rex_def({:def, :stack_effect}, {name, patterns, exprs})
end
defmacro drex({name, _, [expr]}) do
rex_def({:def, :stack_expr}, {name, expr}, __CALLER__)
end
@doc """
Compile a Rex expression into an Elixir function.
The returned anonymous function can be given a stack to operate on.
"""
defmacro rex(expr) do
rex_fn(expr, __CALLER__)
end
@doc ~S"""
Pipe an exising stack to a new Rex expression.
[5, 2, 3] |> rex(double ~> swap ~> double) #=> [4, 10, 3]
"""
defmacro rex(stack, expr) when is_list(stack) do
quote do
unquote(stack) |> unquote(rex_fn(expr, __CALLER__)).()
end
end
end