Class: Packcr::Node::AlternateNode
- Inherits:
-
Packcr::Node
- Object
- Packcr::Node
- Packcr::Node::AlternateNode
- Defined in:
- lib/packcr/node/alternate_node.rb,
lib/packcr/generated/node/alternate_node.rb
Instance Attribute Summary collapse
-
#nodes ⇒ Object
Returns the value of attribute nodes.
Instance Method Summary collapse
- #alt(node) ⇒ Object
- #debug_dump(indent = 0) ⇒ Object
- #generate_code(gen, onfail, indent, bare, oncut: nil) ⇒ Object
- #get_code(gen, onfail, indent, bare, oncut) ⇒ Object
-
#initialize(*nodes) ⇒ AlternateNode
constructor
A new instance of AlternateNode.
- #max ⇒ Object
- #reachability ⇒ Object
- #to_h ⇒ Object
- #verify_captures(ctx, capts) ⇒ Object
- #verify_variables(vars) ⇒ Object
Methods inherited from Packcr::Node
#link_references, #reversible?, #seq, #sequence?, #setup, #setup_rule
Constructor Details
#initialize(*nodes) ⇒ AlternateNode
Returns a new instance of AlternateNode.
6 7 8 9 |
# File 'lib/packcr/node/alternate_node.rb', line 6 def initialize(*nodes) super() self.nodes = nodes end |
Instance Attribute Details
#nodes ⇒ Object
Returns the value of attribute nodes.
4 5 6 |
# File 'lib/packcr/node/alternate_node.rb', line 4 def nodes @nodes end |
Instance Method Details
#alt(node) ⇒ Object
11 12 13 14 |
# File 'lib/packcr/node/alternate_node.rb', line 11 def alt(node) @nodes << node if node self end |
#debug_dump(indent = 0) ⇒ Object
16 17 18 19 20 21 22 |
# File 'lib/packcr/node/alternate_node.rb', line 16 def debug_dump(indent = 0) $stdout.print "#{" " * indent}Alternate(max:#{max}, len:#{nodes.length}) {\n" nodes.each do |node| node.debug_dump(indent + 2) end $stdout.print "#{" " * indent}}\n" end |
#generate_code(gen, onfail, indent, bare, oncut: nil) ⇒ Object
30 31 32 |
# File 'lib/packcr/node/alternate_node.rb', line 30 def generate_code(gen, onfail, indent, , oncut: nil) gen.write Packcr.format_code(get_code(gen, onfail, indent, , oncut), indent: indent, unwrap: ) 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 49 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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/packcr/generated/node/alternate_node.rb', line 4 def get_code(gen, onfail, indent, , oncut) case gen.lang when :c erbout = +"" m = gen.next_label erbout << "{\n const size_t p = ctx->position_offset;\n".freeze if gen.location erbout << " const packcr_location_t p_loc = ctx->position_offset_loc;\n".freeze end erbout << " const size_t n = chunk->thunks.len;\n".freeze nodes.each_with_index do |expr, i| c = i + 1 < nodes.length l = gen.next_label r = expr.reachability erbout << "#{gen.generate_code(expr, l, 4, false)}".freeze case r when Packcr::CODE_REACH__ALWAYS_SUCCEED if c erbout << " /* unreachable codes omitted */\n".freeze end break when Packcr::CODE_REACH__BOTH erbout << " goto L#{format("%04d", m)};\n".freeze end erbout << "L#{format("%04d", l)}:;\n ctx->position_offset = p;\n".freeze if gen.location erbout << " ctx->position_offset_loc = p_loc;\n".freeze end erbout << " packcr_thunk_array__revert(ctx->auxil, &chunk->thunks, n);\n".freeze next if c erbout << " goto L#{format("%04d", onfail)};\n".freeze end erbout << "L#{format("%04d", m)}:;\n}\n".freeze erbout when :rb erbout = +"" m = gen.next_label erbout << "catch(#{m}) do\n pos#{gen.level} = @position_offset\n".freeze if gen.location erbout << " p_loc#{gen.level} = @position_offset_loc\n".freeze end erbout << " n#{gen.level} = answer.thunks.length\n".freeze nodes.each_with_index do |expr, i| c = i + 1 < nodes.length if expr.reversible?(gen) erbout << "#{gen.generate_code(expr, m, 2, false, reverse: true, oncut: onfail)}".freeze else l = gen.next_label erbout << " catch(#{l}) do\n".freeze r = expr.reachability erbout << "#{gen.generate_code(expr, l, 4, false, oncut: onfail)}".freeze case r when Packcr::CODE_REACH__ALWAYS_SUCCEED if c erbout << " # unreachable codes omitted\n".freeze end erbout << " end\n".freeze break when Packcr::CODE_REACH__BOTH erbout << " throw(#{m})\n".freeze end erbout << " end\n".freeze end erbout << " @position_offset = pos#{gen.level}\n".freeze if gen.location erbout << " @position_offset_loc = p_loc#{gen.level}\n".freeze end erbout << " answer.thunks[n#{gen.level}..-1] = []\n".freeze next if c erbout << " throw(#{onfail})\n".freeze end erbout << "end\n".freeze erbout end end |
#max ⇒ Object
24 25 26 27 28 |
# File 'lib/packcr/node/alternate_node.rb', line 24 def max m = 1 m <<= 1 while m < @nodes.length m end |
#reachability ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/packcr/node/alternate_node.rb', line 34 def reachability r = Packcr::CODE_REACH__ALWAYS_FAIL nodes.each do |expr| case expr.reachability when Packcr::CODE_REACH__ALWAYS_SUCCEED return Packcr::CODE_REACH__ALWAYS_SUCCEED when Packcr::CODE_REACH__BOTH r = Packcr::CODE_REACH__BOTH end end r end |
#to_h ⇒ Object
76 77 78 79 80 81 |
# File 'lib/packcr/node/alternate_node.rb', line 76 def to_h { type: :alternate, nodes: nodes&.map(&:to_h), } end |
#verify_captures(ctx, capts) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/packcr/node/alternate_node.rb', line 64 def verify_captures(ctx, capts) m = capts.length v = capts.dup nodes.each do |node| v = v[0, m] node.verify_captures(ctx, v) v[m...-1].each do |added_node| capts.push(added_node) end end end |
#verify_variables(vars) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/packcr/node/alternate_node.rb', line 47 def verify_variables(vars) m = vars.length v = vars.dup nodes.each do |node| v = v[0, m] node.verify_variables(v) v[m...-1].each do |added_node| found = vars[m...-1].any? do |added_var| added_node.index == added_var.index end if !found vars.push(added_node) end end end end |