Class: Stupidedi::Parser::InstructionTable::NonEmpty
- Inherits:
-
Stupidedi::Parser::InstructionTable
- Object
- Stupidedi::Parser::InstructionTable
- Stupidedi::Parser::InstructionTable::NonEmpty
- Defined in:
- lib/stupidedi/parser/instruction_table.rb
Constant Summary
Constants inherited from Stupidedi::Parser::InstructionTable
Instance Attribute Summary collapse
- #instructions ⇒ Array<Instruction> readonly
Instance Method Summary collapse
- #at(segment_use) ⇒ Instruction
- #constraints
- #copy(changes = {}) ⇒ InstructionTable
- #drop(count) ⇒ InstructionTable
- #hash
-
#initialize(instructions, pop) ⇒ NonEmpty
constructor
A new instance of NonEmpty.
- #matches(segment_tok, strict = false, mode = :insert) ⇒ Array<Instruction>
- #pop(count) ⇒ InstructionTable
-
#pretty_print(q)
:nocov:.
- #push(instructions) ⇒ InstructionTable
Methods inherited from Stupidedi::Parser::InstructionTable
Methods included from Inspect
Constructor Details
#initialize(instructions, pop) ⇒ NonEmpty
Returns a new instance of NonEmpty.
15 16 17 18 19 20 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 15 def initialize(instructions, pop) @instructions, @pop = instructions.freeze, pop @__push = Hash.new @__drop = Hash.new end |
Instance Attribute Details
#instructions ⇒ Array<Instruction> (readonly)
11 12 13 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 11 def instructions @instructions end |
Instance Method Details
#at(segment_use) ⇒ Instruction
34 35 36 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 34 def at(segment_use) @instructions.find{|op| op.segment_use.eql?(segment_use) } end |
#constraints
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 58 def constraints @__constraints ||= begin constraints = Hash.new # Group instructions by segment identifier grouped = Hash.new{|h,k| h[k] = [] } @instructions.each{|op| grouped[op.segment_id] << op } # For each group of instructions that have the same segment # id, build a constraint table that can distinguish them grouped.each do |segment_id, instructions| constraints[segment_id] = ConstraintTable.build(instructions) end constraints end end |
#copy(changes = {}) ⇒ InstructionTable
27 28 29 30 31 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 27 def copy(changes = {}) NonEmpty.new \ changes.fetch(:instructions, @instructions), changes.fetch(:pop, @pop) end |
#drop(count) ⇒ InstructionTable
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 86 def drop(count) if count.zero? self else @__drop[count] ||= begin # Calculate the fewest number of instructions we can drop. We # drop this many to construct the next InstructionTable, from # which we drop the remaining number of instructions. smallest = @instructions.length top = @instructions.take(@instructions.length - @pop.length) top.each do |i| unless i.drop_count.zero? or smallest < i.drop_count smallest = i.drop_count end end if smallest == count # There are no intermediate steps to take, because we can't drop # any fewer than the given number of instructions. remaining = @instructions.drop(count) # Adjust the drop_count for each remaining instruction except # those that belong to the parent InstructionTable @pop top, pop = remaining.split_at(remaining.length - @pop.length) top.map!{|op| op.copy(:drop_count => op.drop_count - count) } top.concat(pop) NonEmpty.new(top, @pop) else drop(smallest).drop(count - smallest) end end end end |
#hash
22 23 24 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 22 def hash [NonEmpty, state].hash end |
#matches(segment_tok, strict = false, mode = :insert) ⇒ Array<Instruction>
50 51 52 53 54 55 56 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 50 def matches(segment_tok, strict = false, mode = :insert) if constraints.defined_at?(segment_tok.id) constraints.at(segment_tok.id).matches(segment_tok, strict, mode) else [] end end |
#pop(count) ⇒ InstructionTable
77 78 79 80 81 82 83 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 77 def pop(count) if count.zero? self else @pop.pop(count - 1) end end |
#pretty_print(q)
This method returns an undefined value.
:nocov:
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 124 def pretty_print(q) q.text("InstructionTable") q.group(2, "(", ")") do q.breakable "" index = 0 @instructions.each do |e| index += 1 unless q.current_group.first? q.text "," q.breakable end q.text "#{"% 2s" % index}: " q.pp e end end end |
#push(instructions) ⇒ InstructionTable
39 40 41 42 43 44 45 46 47 |
# File 'lib/stupidedi/parser/instruction_table.rb', line 39 def push(instructions) @__push[instructions] ||= begin bottom = @instructions.map do |op| op.copy(:pop_count => op.pop_count + 1) end NonEmpty.new(instructions + bottom, self) end end |