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, bare, oncut: nil) ⇒ Object



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

def generate_code(gen, onfail, indent, bare, oncut: nil)
  gen.write Packcr.format_code(get_code(gen, onfail, indent, bare, oncut), indent: indent, unwrap: bare)
end

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



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

def generate_reverse_code(gen, onsuccess, indent, bare, oncut: nil)
  gen.write Packcr.format_code(get_reverse_code(gen, onsuccess, indent, bare, oncut), indent: indent)
end

#get_code(gen, onfail, indent, bare, 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, bare, 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.clone()) {\n    break 'L#{format("%04d", onfail)};\n}\n".freeze

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

#get_reverse_code(gen, onsuccess, indent, bare, 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
77
78
79
80
81
# File 'lib/packcr/generated/node/reference_node.rb', line 50

def get_reverse_code(gen, onsuccess, indent, bare, 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
  when :rs
    erbout = +""
    erbout << "/* lib/packcr/templates/node/reference_reverse.rs.erb */\n\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