Class: Furnace::AVM2::Transform::NFNormalize
- Inherits:
-
Object
- Object
- Furnace::AVM2::Transform::NFNormalize
- Includes:
- Visitor
- Defined in:
- lib/furnace-avm2/transform/nf_normalize.rb
Constant Summary collapse
- COERCE_MAP =
{ :coerce_a => :any, :coerce_b => :bool, :coerce_s => :string, }
- CONVERT_MAP =
{ :convert_i => :integer, :convert_u => :unsigned, :convert_d => :double, :convert_s => :string, :convert_o => :object, }
- ForInMatcher =
AST::Matcher.new do [:while, [:has_next2, capture(:object_reg), capture(:index_reg)], [:begin, [ either_multi[ [ :set_local, capture(:value_reg) ], [ :set_slot, capture(:value_reg), [:get_scope_object, 1] ], ], [ either[:coerce, :convert], capture(:value_type), [ capture(:iterator), [:get_local, backref(:object_reg)], [:get_local, backref(:index_reg)]]]], capture_rest(:body)]] end
- ForInIndexMatcher =
AST::Matcher.new do [:set_local, backref(:index_reg), [:integer, 0]] end
- ForInObjectMatcher =
AST::Matcher.new do [:set_local, backref(:object_reg), [:coerce, :any, capture(:root)]] end
- SuperfluousContinueMatcher =
AST::Matcher.new do [:continue] end
Instance Method Summary collapse
- #on_coerce_imm(node) ⇒ Object (also: #on_coerce_a, #on_coerce_b, #on_coerce_s)
- #on_convert_imm(node) ⇒ Object (also: #on_convert_i, #on_convert_u, #on_convert_d, #on_convert_s, #on_convert_o)
- #on_nop(node) ⇒ Object
- #on_while(node) ⇒ Object
- #remove_useless_return ⇒ Object
- #transform(nf) ⇒ Object
Instance Method Details
#on_coerce_imm(node) ⇒ Object Also known as: on_coerce_a, on_coerce_b, on_coerce_s
31 32 33 34 35 36 37 |
# File 'lib/furnace-avm2/transform/nf_normalize.rb', line 31 def on_coerce_imm(node) expr, = node.children node.update(:coerce, [ COERCE_MAP[node.type], expr ]) end |
#on_convert_imm(node) ⇒ Object Also known as: on_convert_i, on_convert_u, on_convert_d, on_convert_s, on_convert_o
50 51 52 53 54 55 56 |
# File 'lib/furnace-avm2/transform/nf_normalize.rb', line 50 def on_convert_imm(node) expr, = node.children node.update(:convert, [ CONVERT_MAP[node.type], expr ]) end |
#on_nop(node) ⇒ Object
21 22 23 |
# File 'lib/furnace-avm2/transform/nf_normalize.rb', line 21 def on_nop(node) node.update(:remove) end |
#on_while(node) ⇒ Object
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/furnace-avm2/transform/nf_normalize.rb', line 92 def on_while(node) *whatever, code = node.children if SuperfluousContinueMatcher.match code.children.last code.children.slice! -1 end if captures = ForInMatcher.match(node) parent = node.parent case captures[:iterator] when :next_name type = :for_in when :next_value type = :for_each_in else return end index_node = object_node = nil loop_index = parent.children.index(node) parent.children[0..loop_index].reverse_each do |parent_node| if ForInIndexMatcher.match(parent_node, captures) index_node = parent_node elsif ForInObjectMatcher.match(parent_node, captures) object_node = parent_node end break if index_node && object_node end return unless index_node && object_node index_node.update(:remove) object_node.update(:remove) node.update(type, [ captures[:value_reg], captures[:value_type], captures[:object_reg], AST::Node.new(:begin, captures[:body]) ]) end end |
#remove_useless_return ⇒ Object
15 16 17 18 19 |
# File 'lib/furnace-avm2/transform/nf_normalize.rb', line 15 def remove_useless_return if @nf.children.last.type == :return_void @nf.children.slice! -1 end end |
#transform(nf) ⇒ Object
6 7 8 9 10 11 12 13 |
# File 'lib/furnace-avm2/transform/nf_normalize.rb', line 6 def transform(nf) @nf = nf.normalize_hierarchy! remove_useless_return visit @nf @nf end |