Module: Fbe::Award::BTerm

Defined in:
lib/fbe/award.rb

Overview

A term module for processing award billing logic.

This module is used to extend Factbase terms to handle award calculations and billing operations. It provides methods to calculate point values and evaluate complex award expressions.

Instance Method Summary collapse

Instance Method Details

#abstract?Boolean

Indicates whether the term is abstract.

Returns:

  • (Boolean)

    Always returns false for BTerm



91
92
93
# File 'lib/fbe/award.rb', line 91

def abstract?
  false
end

#bill_to(bill) ⇒ nil

Processes this term and applies its operations to a bill.

Examples:

term = Factbase::Syntax.new('(award (give 100 "for effort"))').to_term
term.redress!(Fbe::Award::BTerm)
bill = Fbe::Award::Bill.new
term.bill_to(bill)
bill.points #=> 100

Parameters:

Returns:

  • (nil)

Raises:

  • (RuntimeError)

    If there’s a failure processing any term



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/fbe/award.rb', line 106

def bill_to(bill)
  case @op
  when :award
    @operands.each do |o|
      o.bill_to(bill)
    rescue StandardError => e
      raise "Failure in #{o}: #{e.message}"
    end
  when :aka
    @operands[0..-2].each do |o|
      o.bill_to(bill)
    rescue StandardError => e
      raise "Failure in #{o}: #{e.message}"
    end
  when :let, :set
    v = to_val(@operands[1], bill)
    raise "Can't #{@op.inspect} #{@operands[0].inspect} to nil" if v.nil?
    bill.set(@operands[0], v)
  when :give
    text = @operands[1]
    text = '' if text.nil?
    bill.line(to_val(@operands[0], bill), text)
  when :explain, :in
    # nothing, just ignore
  else
    raise "Unknown term '#{@op}'"
  end
end

#calc(bill) ⇒ Object

Calculates the value of this term in the context of a bill.

This method evaluates terms like arithmetic operations, logical operations, and other expressions based on the operator type.

Examples:

bill = Fbe::Award::Bill.new
bill.set(:x, 10)
bill.set(:y, 5)
term = Factbase::Syntax.new('(times x y)').to_term
term.redress!(Fbe::Award::BTerm)
term.calc(bill) #=> 50

Parameters:

Returns:

  • (Object)

    The calculated value (number, boolean, etc.)

Raises:

  • (RuntimeError)

    If the term operation is unknown



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/fbe/award.rb', line 172

def calc(bill)
  case @op
  when :total
    bill.points
  when :if
    to_val(@operands[0], bill) ? to_val(@operands[1], bill) : to_val(@operands[2], bill)
  when :and
    @operands.all? { |o| to_val(o, bill) }
  when :or
    @operands.any? { |o| to_val(o, bill) }
  when :not
    !to_val(@operands[0], bill)
  when :eq
    to_val(@operands[0], bill) == to_val(@operands[1], bill)
  when :lt
    to_val(@operands[0], bill) < to_val(@operands[1], bill)
  when :lte
    to_val(@operands[0], bill) <= to_val(@operands[1], bill)
  when :gt
    to_val(@operands[0], bill) > to_val(@operands[1], bill)
  when :gte
    to_val(@operands[0], bill) >= to_val(@operands[1], bill)
  when :div
    to_val(@operands[0], bill) / to_val(@operands[1], bill)
  when :times
    to_val(@operands[0], bill) * to_val(@operands[1], bill)
  when :plus
    to_val(@operands[0], bill) + to_val(@operands[1], bill)
  when :minus
    to_val(@operands[0], bill) - to_val(@operands[1], bill)
  when :max
    [to_val(@operands[0], bill), to_val(@operands[1], bill)].max
  when :min
    [to_val(@operands[0], bill), to_val(@operands[1], bill)].min
  when :between
    v = to_val(@operands[0], bill)
    a = to_val(@operands[1], bill)
    b = to_val(@operands[2], bill)
    min, max = [a, b].minmax
    return 0 if (!v.negative? && v < min) || (!v.positive? && v > max)
    v.clamp(min, max)
  else
    raise "Unknown term '#{@op}'"
  end
end

#static?Boolean

Indicates whether the term is static.

Returns:

  • (Boolean)

    Always returns true for BTerm



84
85
86
# File 'lib/fbe/award.rb', line 84

def static?
  true
end

#to_sString

Returns a string representation of the term.

Examples:

term.to_s #=> "(give (times loc 5) 'for LoC')"

Returns:

  • (String)

    The term as a string in S-expression format



77
78
79
# File 'lib/fbe/award.rb', line 77

def to_s
  "(#{@op} #{@operands.join(' ')})"
end

#to_val(any, bill) ⇒ Object

Evaluates a value in the context of a bill.

Examples:

bill = Fbe::Award::Bill.new
bill.set(:loc, 100)
term.to_val(:loc, bill) #=> 100

Parameters:

  • any (Object)

    The value to evaluate (symbol, term, or literal)

  • bill (Fbe::Award::Bill)

    The bill providing context for evaluation

Returns:

  • (Object)

    The evaluated value

Raises:

  • (RuntimeError)

    If a symbol isn’t found in the bill



145
146
147
148
149
150
151
152
153
154
155
# File 'lib/fbe/award.rb', line 145

def to_val(any, bill)
  if any.is_a?(BTerm)
    any.calc(bill)
  elsif any.is_a?(Symbol)
    v = bill.vars[any]
    raise "Unknown name #{any.inspect} among: #{bill.vars.keys.map(&:inspect).joined}" if v.nil?
    v
  else
    any
  end
end