Class: Janeway::Interpreters::BinaryOperatorInterpreter
- Defined in:
- lib/janeway/interpreters/binary_operator_interpreter.rb
Overview
Interprets a binary operator within filter selector.
Constant Summary
Constants inherited from Base
Janeway::Interpreters::Base::NOTHING
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#initialize(operator) ⇒ BinaryOperatorInterpreter
constructor
Set up the internal interpreter chain for the BinaryOperator.
-
#interpret(input, root) ⇒ Object
The binary operators are all comparison operators that test equality.
-
#interpret_and(lhs, rhs) ⇒ Object
Interpret && operator May receive node lists, in which case empty node list == false.
- #interpret_boolean(boolean, _input) ⇒ Boolean
- #interpret_equal(lhs, rhs) ⇒ Object
- #interpret_greater_than(lhs, rhs) ⇒ Object
- #interpret_greater_than_or_equal(lhs, rhs) ⇒ Object
- #interpret_less_than(lhs, rhs) ⇒ Object
- #interpret_less_than_or_equal(lhs, rhs) ⇒ Object
-
#interpret_not_equal(lhs, rhs) ⇒ Object
Interpret != operator.
- #interpret_null(_null, _input) ⇒ Object
- #interpret_number(number, _input) ⇒ Integer, Float
-
#interpret_or(lhs, rhs) ⇒ Object
Interpret || operator May receive node lists, in which case empty node list == false.
- #interpret_string_type(string, _input) ⇒ String
-
#to_single_value(result) ⇒ Object
Convert an expression result into a single value suitable for use by a comparison operator.
Constructor Details
#initialize(operator) ⇒ BinaryOperatorInterpreter
Set up the internal interpreter chain for the BinaryOperator.
12 13 14 15 16 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 12 def initialize(operator) super @left = TreeConstructor.ast_node_to_interpreter(operator.left) @right = TreeConstructor.ast_node_to_interpreter(operator.right) end |
Instance Method Details
#interpret(input, root) ⇒ Object
The binary operators are all comparison operators that test equality.
* boolean values specified in the query
* JSONPath expressions which must be evaluated
After a JSONPath expression is evaluated, it results in a node list. This may contain literal values or nodes, whose value must be extracted before comparison.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 28 def interpret(input, root) case operator.name when :and, :or # handle node list for existence check lhs = @left.interpret(input, root) rhs = @right.interpret(input, root) when :equal, :not_equal, :less_than, :greater_than, :less_than_or_equal, :greater_than_or_equal # handle node values for comparison check lhs = to_single_value @left.interpret(input, root) rhs = to_single_value @right.interpret(input, root) else raise "Don't know how to handle binary operator #{operator.name.inspect}" end send(:"interpret_#{operator.name}", lhs, rhs) end |
#interpret_and(lhs, rhs) ⇒ Object
Interpret && operator May receive node lists, in which case empty node list == false
90 91 92 93 94 95 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 90 def interpret_and(lhs, rhs) # non-empty array is already truthy, so that works properly without conversion lhs = false if lhs == [] rhs = false if rhs == [] lhs && rhs end |
#interpret_boolean(boolean, _input) ⇒ Boolean
140 141 142 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 140 def interpret_boolean(boolean, _input) boolean.value end |
#interpret_equal(lhs, rhs) ⇒ Object
79 80 81 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 79 def interpret_equal(lhs, rhs) lhs == rhs end |
#interpret_greater_than(lhs, rhs) ⇒ Object
124 125 126 127 128 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 124 def interpret_greater_than(lhs, rhs) lhs > rhs rescue StandardError false end |
#interpret_greater_than_or_equal(lhs, rhs) ⇒ Object
130 131 132 133 134 135 136 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 130 def interpret_greater_than_or_equal(lhs, rhs) return true if interpret_equal(lhs, rhs) lhs > rhs rescue StandardError false end |
#interpret_less_than(lhs, rhs) ⇒ Object
106 107 108 109 110 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 106 def interpret_less_than(lhs, rhs) lhs < rhs rescue StandardError false end |
#interpret_less_than_or_equal(lhs, rhs) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 112 def interpret_less_than_or_equal(lhs, rhs) # Must be done in 2 comparisons, because the equality comparison is # valid for many types that do not support the < operator. return true if interpret_equal(lhs, rhs) lhs < rhs rescue StandardError # This catches type mismatches like {} <= 1 # RFC says that both < and > return false for such comparisons false end |
#interpret_not_equal(lhs, rhs) ⇒ Object
Interpret != operator
84 85 86 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 84 def interpret_not_equal(lhs, rhs) !interpret_equal(lhs, rhs) end |
#interpret_null(_null, _input) ⇒ Object
158 159 160 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 158 def interpret_null(_null, _input) nil end |
#interpret_number(number, _input) ⇒ Integer, Float
146 147 148 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 146 def interpret_number(number, _input) number.value end |
#interpret_or(lhs, rhs) ⇒ Object
Interpret || operator May receive node lists, in which case empty node list == false
99 100 101 102 103 104 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 99 def interpret_or(lhs, rhs) # non-empty array is already truthy, so that works properly without conversion lhs = false if lhs.is_a?(Array) && lhs.empty? rhs = false if rhs.is_a?(Array) && rhs.empty? lhs || rhs end |
#interpret_string_type(string, _input) ⇒ String
152 153 154 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 152 def interpret_string_type(string, _input) string.value end |
#to_single_value(result) ⇒ Object
Convert an expression result into a single value suitable for use by a comparison operator. Expression result may already ba single value (ie. from a literal like AST::String) or it may be a node list from a singular query.
Any node list is guaranteed not to contain multiple values because the expression that produce it was already verified to be a singular query.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/janeway/interpreters/binary_operator_interpreter.rb', line 59 def to_single_value(result) # Return basic types (ie. from AST::Number, AST::StringType, AST::Null) return result unless result.is_a?(Array) # Node lists are returned by Selectors, ChildSegment, DescendantSegment. # # For a comparison operator, an empty node list represents a missing element. # This must not match any literal value (including null/nil) but must match another missing value. return NOTHING if result.empty? # The parsing stage has already verified that both the left and right # expressions evaluate to a single value. Both are either a literal or a singular query. # So, this check will never raise an error. raise 'node list contains multiple elements but this is a comparison' unless result.size == 1 result.first # Return the only node in the node list end |