Method type distinction: numeric/quantity
This commit is contained in:
parent
6ce02ba05a
commit
8e362ade79
@ -8,8 +8,7 @@ class DemoBuilder < Ripper::SexpBuilder
|
|||||||
super(*args)
|
super(*args)
|
||||||
@disallowed = Hash.new { |h,k| h[k] = Set.new }
|
@disallowed = Hash.new { |h,k| h[k] = Set.new }
|
||||||
@identifiers = Set.new
|
@identifiers = Set.new
|
||||||
@paramed_formula = nil
|
@parts = []
|
||||||
@arguments = []
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def errors
|
def errors
|
||||||
@ -22,7 +21,9 @@ class DemoBuilder < Ripper::SexpBuilder
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
METHODS = ['abs', 'nil?']
|
DECIMAL_METHODS = ['abs', 'nil?']
|
||||||
|
QUANTITY_METHODS = ['all', 'lastBefore']
|
||||||
|
METHODS = DECIMAL_METHODS + QUANTITY_METHODS
|
||||||
|
|
||||||
events = private_instance_methods(false).grep(/\Aon_/) {$'.to_sym}
|
events = private_instance_methods(false).grep(/\Aon_/) {$'.to_sym}
|
||||||
(PARSER_EVENTS - events).each do |event|
|
(PARSER_EVENTS - events).each do |event|
|
||||||
@ -35,8 +36,8 @@ class DemoBuilder < Ripper::SexpBuilder
|
|||||||
end
|
end
|
||||||
|
|
||||||
def on_program(stmts)
|
def on_program(stmts)
|
||||||
@paramed_formula = join_stmts(stmts)
|
@parts << {type: :indexed, content: join_stmts(stmts)}
|
||||||
[@identifiers, @paramed_formula, @arguments]
|
[@identifiers, @parts]
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_string_content
|
def on_string_content
|
||||||
@ -73,10 +74,8 @@ class DemoBuilder < Ripper::SexpBuilder
|
|||||||
when :bt_quantity
|
when :bt_quantity
|
||||||
"params['#{token}']"
|
"params['#{token}']"
|
||||||
when :bt_expression
|
when :bt_expression
|
||||||
# FIXME: 'token' expression has to be evaluated in block with _index and
|
@parts << {type: :indexed, content: token}
|
||||||
# result stored in @arguments
|
"parts[#{@parts.length - 1}]"
|
||||||
@arguments << token
|
|
||||||
"args['#{@arguments.length - 1}']"
|
|
||||||
else
|
else
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
end
|
||||||
@ -100,30 +99,53 @@ class DemoBuilder < Ripper::SexpBuilder
|
|||||||
end
|
end
|
||||||
|
|
||||||
def on_call(left, dot, right)
|
def on_call(left, dot, right)
|
||||||
[
|
method, mtype =
|
||||||
:bt_method_call,
|
|
||||||
case left[0]
|
|
||||||
when :bt_quantity
|
|
||||||
"params['#{left[1]}']"
|
|
||||||
when :bt_method_call
|
|
||||||
"#{left[1]}"
|
|
||||||
else
|
|
||||||
raise NotImplementedError
|
|
||||||
end <<
|
|
||||||
dot.to_s <<
|
|
||||||
case right[0]
|
case right[0]
|
||||||
when :bt_ident
|
when :bt_ident
|
||||||
@disallowed[:method] << right[1] unless METHODS.include?(right[1])
|
case
|
||||||
right[1]
|
when DECIMAL_METHODS.include?(right[1])
|
||||||
|
[right[1], :numeric_method]
|
||||||
|
when QUANTITY_METHODS.include?(right[1])
|
||||||
|
[right[1], :quantity_method]
|
||||||
|
else
|
||||||
|
@disallowed[:method] << right[1]
|
||||||
|
[right[1], :unknown_method]
|
||||||
|
end
|
||||||
else
|
else
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
end
|
||||||
]
|
|
||||||
|
case left[0]
|
||||||
|
when :bt_quantity
|
||||||
|
if mtype == :quantity_method
|
||||||
|
part_index = @parts.length
|
||||||
|
@parts << {type: :unindexed, content: "params['#{left[1]}']#{dot.to_s}#{method}"}
|
||||||
|
[:bt_quantity_method_call, "parts[#{part_index}]", part_index]
|
||||||
|
else
|
||||||
|
[:bt_numeric_method_call, "params['#{left[1]}'][_index]#{dot.to_s}#{method}"]
|
||||||
|
end
|
||||||
|
when :bt_quantity_method_call
|
||||||
|
if mtype == :quantity_method
|
||||||
|
@parts[left[2]][:content] << "#{dot.to_s}#{method}"
|
||||||
|
left
|
||||||
|
else
|
||||||
|
[:bt_numeric_method_call, "#{left[1]}#{dot.to_s}#{method}"]
|
||||||
|
end
|
||||||
|
when :bt_numeric_method_call
|
||||||
|
if mtype == :quantity_method
|
||||||
|
# TODO: add error reporting
|
||||||
|
raise NotImplementedError
|
||||||
|
else
|
||||||
|
[:bt_numeric_method_call, "#{left[1]}#{dot.to_s}#{method}"]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_fcall(token)
|
def on_fcall(token)
|
||||||
@disallowed[:method] = token[1]
|
@disallowed[:method] = token[1]
|
||||||
[:bt_method, token[1]]
|
[:bt_numeric_method_call, token[1]]
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_vcall(token)
|
def on_vcall(token)
|
||||||
@ -137,10 +159,15 @@ class DemoBuilder < Ripper::SexpBuilder
|
|||||||
end
|
end
|
||||||
|
|
||||||
def on_method_add_arg(method, paren)
|
def on_method_add_arg(method, paren)
|
||||||
[
|
case method[0]
|
||||||
:bt_method_call,
|
when :bt_quantity_method_call
|
||||||
"#{method[1]}#{paren}"
|
@parts[method[2]][:content] << paren
|
||||||
]
|
method
|
||||||
|
when :bt_numeric_method_call
|
||||||
|
[:bt_numeric_method_call, "#{method[1]}#{paren}"]
|
||||||
|
else
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_binary(left, op, right)
|
def on_binary(left, op, right)
|
||||||
@ -206,4 +233,5 @@ pp Ripper.sexp_raw(src)
|
|||||||
parser = DemoBuilder.new(src)
|
parser = DemoBuilder.new(src)
|
||||||
pp parser.parse
|
pp parser.parse
|
||||||
pp parser.errors
|
pp parser.errors
|
||||||
puts "(params['Weight'][_index]/params['Height'].all(args['0']).lastBefore(params['TakenAt'])^2)+2*params['Other'][_index]*params['Other'][_index]*params['other'][_index]"
|
puts src
|
||||||
|
puts " (params['Weight'][_index]/params['Height'].all(args['0']).lastBefore(params['TakenAt'])^2)+2*params['Other'][_index]*params['Other'][_index]*params['other'][_index]"
|
||||||
|
Reference in New Issue
Block a user