ExDiceRoller v1.0.0-rc.2 ExDiceRoller.Compiler behaviour View Source
Provides functionality for compiling expressions into ready-to-execute functions.
Compiler’s main job is to perform the following:
- takes a concrete parse tree, generally outputted by
ExDiceRoller.Parser
, and recursively navigates the tree each expression is delegated to an appropriate module that implements the
compile/1
callback, which then- converts each expression that results in an invariable value into a number
- converts each expression containing variability, or randomness, into a compiled anonymous function
- sends sub-expressions back to Compiler to be delegated appropriately
wraps the nested set of compiled functions with an anonymous function that also:
- checks for cache usage and acts accordingly
- applies any
ExDiceRoller.Filters
present in the arguments - rounds and returns the final value
Note that all compiled functions outputted by Compiler accept both arguments and options. Arguments are used exclusively for replacing variables with values. Options affect the behavior of the anonymous functions and include concepts such as exploding dice, choosing highest or lowest values, and more.
More information about the different types of expression compilers and their
function can be found in the individual ExDiceRoller.Compiler.*
modules.
Example
> parsed =
{{:operator, '+'},
{{:operator, '-'}, {:roll, 1, 4},
{{:operator, '/'}, {:roll, 3, 6}, 2}},
{:roll, {:roll, 1, 4},
{:roll, 1, 6}}}
> fun = ExDiceRoller.Compiler.compile(parsed)
#Function<1.51809653/1 in ExDiceRoller.Compiler.build_final_function/1>
> fun.([])
11
> ExDiceRoller.Compiler.fun_info(fun)
{#Function<0.102777967/1 in ExDiceRoller.Compilers.Math.compile_add/2>,
:"-compile_add/2-fun-1-",
[
{#Function<20.102777967/1 in ExDiceRoller.Compilers.Math.compile_sub/2>,
:"-compile_sub/2-fun-1-",
[
{#Function<3.31405244/1 in ExDiceRoller.Compilers.Roll.compile_roll/2>,
:"-compile_roll/2-fun-3-", [1, 4]},
{#Function<5.102777967/1 in ExDiceRoller.Compilers.Math.compile_div/2>,
:"-compile_div/2-fun-3-",
[
{#Function<3.31405244/1 in ExDiceRoller.Compilers.Roll.compile_roll/2>,
:"-compile_roll/2-fun-3-", [3, 6]},
2
]}
]},
{#Function<0.31405244/1 in ExDiceRoller.Compilers.Roll.compile_roll/2>,
:"-compile_roll/2-fun-0-",
[
{#Function<3.31405244/1 in ExDiceRoller.Compilers.Roll.compile_roll/2>,
:"-compile_roll/2-fun-3-", [1, 4]},
{#Function<3.31405244/1 in ExDiceRoller.Compilers.Roll.compile_roll/2>,
:"-compile_roll/2-fun-3-", [1, 6]}
]}
]}
Link to this section Summary
Functions
Compiles a provided t:Parser.expression/0
into an anonymous function
Delegates expression compilation to an appropriate module that implements
ExDiceRoller.Compiler
behaviours
Shows the nested functions and relationships of a compiled function. The
structure of the fun_info result is {<function>, <atom with name, arity, and
ordered function #>, [<recursive info about child functions>]}
Performs rounding on both numbers and lists of numbers
Callbacks
Compiles the expression into a compiled_val/0
Link to this section Types
Link to this section Functions
compile(ExDiceRoller.Parser.expression()) :: compiled_val()
Compiles a provided t:Parser.expression/0
into an anonymous function.
iex> expr = "1d2+x"
"1d2+x"
iex> {:ok, tokens} = ExDiceRoller.Tokenizer.tokenize(expr)
{:ok,
[
{:int, 1, '1'},
{:roll, 1, 'd'},
{:int, 1, '2'},
{:basic_operator, 1, '+'},
{:var, 1, 'x'}
]}
iex> {:ok, parsed} = ExDiceRoller.Parser.parse(tokens)
{:ok, {{:operator, '+'}, {:roll, 1, 2}, {:var, 'x'}}}
iex> fun = ExDiceRoller.Compiler.compile(parsed)
iex> fun.([x: 1, opts: [:explode]])
2
During calculation, float values are left as float for as long as possible.
If a compiled roll is invoked with a float as the number of dice or sides,
that value will be rounded to an integer. Finally, the return value is a
rounded integer. Rounding rules can be found at Kernel.round/1
.
delegate(ExDiceRoller.Parser.expression()) :: compiled_val()
Delegates expression compilation to an appropriate module that implements
ExDiceRoller.Compiler
behaviours.
Shows the nested functions and relationships of a compiled function. The
structure of the fun_info result is {<function>, <atom with name, arity, and
ordered function #>, [<recursive info about child functions>]}
.
> {:ok, fun} = ExDiceRoller.compile("1d8+(1-x)d(2*y)")
#=> {:ok, #Function<0.84780260/1 in ExDiceRoller.Compiler.compile_add/4>}
> ExDiceRoller.Compiler.fun_info fun
#=> {#Function<0.16543174/1 in ExDiceRoller.Compiler.compile_add/4>,
:"-compile_add/4-fun-0-",
[
{#Function<12.16543174/1 in ExDiceRoller.Compiler.compile_roll/4>,
:"-compile_roll/4-fun-3-", [1, 8]},
{#Function<9.16543174/1 in ExDiceRoller.Compiler.compile_roll/4>,
:"-compile_roll/4-fun-0-",
[
{#Function<15.16543174/1 in ExDiceRoller.Compiler.compile_sub/4>,
:"-compile_sub/4-fun-2-",
[
1,
{#Function<16.16543174/1 in ExDiceRoller.Compiler.compile_var/1>,
:"-compile_var/1-fun-0-", ['x']}
]},
{#Function<8.16543174/1 in ExDiceRoller.Compiler.compile_mul/4>,
:"-compile_mul/4-fun-2-",
[
2,
{#Function<16.16543174/1 in ExDiceRoller.Compiler.compile_var/1>,
:"-compile_var/1-fun-0-", ['y']}
]}
]}
]}
round_val(calculated_val() | float()) :: calculated_val()
Performs rounding on both numbers and lists of numbers.
Link to this section Callbacks
compile(ExDiceRoller.Parser.expression()) :: compiled_val()
Compiles the expression into a compiled_val/0
.