Updated Formula get_quantities/calculate for new parsing algo
This commit is contained in:
parent
613c26728c
commit
2e477921e9
@ -4,10 +4,13 @@ module BodyTracking
|
|||||||
QUANTITY_TTYPES = [:on_ident, :on_tstring_content, :on_const]
|
QUANTITY_TTYPES = [:on_ident, :on_tstring_content, :on_const]
|
||||||
FUNCTIONS = ['abs', 'nil?']
|
FUNCTIONS = ['abs', 'nil?']
|
||||||
|
|
||||||
|
class InvalidFormula < RuntimeError; end
|
||||||
class Formula
|
class Formula
|
||||||
def initialize(project, formula)
|
def initialize(project, formula)
|
||||||
@project = project
|
@project = project
|
||||||
@formula = formula
|
@formula = formula
|
||||||
|
@paramed_formula = nil
|
||||||
|
@quantities = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate
|
def validate
|
||||||
@ -60,9 +63,9 @@ module BodyTracking
|
|||||||
when :var_ref
|
when :var_ref
|
||||||
vtype, vname, vloc = token
|
vtype, vname, vloc = token
|
||||||
case vtype
|
case vtype
|
||||||
when vtype == :@conts
|
when :@const
|
||||||
identifiers << vname
|
identifiers << vname
|
||||||
when vtype == :@kw
|
when :@kw
|
||||||
disallowed[:keyword] << token if vname != 'nil'
|
disallowed[:keyword] << token if vname != 'nil'
|
||||||
end
|
end
|
||||||
when :@int, :@float
|
when :@int, :@float
|
||||||
@ -76,32 +79,44 @@ module BodyTracking
|
|||||||
|
|
||||||
# 4th: check if identifiers used in formula correspond to existing quantities
|
# 4th: check if identifiers used in formula correspond to existing quantities
|
||||||
identifiers.uniq!
|
identifiers.uniq!
|
||||||
quantities = @project.quantities.where(name: identifiers).pluck(:name)
|
quantities = @project.quantities.where(name: identifiers)
|
||||||
(identifiers - quantities).each { |q| errors << [:unknown_quantity, {quantity: q}] }
|
quantities_names = quantities.pluck(:name)
|
||||||
|
(identifiers - quantities_names).each do |q|
|
||||||
|
errors << [:unknown_quantity, {quantity: q}]
|
||||||
|
end
|
||||||
|
|
||||||
|
if errors.empty?
|
||||||
|
@quantities = quantities
|
||||||
|
@paramed_formula = Ripper.lex(@formula).map do |*, ttype, token|
|
||||||
|
if QUANTITY_TTYPES.include?(ttype) && quantities_names.include?(token)
|
||||||
|
"params['#{token}']"
|
||||||
|
else
|
||||||
|
token
|
||||||
|
end
|
||||||
|
end.join
|
||||||
|
end
|
||||||
|
|
||||||
errors
|
errors
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid?
|
def valid?
|
||||||
self.validate.empty?
|
self.validate if @quantities.nil?
|
||||||
|
!@quantities.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_quantities
|
def get_quantities
|
||||||
q_names = Ripper.lex(@formula).map do |*, ttype, token|
|
raise RuntimeError, 'Invalid formula' unless self.valid?
|
||||||
token if is_token_quantity?(ttype, token)
|
|
||||||
end.compact
|
@quantities.to_a
|
||||||
@project.quantities.where(name: q_names).to_a
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def calculate(inputs)
|
def calculate(inputs)
|
||||||
paramed_formula = Ripper.lex(@formula).map do |*, ttype, token|
|
raise RuntimeError, 'Invalid formula' unless self.valid?
|
||||||
is_token_quantity?(ttype, token) ? "params['#{token}']" : token
|
|
||||||
end.join
|
|
||||||
|
|
||||||
inputs.map do |i, values|
|
inputs.map do |i, values|
|
||||||
puts values.inspect
|
puts values.inspect
|
||||||
begin
|
begin
|
||||||
[i, [get_binding(values).eval(paramed_formula), nil]]
|
[i, [get_binding(values).eval(@paramed_formula), nil]]
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
puts e.message
|
puts e.message
|
||||||
[i, [nil, nil]]
|
[i, [nil, nil]]
|
||||||
@ -111,10 +126,6 @@ module BodyTracking
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def is_token_quantity?(ttype, token)
|
|
||||||
QUANTITY_TTYPES.include?(ttype) && !FUNCTIONS.include?(token)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_binding(params)
|
def get_binding(params)
|
||||||
binding
|
binding
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user