Class: Dentaku::Rules

Inherits:
Object
  • Object
show all
Defined in:
lib/dentaku/rules.rb

Class Method Summary collapse

Class Method Details

.add_function(f) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/dentaku/rules.rb', line 36

def self.add_function(f)
  ext = ExternalFunction.new(f[:name], f[:type], f[:signature], f[:body])

  @rules ||= core_rules
  @funcs ||= {}

  ## rules need to be added to the beginning of @rules for precedence
  @rules.unshift [
    [
      TokenMatcher.send(ext.name),
      t(:fopen),
      *pattern(*ext.tokens),
      t(:close)
    ],
    ext.name
  ]
  @funcs[ext.name] = ext
end

.core_rulesObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/dentaku/rules.rb', line 7

def self.core_rules
  [
    [ p(:if),         :if             ],
    [ p(:round),      :round          ],
    [ p(:roundup),    :round_int      ],
    [ p(:rounddown),  :round_int      ],
    [ p(:not),        :not            ],

    [ p(:group),      :evaluate_group ],
    [ p(:start_neg),  :negate         ],
    [ p(:math_pow),   :apply          ],
    [ p(:math_mod),   :apply          ],
    [ p(:math_mul),   :apply          ],
    [ p(:math_add),   :apply          ],
    [ p(:percentage), :percentage     ],
    [ p(:negation),   :negate         ],
    [ p(:range_asc),  :expand_range   ],
    [ p(:range_desc), :expand_range   ],
    [ p(:num_comp),   :apply          ],
    [ p(:str_comp),   :apply          ],
    [ p(:combine),    :apply          ]
  ]
end

.eachObject



31
32
33
34
# File 'lib/dentaku/rules.rb', line 31

def self.each
  @rules ||= core_rules
  @rules.each { |r| yield r }
end

.func(name) ⇒ Object



55
56
57
58
# File 'lib/dentaku/rules.rb', line 55

def self.func(name)
  @funcs ||= {}
  @funcs.fetch(name)
end

.func_pattern(func, *tokens) ⇒ Object



107
108
109
# File 'lib/dentaku/rules.rb', line 107

def self.func_pattern(func, *tokens)
  pattern(func, :fopen, *tokens, :close)
end

.generate_matchersObject



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/dentaku/rules.rb', line 65

def self.generate_matchers
  [
    :numeric, :string, :addsub, :subtract, :muldiv, :pow, :mod,
    :comparator, :comp_gt, :comp_lt, :fopen, :open, :close, :comma,
    :non_close_plus, :non_group, :non_group_star, :arguments,
    :logical, :combinator, :if, :round, :roundup, :rounddown, :not,
    :anchored_minus
  ].each_with_object({}) do |name, matchers|
    matchers[name] = TokenMatcher.send(name)
  end
end

.p(name) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/dentaku/rules.rb', line 77

def self.p(name)
  @patterns ||= {
    group:      pattern(:open,     :non_group_star, :close),
    math_add:   pattern(:numeric,  :addsub,         :numeric),
    math_mul:   pattern(:numeric,  :muldiv,         :numeric),
    math_pow:   pattern(:numeric,  :pow,            :numeric),
    math_mod:   pattern(:numeric,  :mod,            :numeric),
    negation:   pattern(:subtract, :numeric),
    start_neg:  pattern(:anchored_minus, :numeric),
    percentage: pattern(:numeric,  :mod),
    range_asc:  pattern(:numeric,  :comp_lt,        :numeric,  :comp_lt, :numeric),
    range_desc: pattern(:numeric,  :comp_gt,        :numeric,  :comp_gt, :numeric),
    num_comp:   pattern(:numeric,  :comparator,     :numeric),
    str_comp:   pattern(:string,   :comparator,     :string),
    combine:    pattern(:logical,  :combinator,     :logical),

    if:         func_pattern(:if,        :non_group,      :comma, :non_group, :comma, :non_group),
    round:      func_pattern(:round,     :arguments),
    roundup:    func_pattern(:roundup,   :arguments),
    rounddown:  func_pattern(:rounddown, :arguments),
    not:        func_pattern(:not,       :arguments)
  }

  @patterns[name]
end

.pattern(*symbols) ⇒ Object



103
104
105
# File 'lib/dentaku/rules.rb', line 103

def self.pattern(*symbols)
  symbols.map { |s| t(s) }
end

.t(name) ⇒ Object



60
61
62
63
# File 'lib/dentaku/rules.rb', line 60

def self.t(name)
  @matchers ||= generate_matchers
  @matchers.fetch(name)
end