Module: Postsvg::Visitors::PsVisitor::Container
- Included in:
- Postsvg::Visitors::PsVisitor
- Defined in:
- lib/postsvg/visitors/ps_visitor/container.rb
Overview
Operators that operate on any collection (string, array,
dictionary). The visitor dispatches by is_a? on the
operand at runtime.
Instance Method Summary collapse
- #visit_anchorsearch(op, _ctx) ⇒ Object
- #visit_astore(op, _ctx) ⇒ Object
- #visit_cvs(op, _ctx) ⇒ Object
- #visit_forall(op, _ctx) ⇒ Object
- #visit_get(op, _ctx) ⇒ Object
- #visit_getinterval(op, _ctx) ⇒ Object
- #visit_length(op, _ctx) ⇒ Object
- #visit_put(op, _ctx) ⇒ Object
- #visit_putinterval(_op, _ctx) ⇒ Object
- #visit_search(op, _ctx) ⇒ Object
- #visit_string(op, _ctx) ⇒ Object
- #visit_token(op, _ctx) ⇒ Object
Instance Method Details
#visit_anchorsearch(op, _ctx) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 118 def visit_anchorsearch(op, _ctx) haystack = string_value(op.target) needle = string_value(op.pattern) if haystack && needle && haystack.start_with?(needle) @stack << haystack[needle.length..] @stack << needle @stack << true else @stack << haystack @stack << false end end |
#visit_astore(op, _ctx) ⇒ Object
95 96 97 98 99 100 101 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 95 def visit_astore(op, _ctx) # astore pops N items and builds an array. The parser # already gave us the array via from_operands; just push # it back. The original semantics (`arr astore` arr is on # bottom, n items on top) are preserved. @stack << (op.array.is_a?(Array) ? op.array : []) end |
#visit_cvs(op, _ctx) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 149 def visit_cvs(op, _ctx) text = case op.value when Numeric then op.value.to_s when String then op.value when Model::Literals::StringLiteral then op.value.value when Model::Literals::Name then op.value.value else op.value.to_s end @stack << text end |
#visit_forall(op, _ctx) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 72 def visit_forall(op, _ctx) return unless op.body.is_a?(Model::Literals::Procedure) case op.collection when Array op.collection.each do |item| @stack << item op.body.body.each { |node| node.accept(self, nil) } end when Hash op.collection.each do |key, value| @stack << value @stack << key op.body.body.each { |node| node.accept(self, nil) } end when String op.collection.each_byte do |byte| @stack << byte op.body.body.each { |node| node.accept(self, nil) } end end end |
#visit_get(op, _ctx) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 26 def visit_get(op, _ctx) operand = op.operand key = op.key value = case operand when Hash operand[normalize_key(key)] when Array operand[key.to_i] when String operand.getbyte(key.to_i) when Model::Literals::Dictionary operand.entries[normalize_key(key)] when Model::Literals::ArrayLiteral operand.elements[key.to_i] when Model::Literals::StringLiteral operand.value.getbyte(key.to_i) end @stack << value end |
#visit_getinterval(op, _ctx) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 53 def visit_getinterval(op, _ctx) case op.operand when String @stack << op.operand[op.start, op.count] when Array @stack << op.operand[op.start, op.count] when Model::Literals::StringLiteral @stack << op.operand.value[op.start, op.count] when Model::Literals::ArrayLiteral @stack << op.operand.elements[op.start, op.count] else @stack << "" end end |
#visit_length(op, _ctx) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 10 def visit_length(op, _ctx) operand = op.operand value = case operand when String then operand.length when Array then operand.length when Hash then operand.length when Model::Literals::StringLiteral then operand.value.length when Model::Literals::ArrayLiteral then operand.elements.length when Model::Literals::Dictionary then operand.entries.length when Model::Literals::HexLiteral then operand.value.length / 2 else 0 end @stack << value end |
#visit_put(op, _ctx) ⇒ Object
47 48 49 50 51 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 47 def visit_put(op, _ctx) # PS put mutates in place. Our value objects are immutable. # Marked as a comment in the output so the gap is visible. @builder.comment("put: in-place mutation not supported") end |
#visit_putinterval(_op, _ctx) ⇒ Object
68 69 70 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 68 def visit_putinterval(_op, _ctx) @builder.comment("putinterval: in-place mutation not supported") end |
#visit_search(op, _ctx) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 103 def visit_search(op, _ctx) haystack = string_value(op.target) needle = string_value(op.pattern) if haystack && needle && (idx = haystack.index(needle)) post = haystack[(idx + needle.length)..] @stack << post @stack << needle @stack << haystack[0, idx] @stack << true else @stack << haystack @stack << false end end |
#visit_string(op, _ctx) ⇒ Object
145 146 147 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 145 def visit_string(op, _ctx) @stack << ("\0" * op.count.to_i) end |
#visit_token(op, _ctx) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/postsvg/visitors/ps_visitor/container.rb', line 131 def visit_token(op, _ctx) text = string_value(op.target) return @stack << false unless text # PS token splits on whitespace and parses the next token. if (match = text.match(/\A\s*(-?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?)/)) @stack << match[1].to_f @stack << text[match[0].length..] @stack << true else @stack << false end end |