Module: Dogfood::DSL::Evaluator

Defined in:
lib/dogfood/dsl/evaluator.rb

Overview

Evaluates minimal $... expressions. Safe: it is a tiny hand-rolled recursive-descent parser, NOT eval. See SPEC.md 4.4 for the grammar.

Defined Under Namespace

Classes: CatProxy, Parser, PoolAccessor, PoolProxy

Constant Summary collapse

TOKEN =
/\$\{([^}]*)\}/

Class Method Summary collapse

Class Method Details

.eval(value, bindings:, state:, rng:, self_object: nil, pools: nil, faker: nil) ⇒ Object

Evaluates a value that may contain $... tokens. Returns the raw bound value if the entire input is a single $...; otherwise interpolates tokens into the surrounding string.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/dogfood/dsl/evaluator.rb', line 13

def self.eval(value, bindings:, state:, rng:, self_object: nil, pools: nil, faker: nil)
  if value.is_a?(String) && (m = TOKEN.match(value)) && m[0] == value
    return evaluate_expression(m[1], bindings: bindings, state: state, rng: rng,
                            self_object: self_object, pools: pools, faker: faker)
  end

  case value
  when String
    value.gsub(TOKEN) do
      result = evaluate_expression(Regexp.last_match(1), bindings: bindings, state: state, rng: rng,
                                  self_object: self_object, pools: pools, faker: faker)
      stringify(result)
    end
  when Hash
    value.each_with_object({}) do |(k, v), acc|
      acc[eval(k, bindings: bindings, state: state, rng: rng, self_object: self_object, pools: pools, faker: faker)] =
        eval(v, bindings: bindings, state: state, rng: rng, self_object: self_object, pools: pools, faker: faker)
    end
  when Array
    value.map { |v| eval(v, bindings: bindings, state: state, rng: rng, self_object: self_object, pools: pools, faker: faker) }
  else
    value
  end
end

.evaluate_expression(expr, bindings:, state:, rng:, self_object: nil, pools: nil, faker: nil) ⇒ Object

Parses and evaluates a single expression (without $... delimiters).



39
40
41
# File 'lib/dogfood/dsl/evaluator.rb', line 39

def self.evaluate_expression(expr, bindings:, state:, rng:, self_object: nil, pools: nil, faker: nil)
  Parser.new(expr, bindings: bindings, state: state, rng: rng, self_object: self_object, pools: pools, faker: faker).parse
end

.stringify(value) ⇒ Object



43
44
45
46
47
48
49
50
# File 'lib/dogfood/dsl/evaluator.rb', line 43

def self.stringify(value)
  case value
  when nil then "null"
  when true then "true"
  when false then "false"
  else value.to_s
  end
end