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 type calculated_val() View Source
calculated_val() :: number() | [number()]
Link to this type compiled_fun() View Source
compiled_fun() :: (args() -> calculated_val())
Link to this type compiled_val() View Source
compiled_val() :: compiled_fun() | calculated_val()
Link to this type fun_info_tuple() View Source
fun_info_tuple() :: {function(), atom(), [any()]}

Link to this section Functions

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.

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']}
      ]}
    ]}
]}

Performs rounding on both numbers and lists of numbers.

Link to this section Callbacks

Compiles the expression into a compiled_val/0.