def evaluate_expr
return @expr if @expr.is_a?(Numeric)
return nil if @expr.nil?
if @expr.is_a? Symbol
@expr = ':' + @expr.to_s
else
@expr.gsub!("\n", ' ')
@expr.scrub!
end
result = false
if @expr.match(/\:\S+/)
limit_items = @expr.split(/\:|\s+/).reject(&:empty?)
if limit_items.size == 1
return fetch_reference_value(limit_items.first)
else
references = @expr.split(/\:|\s+/).select { |var| var.match(/^[a-zA-Z]\S+$/) }
new_limit_items = [].tap do |limit_ary|
limit_items.each do |item|
if references.include? item
limit_ary << fetch_reference_value(item)
next
else
limit_ary << item
end
end
end
new_limit = new_limit_items.join(' ')
new_limit_references = new_limit.split(/\:|\s+/).select { |var| var.match(/^[a-zA-Z]\S+$/) }
if new_limit_references.empty?
result = eval(new_limit).round(4)
else
return @expr
end
end
elsif !!(@expr.match(/^\d+\.\d+$/)) || !!(@expr.match(/^-\d+\.\d+$/))
result = Float(@expr).round(4) rescue false
elsif !!(@expr.match(/\d+\.\d+\s+\d+\.\d+/))
Origen.log.debug "Found two numbers without an operator in the @expr string '#{@expr}', choosing the first..."
first_number = @expr.match(/(\d+\.\d+)\s+\d+\.\d+/).captures.first
result = Float(first_number).round(4) rescue false
else
result = Integer(@expr) rescue false
end
if result == false
begin
result = eval(@expr)
return result.round(4) if result.is_a? Numeric
rescue ::SyntaxError, ::NameError, ::TypeError
Origen.log.debug "Limit '#{@expr}' had to be rescued, storing it as a #{@expr.class}"
if @expr.is_a? Symbol
@expr
else
"#{@expr}"
end
end
else
result
end
end