Class: Packcr::Node::SequenceNode

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Packcr::Node

#alt, #link_references, #reversible?, #setup, #setup_rule, #verify_captures, #verify_variables

Constructor Details

#initialize(*nodes, cut: false) ⇒ SequenceNode

Returns a new instance of SequenceNode.



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

def initialize(*nodes, cut: false)
  super()
  self.nodes = nodes
  @cut = cut
end

Instance Attribute Details

#nodesObject

Returns the value of attribute nodes.



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

def nodes
  @nodes
end

Instance Method Details

#debug_dump(indent = 0) ⇒ Object



42
43
44
45
46
47
48
# File 'lib/packcr/node/sequence_node.rb', line 42

def debug_dump(indent = 0)
  $stdout.print "#{" " * indent}Sequence(max:#{max}, len:#{nodes.length}#{@cut ? ", cut: true" : ""}) {\n"
  nodes.each do |child_node|
    child_node.debug_dump(indent + 2)
  end
  $stdout.print "#{" " * indent}}\n"
end

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



56
57
58
# File 'lib/packcr/node/sequence_node.rb', line 56

def generate_code(gen, onfail, indent, bare, oncut: nil)
  gen.write Packcr.format_code(get_code(gen, onfail, 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
# File 'lib/packcr/generated/node/sequence_node.rb', line 4

def get_code(gen, onfail, indent, bare, oncut)
  case gen.lang
  when :c
    erbout = +""
    if @cut && oncut
      onfail = oncut
      oncut = nil
    end
    nodes.each_with_index do |expr, i|
      erbout << "#{gen.generate_code(expr, onfail, 0, false, oncut: oncut)}".freeze
      next unless expr.reachability == Packcr::CODE_REACH__ALWAYS_FAIL

      if i + 1 < nodes.length
        erbout << "/* unreachable codes omitted */\n".freeze
      end
      break
    end
    erbout
  when :rb
    erbout = +""
    if @cut && oncut
      onfail = oncut
      oncut = nil
    end
    nodes.each_with_index do |expr, i|
      erbout << "#{gen.generate_code(expr, onfail, 0, false, oncut: oncut)}".freeze
      next unless expr.reachability == Packcr::CODE_REACH__ALWAYS_FAIL

      if i + 1 < nodes.length
        erbout << "# unreachable codes omitted\n".freeze
      end
      break
    end
    erbout
  end
end

#maxObject



50
51
52
53
54
# File 'lib/packcr/node/sequence_node.rb', line 50

def max
  m = 1
  m <<= 1 while m < @nodes.length
  m
end

#reachabilityObject



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/packcr/node/sequence_node.rb', line 60

def reachability
  r = Packcr::CODE_REACH__ALWAYS_SUCCEED
  nodes.each do |expr|
    case expr.reachability
    when Packcr::CODE_REACH__ALWAYS_FAIL
      return Packcr::CODE_REACH__ALWAYS_FAIL
    when Packcr::CODE_REACH__BOTH
      r = Packcr::CODE_REACH__BOTH
    end
  end
  r
end

#seq(node, cut: false) ⇒ Object



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
# File 'lib/packcr/node/sequence_node.rb', line 16

def seq(node, cut: false)
  if node&.sequence?
    node.nodes.each do |child|
      seq(child, cut: cut)
      cut = false
    end
    return self
  end

  if cut
    if node
      node = Packcr::Node::SequenceNode.new(node, cut: true)
    else
      node = Packcr::Node::SequenceNode.new(cut: true)
    end
  end
  if node
    if @nodes.last.sequence?
      @nodes.last.seq(node)
    else
      @nodes << node
    end
  end
  self
end

#sequence?Boolean

Returns:

  • (Boolean)


12
13
14
# File 'lib/packcr/node/sequence_node.rb', line 12

def sequence?
  true
end

#to_hObject



73
74
75
76
77
78
# File 'lib/packcr/node/sequence_node.rb', line 73

def to_h
  {
    type: :sequence,
    nodes: nodes.map(&:to_h),
  }
end