Class: Wardite::Revisitor
- Inherits:
-
Object
- Object
- Wardite::Revisitor
- Defined in:
- lib/wardite/revisitor.rb
Instance Attribute Summary collapse
Instance Method Summary collapse
- #fetch_ops_while_else_or_end(pc_start) ⇒ Object
- #fetch_ops_while_end(pc_start) ⇒ Object
-
#initialize(ops) ⇒ Revisitor
constructor
A new instance of Revisitor.
- #revisit! ⇒ Object
Constructor Details
#initialize(ops) ⇒ Revisitor
Returns a new instance of Revisitor.
8 9 10 |
# File 'lib/wardite/revisitor.rb', line 8 def initialize(ops) @ops = ops end |
Instance Attribute Details
Instance Method Details
#fetch_ops_while_else_or_end(pc_start) ⇒ Object
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 |
# File 'lib/wardite/revisitor.rb', line 44 def fetch_ops_while_else_or_end(pc_start) cursor = pc_start depth = 0 loop { cursor += 1 inst = @ops[cursor] case inst&.code when nil raise EvalError, "end op not found" when :if, :block, :loop depth += 1 when :else if depth == 0 return cursor end # do not touch depth when :end if depth == 0 return cursor else depth -= 1 end else # nop end } raise "not found corresponding end" end |
#fetch_ops_while_end(pc_start) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/wardite/revisitor.rb', line 76 def fetch_ops_while_end(pc_start) cursor = pc_start depth = 0 loop { cursor += 1 inst = @ops[cursor] case inst&.code when nil raise EvalError, "end op not found" when :if, :block, :loop depth += 1 when :end if depth == 0 return cursor else depth -= 1 end else # nop end } raise "not found corresponding end" end |
#revisit! ⇒ Object
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/wardite/revisitor.rb', line 13 def revisit! @ops.each_with_index do |op, idx| case op.code when :block next_pc = fetch_ops_while_end(idx) if op.[:end_pos] != next_pc raise "mismatched end_pos for block at #{op}: #{op.[:end_pos]} vs #{next_pc}" end when :loop next_pc = fetch_ops_while_end(idx) if op.[:end_pos] != next_pc raise "mismatched end_pos for loop at #{op}: #{op.[:end_pos]} vs #{next_pc}" end when :if next_pc = fetch_ops_while_end(idx) else_pc = fetch_ops_while_else_or_end(idx) if op.[:end_pos] != next_pc raise "mismatched end_pos for if at #{op}: #{op.[:end_pos]} vs #{next_pc}" end if op.[:else_pos] != else_pc raise "mismatched else_pos for if at #{op}: #{op.[:else_pos]} vs #{else_pc}" end end end end |