Class: Calyx::Syntax::ExpressionChain

Inherits:
Object
  • Object
show all
Defined in:
lib/calyx/syntax/expression.rb

Overview

Handles filter chains that symbolic expressions can pass through to generate a custom substitution.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(production, modifiers, registry) ⇒ ExpressionChain

Returns a new instance of ExpressionChain.

Parameters:



58
59
60
61
62
# File 'lib/calyx/syntax/expression.rb', line 58

def initialize(production, modifiers, registry)
  @production = production
  @modifiers = modifiers
  @registry = registry
end

Class Method Details

.parse(production, production_chain, registry) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/calyx/syntax/expression.rb', line 33

def self.parse(production, production_chain, registry)
  modifier_chain = production_chain.each_slice(2).map do |op_token, target|
    rule = target.to_sym
    case op_token
    when Token::EXPR_FILTER then Modifier.filter(rule)
    when Token::EXPR_MAP_LEFT then Modifier.map_left(rule)
    when Token::EXPR_MAP_RIGHT then Modifier.map_right(rule)
    else
      # Should not end up here because the regex excludes it but this
      # could be a place to add a helpful parse error on any weird
      # chars used by the expression—current behaviour is to pass
      # the broken expression through to the result as part of the
      # text, as if that is what the author meant.
      raise("unreachable")
    end
  end

  expression = Expression.parse(production, registry)

  self.new(expression, modifier_chain, registry)
end

Instance Method Details

#evaluate(options) ⇒ Array

Evaluate the expression by expanding the non-terminal to produce a terminal string, then passing it through the given modifier chain and returning the transformed result.

Parameters:

Returns:

  • (Array)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/calyx/syntax/expression.rb', line 70

def evaluate(options)
  expanded = @production.evaluate(options).flatten.reject { |o| o.is_a?(Symbol) }.join
  chain = []

  expression = @modifiers.reduce(expanded) do |value, modifier|
    case modifier.type
    when :filter
      @registry.expand_filter(modifier.name, value)
    when :map
      @registry.expand_map(modifier.name, value, modifier.map_dir)
    end
  end

  [:expression, expression]
end