Class: TEALrb::Rewriters::OpRewriter

Inherits:
Rewriter
  • Object
show all
Defined in:
lib/tealrb/rewriters.rb

Constant Summary collapse

OPCODE_METHODS =
TEALrb::Opcodes::TEALOpcodes.instance_methods.freeze
OPCODE_INSTANCE_METHODS =
TEALrb::Opcodes::BINARY_OPCODE_METHOD_MAPPING.merge(
  TEALrb::Opcodes::UNARY_OPCODE_METHOD_MAPPING
)

Instance Attribute Summary

Attributes inherited from Rewriter

#contract

Instance Method Summary collapse

Methods inherited from Rewriter

#rewrite

Constructor Details

#initializeOpRewriter

Returns a new instance of OpRewriter.



93
94
95
96
# File 'lib/tealrb/rewriters.rb', line 93

def initialize
  @skips = []
  super
end

Instance Method Details

#on_and(node) ⇒ Object



98
99
100
101
102
103
104
105
106
107
# File 'lib/tealrb/rewriters.rb', line 98

def on_and(node)
  wrap(node.children[1].source_range, '(', ')')

  op_loc = node.loc.operator
  op_loc = op_loc.resize(3) if op_loc.resize(3).source == '&& '

  replace(op_loc, '.boolean_and')

  super
end

#on_int(node) ⇒ Object



150
151
152
153
154
155
156
157
158
# File 'lib/tealrb/rewriters.rb', line 150

def on_int(node)
  if @skips.include? node
    @skips.delete(node)
  else
    wrap(node.source_range, 'int(', ')')
  end

  super
end

#on_or(node) ⇒ Object



109
110
111
112
113
114
115
116
117
# File 'lib/tealrb/rewriters.rb', line 109

def on_or(node)
  wrap(node.children[1].source_range, '(', ')')

  op_loc = node.loc.operator
  op_loc = op_loc.resize(3) if op_loc.resize(3).source == '|| '

  replace(op_loc, '.boolean_or')
  super
end

#on_return(node) ⇒ Object



119
120
121
122
123
# File 'lib/tealrb/rewriters.rb', line 119

def on_return(node)
  replace node.loc.keyword, 'abi_return'

  super
end

#on_send(node) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/tealrb/rewriters.rb', line 130

def on_send(node)
  meth_name = node.children[1]

  if OPCODE_METHODS.include? meth_name
    if %w[bytecblock intcblock pushints pushbytess switch match].include? meth_name.to_s
      @skips += node.children[2..]
    else
      params = TEALrb::Opcodes::TEALOpcodes.instance_method(meth_name).parameters
      req_params = params.count { |param| param[0] == :req }
      @skips += node.children[2..(1 + req_params.size)] unless req_params.zero?
    end
  elsif %i[comment placeholder rb].include?(meth_name)
    @skips << node.children[2]
  elsif meth_name == :[]
    @skips << node.children[2] if node.children[2].type == :int
  end

  super
end

#on_str(node) ⇒ Object



160
161
162
163
164
165
166
167
168
# File 'lib/tealrb/rewriters.rb', line 160

def on_str(node)
  if @skips.include? node
    @skips.delete(node)
  else
    wrap(node.source_range, 'byte(', ')')
  end

  super
end

#on_sym(node) ⇒ Object



170
171
172
173
174
175
176
177
178
# File 'lib/tealrb/rewriters.rb', line 170

def on_sym(node)
  if @skips.include? node
    @skips.delete(node)
  elsif node.source_range.source[/^:/]
    wrap(node.source_range, 'label(', ')')
  end

  super
end