Module: Postsvg::Visitors::PsVisitor::Dictionary

Included in:
Postsvg::Visitors::PsVisitor
Defined in:
lib/postsvg/visitors/ps_visitor/dictionary.rb

Overview

Dictionary operator handlers (dict-specific only). Generic collection operators (get / put / length / getinterval / putinterval) live in the Container module because they dispatch on operand type at runtime.

Instance Method Summary collapse

Instance Method Details

#dict_stackObject



82
83
84
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 82

def dict_stack
  @dict_stack ||= [{}]
end

#visit_begin(_op, _ctx) ⇒ Object



19
20
21
22
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 19

def visit_begin(_op, _ctx)
  value = @stack.pop
  @dict_stack << (value.is_a?(Hash) ? value : {})
end

#visit_countdictstack(_op, _ctx) ⇒ Object



65
66
67
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 65

def visit_countdictstack(_op, _ctx)
  @stack << @dict_stack.length
end

#visit_currentdict(_op, _ctx) ⇒ Object



61
62
63
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 61

def visit_currentdict(_op, _ctx)
  @stack << @dict_stack.last
end

#visit_def(op, _ctx) ⇒ Object



28
29
30
31
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 28

def visit_def(op, _ctx)
  key = normalize_key(op.key)
  @dict_stack.last[key] = op.value
end

#visit_dict(_op, _ctx) ⇒ Object

The base PsVisitor class initializes @dict_stack as a single-element array (the global dictionary). Modules assume it exists; they do not re-initialize.



15
16
17
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 15

def visit_dict(_op, _ctx)
  @stack << {}
end

#visit_dictstack(_op, _ctx) ⇒ Object



69
70
71
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 69

def visit_dictstack(_op, _ctx)
  @stack << @dict_stack.dup
end

#visit_end(_op, _ctx) ⇒ Object



24
25
26
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 24

def visit_end(_op, _ctx)
  @dict_stack.pop if @dict_stack.length > 1
end

#visit_known(op, _ctx) ⇒ Object



55
56
57
58
59
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 55

def visit_known(op, _ctx)
  key = normalize_key(op.key)
  dict = op.dict.is_a?(Hash) ? op.dict : {}
  @stack << dict.key?(key)
end

#visit_load(op, _ctx) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 33

def visit_load(op, _ctx)
  key = normalize_key(op.key)
  @dict_stack.reverse_each do |dict|
    if dict.key?(key)
      @stack << dict[key]
      return
    end
  end
  raise UndefinedOperatorError, "no value bound to /#{key}"
end

#visit_maxlength(op, _ctx) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 73

def visit_maxlength(op, _ctx)
  # PS dictionaries can grow dynamically; report current size.
  case op.operand
  when Hash then @stack << op.operand.length
  when Model::Literals::Dictionary then @stack << op.operand.entries.length
  else @stack << 0
  end
end

#visit_store(op, _ctx) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/postsvg/visitors/ps_visitor/dictionary.rb', line 44

def visit_store(op, _ctx)
  key = normalize_key(op.key)
  @dict_stack.reverse_each do |dict|
    if dict.key?(key)
      dict[key] = op.value
      return
    end
  end
  @dict_stack.last[key] = op.value
end