Class: Packcr::Node::ReferenceNode

Inherits:
Packcr::Node show all
Defined in:
lib/packcr/node/reference_node.rb,
lib/packcr/generated/node/reference_node.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Packcr::Node

#alt, #nodes, #seq, #sequence?, #setup, #verify_captures

Constructor Details

#initialize(name = nil, var = nil, line = nil, col = nil) ⇒ ReferenceNode

Returns a new instance of ReferenceNode.



6
7
8
9
10
11
# File 'lib/packcr/node/reference_node.rb', line 6

def initialize(name = nil, var = nil, line = nil, col = nil)
  @name = name
  @var = var
  @line = line
  @col = col
end

Instance Attribute Details

#colObject

Returns the value of attribute col.



4
5
6
# File 'lib/packcr/node/reference_node.rb', line 4

def col
  @col
end

#indexObject

Returns the value of attribute index.



4
5
6
# File 'lib/packcr/node/reference_node.rb', line 4

def index
  @index
end

#lineObject

Returns the value of attribute line.



4
5
6
# File 'lib/packcr/node/reference_node.rb', line 4

def line
  @line
end

#nameObject

Returns the value of attribute name.



4
5
6
# File 'lib/packcr/node/reference_node.rb', line 4

def name
  @name
end

#ruleObject

Returns the value of attribute rule.



4
5
6
# File 'lib/packcr/node/reference_node.rb', line 4

def rule
  @rule
end

#varObject

Returns the value of attribute var.



4
5
6
# File 'lib/packcr/node/reference_node.rb', line 4

def var
  @var
end

Instance Method Details

#debug_dump(indent = 0) ⇒ Object



13
14
15
16
17
# File 'lib/packcr/node/reference_node.rb', line 13

def debug_dump(indent = 0)
  $stdout.print "#{" " * indent}Reference(var:'#{var || "(null)"}', index:"
  Packcr.dump_integer_value(index)
  $stdout.print ", name:'#{name}', rule:'#{rule&.name || "(null)"}')\n"
end

#generate_code(gen, onfail, indent, unwrap, oncut: nil) ⇒ Object



23
24
25
# File 'lib/packcr/node/reference_node.rb', line 23

def generate_code(gen, onfail, indent, unwrap, oncut: nil)
  get_code(gen, onfail, indent, unwrap, oncut)
end

#generate_reverse_code(gen, onsuccess, indent, unwrap, oncut: nil) ⇒ Object



27
28
29
# File 'lib/packcr/node/reference_node.rb', line 27

def generate_reverse_code(gen, onsuccess, indent, unwrap, oncut: nil)
  get_reverse_code(gen, onsuccess, indent, unwrap, oncut)
end

#get_code(gen, onfail, indent, unwrap, oncut) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/packcr/generated/node/reference_node.rb', line 4

def get_code(gen, onfail, indent, unwrap, oncut)
  case gen.lang
  when :c
    erbout = +""
    if index.nil?
      erbout << "{\n    packcr_rule_set_t *l = NULL;\n    if (limits && ctx->position_offset == offset && packcr_rule_set__index(ctx->auxil, limits, packcr_evaluate_rule_#{name}) == PACKCR_VOID_VALUE) {\n        l = limits;\n    }\n    if (!packcr_apply_rule(ctx, packcr_evaluate_rule_#{name}, &chunk->thunks, NULL, offset".freeze
    else
      erbout << "{\n    packcr_rule_set_t *l = NULL;\n    if (limits && ctx->position_offset == offset && packcr_rule_set__index(ctx->auxil, limits, packcr_evaluate_rule_#{name}) == PACKCR_VOID_VALUE) {\n        l = limits;\n    }\n    if (!packcr_apply_rule(ctx, packcr_evaluate_rule_#{name}, &chunk->thunks, &(chunk->values.buf[#{index}]), offset".freeze

    end
    if gen.location
      erbout << ", offset_loc".freeze
    end
    erbout << ", l)) goto L#{format("%04d", onfail)};\n}\n".freeze
    erbout
  when :rb
    erbout = +""
    if index.nil?
      erbout << "if limits && @position_offset == offset && !limits[:evaluate_rule_#{name}]\n  if !apply_rule(:evaluate_rule_#{name}, answer.thunks, nil, 0, offset".freeze
      if gen.location
        erbout << ", offset_loc".freeze
      end
      erbout << ", limits: limits)\n    throw(#{onfail})\n  end\nelse\n  if !apply_rule(:evaluate_rule_#{name}, answer.thunks, nil, 0, offset".freeze
    else
      erbout << "if limits && @position_offset == offset && !limits[:evaluate_rule_#{name}]\n  if !apply_rule(:evaluate_rule_#{name}, answer.thunks, answer.values, #{index}, offset".freeze
      if gen.location
        erbout << ", offset_loc".freeze
      end
      erbout << ", limits: limits)\n    throw(#{onfail})\n  end\nelse\n  if !apply_rule(:evaluate_rule_#{name}, answer.thunks, answer.values, #{index}, offset".freeze

    end
    if gen.location
      erbout << ", offset_loc".freeze
    end
    erbout << ")\n    throw(#{onfail})\n  end\nend\n".freeze
    erbout
  when :rs
    erbout = +""
    erbout << "if !self.apply_rule(Rule::#{Packcr.camelize(name)}, &mut answer, #{index || 0}, offset, &limits) {\n    return throw(#{onfail});\n}\n".freeze

    erbout
  else
    raise "unknown lang #{gen.lang}"
  end
