lib/rollex/token.ex

defprotocol Rollex.Token do
  @doc """
  Create a token from the passed-in string representing a roll expression.
  Returns a token and the number of bytes consumed in doing so.
  """
  @spec create(Rollex.token(), roll_expr :: String.t(), matches :: [String.t()] | nil) ::
          {Rollex.token(), num_bytes_consumed :: integer}
  def create(token, roll_expr, matches)

  @doc """
  Null denotation (nud): the action take when this token is at the start of an expression,
  e.g. prefix operations
  """
  @spec nud(Rollex.token(), rest :: Rollex.tokens()) ::
          {:ok, Rollex.totals(), Rollex.tokens()}
          | {:error, reason :: String.t()}
  def nud(token, rest)

  @doc """
  Left denotation (led): take action when this token is encountered within an expression,
  e.g. infix and postfix operations
  """
  @spec led(Rollex.token(), left :: Rollex.totals(), rest :: Rollex.tokens()) ::
          {:ok, Rollex.totals(), Rollex.tokens()}
          | {:error, reason :: String.t()}
  def led(token, left, rest)

  @doc """
  The left binding power (lbp), or the precedence in infix form for operator precedence.
  Higher lbp takes precedence over lower
  """
  @spec lbp(Rollex.token()) :: integer
  def lbp(token)
end