end

#get_reverse_code(gen, onsuccess, indent, unwrap, oncut) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/packcr/generated/node/reference_node.rb', line 50

def get_reverse_code(gen, onsuccess, indent, unwrap, oncut)
  case gen.lang
  when :rb
    erbout = +""
    if index.nil?
      erbout << "if limits && @position_offset == offset && !limits[:evaluate_rule_#{name}]\n  if apply_rule(:evaluate_rule_#{name}, answer.thunks, nil, 0, offset".freeze
      if gen.location
        erbout << ", offset_loc".freeze
      end
      erbout << ", limits: limits)\n    throw(#{onsuccess})\n  end\nelse\n  if apply_rule(:evaluate_rule_#{name}, answer.thunks, nil, 0, offset".freeze
    else
      erbout << "if limits && @position_offset == offset && !limits[:evaluate_rule_#{name}]\n  if apply_rule(:evaluate_rule_#{name}, answer.thunks, answer.values, #{index}, offset".freeze
      if gen.location
        erbout << ", offset_loc".freeze
      end
      erbout << ", limits: limits)\n    throw(#{onsuccess})\n  end\nelse\n  if apply_rule(:evaluate_rule_#{name}, answer.thunks, answer.values, #{index}, offset".freeze

    end
    if gen.location
      erbout << ", offset_loc".freeze
    end
    erbout << ")\n    throw(#{onsuccess})\n  end\nend\n".freeze
    erbout
  else
    raise "unknown lang #{gen.lang}"
  end
end


66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/packcr/node/reference_node.rb', line 66

def link_references(ctx)
  rule = ctx.root.rule(name)
  if rule
    unless rule.is_a?(Packcr::Node::RuleNode)
      raise "unexpected node type #{rule.class}"
    end

    rule.add_ref
    self.rule = rule
  else
    ctx.error line + 1, col + 1, "No definition of rule '#{name}'"
  end
end

#reachabilityObject



31
32
33
# File 'lib/packcr/node/reference_node.rb', line 31

def reachability
  Packcr::CODE_REACH__BOTH
end

#reversible?(gen) ⇒ Boolean

Returns:

  • (Boolean)


19
20
21
# File 'lib/packcr/node/reference_node.rb', line 19

def reversible?(gen)
  gen.lang == :rb
end

#setup_rule(rule) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/packcr/node/reference_node.rb', line 35

def setup_rule(rule)
  rule.has_ref = true
  return unless var

  i = rule.vars.index do |ref|
    unless ref.is_a?(Packcr::Node::ReferenceNode)
      raise "Unexpected node type: #{ref.class}"
    end

    var == ref.var
  end
  if !i
    i = rule.vars.length
    rule.vars << self
  end
  @index = i
end

#to_hObject



80
81
82
83
84
85
86
# File 'lib/packcr/node/reference_node.rb', line 80

def to_h
  {
    type: :reference,
    name: name,
    var: var,
  }
end

#verify_variables(vars) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/packcr/node/reference_node.rb', line 53

def verify_variables(vars)
  return if index.nil?

  found = vars.any? do |var|
    unless var.is_a?(Packcr::Node::ReferenceNode)
      raise "unexpected var: #{var.class}"
    end

    index == var.index
  end
  vars.push(self) if !found
end