tealrb 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,9 +4,11 @@ module TEALrb
4
4
  module Rewriters
5
5
  class Rewriter < Parser::TreeRewriter
6
6
  include RuboCop::AST::Traversal
7
+ attr_reader :contract
7
8
 
8
- def rewrite(processed_source)
9
+ def rewrite(processed_source, contract)
9
10
  @comments = processed_source.comments
11
+ @contract = contract
10
12
  super(processed_source.buffer, processed_source.ast)
11
13
  end
12
14
  end
@@ -27,29 +29,6 @@ module TEALrb
27
29
  end
28
30
  end
29
31
 
30
- class InternalMethodRewriter < Rewriter
31
- def on_send(node)
32
- teal_methods = TEALrb::Contract.class_variable_get(:@@active_contract).class.teal_methods
33
-
34
- method_name = node.loc.selector.source.to_sym
35
-
36
- if teal_methods.keys.include? method_name
37
- param_names = teal_methods[method_name].parameters.map(&:last)
38
-
39
- pre_string = StringIO.new
40
- param_names.each_with_index do |param, i|
41
- scratch_name = [method_name, param].map(&:to_s).join(': ')
42
-
43
- pre_string.puts "@scratch.store('#{scratch_name}', #{node.children[i + 2].loc.expression.source})"
44
- end
45
-
46
- replace node.source_range, "#{pre_string.string}\n#{method_name}"
47
- end
48
-
49
- super
50
- end
51
- end
52
-
53
32
  class MethodRewriter < Rewriter
54
33
  def on_def(node)
55
34
  replace node.source_range, node.body.source
@@ -59,22 +38,11 @@ module TEALrb
59
38
  def on_block(node)
60
39
  replace node.source_range, node.body.source
61
40
  end
62
-
63
- def on_send(node)
64
- remove node.loc.selector if node.loc.selector.source == 'subroutine' || node.loc.selector.source == 'teal'
65
-
66
- # @teal_methods[:name] = ->(*args) { ... } becomes ->(*args) { ... }
67
- if ['@teal_methods', '@subroutines'].include? node.children[0]&.source
68
- replace node.source_range, node.children[3].body.source
69
- end
70
-
71
- super
72
- end
73
41
  end
74
42
 
75
43
  class AssignRewriter < Rewriter
76
44
  def on_lvasgn(node)
77
- wrap(node.children[1].source_range, '-> { ', ' }')
45
+ wrap(node.children[1].source_range, '-> {', '}')
78
46
  super
79
47
  end
80
48
 
@@ -84,12 +52,12 @@ module TEALrb
84
52
  end
85
53
 
86
54
  def on_ivasgn(node)
87
- wrap(node.children[1].source_range, '-> { ', ' }')
55
+ wrap(node.children[1].source_range, '-> {', ' }')
88
56
  super
89
57
  end
90
58
 
91
59
  def on_ivar(node)
92
- insert_after(node.loc.name, '.call') unless ['@teal_methods', '@subroutines', '@scratch'].include? node.source
60
+ insert_after(node.loc.name, '.call')
93
61
  super
94
62
  end
95
63
 
@@ -154,34 +122,26 @@ module TEALrb
154
122
  super
155
123
  end
156
124
 
157
- OPCODE_METHODS = TEALrb::Opcodes::AllOpcodes.instance_methods.freeze
125
+ OPCODE_METHODS = TEALrb::Opcodes::TEALOpcodes.instance_methods.freeze
126
+ OPCODE_INSTANCE_METHODS = TEALrb::Opcodes::BINARY_OPCODE_METHOD_MAPPING.merge(
127
+ TEALrb::Opcodes::UNARY_OPCODE_METHOD_MAPPING
128
+ )
158
129
 
159
130
  def on_send(node)
160
131
  meth_name = node.children[1]
161
132
 
162
133
  if OPCODE_METHODS.include? meth_name
163
- if meth_name[/(byte|int)cblock/]
134
+ if %w[bytecblock intcblock pushints pushbytess switch match].include? meth_name.to_s
164
135
  @skips += node.children[2..]
165
136
  else
166
- params = TEALrb::Opcodes::AllOpcodes.instance_method(meth_name).parameters
137
+ params = TEALrb::Opcodes::TEALOpcodes.instance_method(meth_name).parameters
167
138
  req_params = params.count { |param| param[0] == :req }
168
139
  @skips += node.children[2..(1 + req_params.size)] unless req_params.zero?
169
140
  end
170
- elsif %i[comment placeholder rb].include?(meth_name) ||
171
- (%i[[] []=].include?(meth_name) &&
172
- (
173
- %i[@scratch @teal_methods Gtxn
174
- AppArgs].include?(node.children[0].children.last) ||
175
- node.children[0].children.first&.children&.last == :Txna
176
- ))
177
-
141
+ elsif %i[comment placeholder rb].include?(meth_name)
178
142
  @skips << node.children[2]
179
- elsif node.children.first&.children&.last == :@scratch && meth_name[/=$/]
180
- nil
181
- elsif %i[@scratch Gtxn].include? node.children.first&.children&.last
182
- @skips << node.children.last
183
- elsif %i[Accounts ApplicationArgs Assets Apps Logs].include? node.children.first&.children&.last
184
- @skips << node.children.last if node.children.last.int_type?
143
+ elsif meth_name == :[]
144
+ @skips << node.children[2] if node.children[2].type == :int
185
145
  end
186
146
 
187
147
  super
@@ -222,9 +182,15 @@ module TEALrb
222
182
  def on_if(node)
223
183
  unless node.loc.respond_to? :else
224
184
  conditional = node.children[0].source
225
- if_blk = node.children[1].source
226
185
 
227
- replace(node.loc.expression, "if(#{conditional})\n#{if_blk}\nend")
186
+ if_blk = if node.keyword == 'unless'
187
+ node.children[2].source
188
+ conditional = "!(#{conditional})"
189
+ else
190
+ node.children[1].source
191
+ end
192
+
193
+ replace(node.loc.expression, "if(#{conditional});#{if_blk};end")
228
194
  end
229
195
 
230
196
  super
@@ -233,17 +199,53 @@ module TEALrb
233
199
 
234
200
  class IfRewriter < Rewriter
235
201
  def on_if(node)
202
+ condition = node.children.first
203
+ block = node.children[1]
204
+
236
205
  case node.loc.keyword.source
237
- when 'if'
238
- replace(node.loc.keyword, 'IfBlock.new(')
206
+ when 'if', 'unless'
207
+ @contract.if_count += 1
208
+ @elsif_count ||= 0
209
+
210
+ if node.loc.keyword.source == 'unless'
211
+ replace(node.loc.keyword, ":if#{@contract.if_count}_condition;!")
212
+ else
213
+ replace(node.loc.keyword, ":if#{@contract.if_count}_condition;")
214
+ end
215
+ insert_before(block.source_range, ":if#{@contract.if_count}_logic;")
216
+
217
+ case node.loc.else&.source
218
+ when 'else'
219
+ insert_after(condition.source_range, "; bz :if#{@contract.if_count}_else")
220
+ insert_after(block.source_range, "; b :if#{@contract.if_count}_end")
221
+ replace(node.loc.else, ":if#{@contract.if_count}_else;")
222
+ when 'elsif'
223
+ insert_after(condition.source_range, "; bz :if#{@contract.if_count}_elsif#{@elsif_count + 1}_condition")
224
+ insert_after(block.source_range, "; b :if#{@contract.if_count}_end")
225
+ replace(node.loc.else, ":if#{@contract.if_count}_elsif#{@elsif_count + 1}_condition;")
226
+ else
227
+ insert_after(condition.source_range, "; bz :if#{@contract.if_count}_end")
228
+ end
229
+ replace(node.loc.end, ":if#{@contract.if_count}_end")
239
230
  when 'elsif'
240
- replace(node.loc.keyword, 'end.elsif(')
241
- end
231
+ @elsif_count += 1
232
+
233
+ case node.loc.else&.source
234
+ when 'else'
235
+ insert_after(condition.source_range, "; bz :if#{@contract.if_count}_else")
236
+ insert_after(block.source_range, "; b :if#{@contract.if_count}_end")
237
+ replace(node.loc.else, ":if#{@contract.if_count}_else;")
238
+ when 'elsif'
239
+ insert_after(condition.source_range, "; bz :if#{@contract.if_count}_elsif#{@elsif_count + 1}_condition")
240
+ insert_after(block.source_range, "; b :if#{@contract.if_count}_end")
241
+ replace(node.loc.else, ":if#{@contract.if_count}_elsif#{@elsif_count + 1}_condition;")
242
+ else
243
+ insert_after(condition.source_range, "; bz :if#{@contract.if_count}_end")
244
+ end
242
245
 
243
- cond_expr = node.children.first.source_range
244
- replace(cond_expr, "#{cond_expr.source} ) do")
246
+ insert_before(block.source_range, ":if#{@contract.if_count}_elsif#{@elsif_count}_logic;")
247
+ end
245
248
 
246
- replace(node.loc.else, 'end.else do') if node.loc.else && node.loc.else.source == 'else'
247
249
  super
248
250
  end
249
251
  end
@@ -265,9 +267,12 @@ module TEALrb
265
267
 
266
268
  def on_while(node)
267
269
  cond_node = node.children.first
268
- replace(node.loc.keyword, ":while#{while_count}\n#{cond_node.source}\nbz :end_while#{while_count}")
270
+ replace(
271
+ node.loc.keyword,
272
+ ":while#{while_count}_condition;#{cond_node.source};bz :while#{while_count}_end; :while#{while_count}_logic;"
273
+ )
269
274
  replace(node.loc.begin, '') if node.loc.begin
270
- replace(node.loc.end, "b :while#{while_count}\n:end_while#{while_count}")
275
+ replace(node.loc.end, "b :while#{while_count}_condition;:while#{while_count}_end")
271
276
  replace(cond_node.loc.expression, '')
272
277
  super
273
278
  end
@@ -2,14 +2,15 @@
2
2
 
3
3
  module TEALrb
4
4
  class Scratch
5
- def initialize
5
+ def initialize(contract)
6
6
  @open_slots = (0..256).to_a
7
7
  @named_slots = {}
8
8
  @values = {}
9
+ @contract = contract
9
10
  end
10
11
 
11
12
  def [](key)
12
- TEAL.instance << "load #{@named_slots[key]} // #{key}"
13
+ @contract.teal << "load #{@named_slots[key]} // #{key}"
13
14
  @values[key]
14
15
  end
15
16
 
@@ -17,9 +18,9 @@ module TEALrb
17
18
  store(key, value)
18
19
  end
19
20
 
20
- def store(key, value = TEAL.instance)
21
+ def store(key, value = @contract.teal)
21
22
  @values[key] = value
22
- TEAL.instance << "store #{@named_slots[key] ||= @open_slots.shift} // #{key}"
23
+ @contract.teal << "store #{@named_slots[key] ||= @open_slots.shift} // #{key}"
23
24
  end
24
25
 
25
26
  def delete(key)
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TEALrb
4
+ class ThisTxn < OpcodeType
5
+ include TxnFields
6
+
7
+ private
8
+
9
+ def txnfield_opcode(field, *_args)
10
+ @contract.txn field
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,333 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TEALrb
4
+ module TxnFields
5
+ def txnfield_opcode(*args)
6
+ raise NotImplementedError
7
+ end
8
+
9
+ # @return [[]byte] 32 byte address (v1)
10
+ def sender(*args)
11
+ @contract.account txnfield_opcode('Sender', *args)
12
+ end
13
+
14
+ # @return [uint64] microalgos (v1)
15
+ def fee(*args)
16
+ txnfield_opcode('Fee', *args)
17
+ end
18
+
19
+ # @return [uint64] round number (v1)
20
+ def first_valid(*args)
21
+ txnfield_opcode('FirstValid', *args)
22
+ end
23
+
24
+ # @return [uint64] Causes program to fail; reserved for future use (v1)
25
+ def first_valid_time(*args)
26
+ txnfield_opcode('FirstValidTime', *args)
27
+ end
28
+
29
+ # @return [uint64] round number (v1)
30
+ def last_valid(*args)
31
+ txnfield_opcode('LastValid', *args)
32
+ end
33
+
34
+ # @return [[]byte] Any data up to 1024 bytes (v1)
35
+ def note(*args)
36
+ txnfield_opcode('Note', *args)
37
+ end
38
+
39
+ # @return [[]byte] 32 byte lease value (v1)
40
+ def lease(*args)
41
+ txnfield_opcode('Lease', *args)
42
+ end
43
+
44
+ # @return [[]byte] 32 byte address (v1)
45
+ def receiver(*args)
46
+ @contract.account txnfield_opcode('Receiver', *args)
47
+ end
48
+
49
+ # @return [uint64] microalgos (v1)
50
+ def amount(*args)
51
+ txnfield_opcode('Amount', *args)
52
+ end
53
+
54
+ # @return [[]byte] 32 byte address (v1)
55
+ def close_remainder_to(*args)
56
+ @contract.account txnfield_opcode('CloseRemainderTo', *args)
57
+ end
58
+
59
+ # @return [[]byte] 32 byte address (v1)
60
+ def vote_pk(*args)
61
+ txnfield_opcode('VotePK', *args)
62
+ end
63
+
64
+ # @return [[]byte] 32 byte address (v1)
65
+ def selection_pk(*args)
66
+ txnfield_opcode('SelectionPK', *args)
67
+ end
68
+
69
+ # @return [uint64] The first round that the participation key is valid. (v1)
70
+ def vote_first(*args)
71
+ txnfield_opcode('VoteFirst', *args)
72
+ end
73
+
74
+ # @return [uint64] The last round that the participation key is valid. (v1)
75
+ def vote_last(*args)
76
+ txnfield_opcode('VoteLast', *args)
77
+ end
78
+
79
+ # @return [uint64] Dilution for the 2-level participation key (v1)
80
+ def vote_key_dilution(*args)
81
+ txnfield_opcode('VoteKeyDilution', *args)
82
+ end
83
+
84
+ # @return [[]byte] Transaction type as bytes (v1)
85
+ def type(*args)
86
+ txnfield_opcode('Type', *args)
87
+ end
88
+
89
+ # @return [uint64] See table below (v1)
90
+ def type_enum(*args)
91
+ txnfield_opcode('TypeEnum', *args)
92
+ end
93
+
94
+ # @return [uint64] Asset ID (v1)
95
+ def xfer_asset(*args)
96
+ @contract.asset txnfield_opcode('XferAsset', *args)
97
+ end
98
+
99
+ # @return [uint64] value in Asset's units (v1)
100
+ def asset_amount(*args)
101
+ txnfield_opcode('AssetAmount', *args)
102
+ end
103
+
104
+ # @return [[]byte] 32 byte address. Causes clawback of all value of asset from AssetSender if
105
+ # Sender is the Clawback address of the asset. (v1)
106
+ def asset_sender(*args)
107
+ @contract.account txnfield_opcode('AssetSender', *args)
108
+ end
109
+
110
+ # @return [[]byte] 32 byte address (v1)
111
+ def asset_receiver(*args)
112
+ @contract.account txnfield_opcode('AssetReceiver', *args)
113
+ end
114
+
115
+ # @return [[]byte] 32 byte address (v1)
116
+ def asset_close_to(*args)
117
+ @contract.account txnfield_opcode('AssetCloseTo', *args)
118
+ end
119
+
120
+ # @return [uint64] Position of this transaction within an atomic transaction group.
121
+ # A stand-alone transaction is implicitly element 0 in a group of 1 (v1)
122
+ def group_index(*args)
123
+ txnfield_opcode('GroupIndex', *args)
124
+ end
125
+
126
+ # @return [[]byte] The computed ID for this transaction. 32 bytes. (v1)
127
+ def tx_id(*args)
128
+ txnfield_opcode('TxID', *args)
129
+ end
130
+
131
+ # @return [uint64] ApplicationID from ApplicationCall transaction (v2)
132
+ def application_id(*args)
133
+ @contract.app txnfield_opcode('ApplicationID', *args)
134
+ end
135
+
136
+ # @return [uint64] ApplicationCall transaction on completion action (v2)
137
+ def on_completion(*args)
138
+ txnfield_opcode('OnCompletion', *args)
139
+ end
140
+
141
+ # @return [[]byte] Arguments passed to the application in the ApplicationCall transaction (v2)
142
+ def application_args(*args)
143
+ txnfield_opcode('ApplicationArgs', *args)
144
+ end
145
+
146
+ # @return [uint64] Number of ApplicationArgs (v2)
147
+ def num_app_args(*args)
148
+ txnfield_opcode('NumAppArgs', *args)
149
+ end
150
+
151
+ # @return [[]byte] Accounts listed in the ApplicationCall transaction (v2)
152
+ def accounts(*args)
153
+ txnfield_opcode('Accounts', *args)
154
+ end
155
+
156
+ # @return [uint64] Number of Accounts (v2)
157
+ def num_accounts(*args)
158
+ txnfield_opcode('NumAccounts', *args)
159
+ end
160
+
161
+ # @return [[]byte] Approval program (v2)
162
+ def approval_program(*args)
163
+ txnfield_opcode('ApprovalProgram', *args)
164
+ end
165
+
166
+ # @return [[]byte] Clear state program (v2)
167
+ def clear_state_program(*args)
168
+ txnfield_opcode('ClearStateProgram', *args)
169
+ end
170
+
171
+ # @return [[]byte] 32 byte Sender's new AuthAddr (v2)
172
+ def rekey_to(*args)
173
+ @contract.account txnfield_opcode('RekeyTo', *args)
174
+ end
175
+
176
+ # @return [uint64] Asset ID in asset config transaction (v2)
177
+ def config_asset(*args)
178
+ @contract.asset txnfield_opcode('ConfigAsset', *args)
179
+ end
180
+
181
+ # @return [uint64] Total number of units of this asset created (v2)
182
+ def config_asset_total(*args)
183
+ txnfield_opcode('ConfigAssetTotal', *args)
184
+ end
185
+
186
+ # @return [uint64] Number of digits to display after the decimal place when displaying the asset (v2)
187
+ def config_asset_decimals(*args)
188
+ txnfield_opcode('ConfigAssetDecimals', *args)
189
+ end
190
+
191
+ # @return [uint64] Whether the asset's slots are frozen by default or not, 0 or 1 (v2)
192
+ def config_asset_default_frozen(*args)
193
+ txnfield_opcode('ConfigAssetDefaultFrozen', *args)
194
+ end
195
+
196
+ # @return [[]byte] Unit name of the asset (v2)
197
+ def config_asset_unit_name(*args)
198
+ txnfield_opcode('ConfigAssetUnitName', *args)
199
+ end
200
+
201
+ # @return [[]byte] The asset name (v2)
202
+ def config_asset_name(*args)
203
+ txnfield_opcode('ConfigAssetName', *args)
204
+ end
205
+
206
+ # @return [[]byte] URL (v2)
207
+ def config_asset_url(*args)
208
+ txnfield_opcode('ConfigAssetURL', *args)
209
+ end
210
+
211
+ # @return [[]byte] 32 byte commitment to some unspecified asset metadata (v2)
212
+ def config_asset_metadata_hash(*args)
213
+ txnfield_opcode('ConfigAssetMetadataHash', *args)
214
+ end
215
+
216
+ # @return [[]byte] 32 byte address (v2)
217
+ def config_asset_manager(*args)
218
+ @contract.account txnfield_opcode('ConfigAssetManager', *args)
219
+ end
220
+
221
+ # @return [[]byte] 32 byte address (v2)
222
+ def config_asset_reserve(*args)
223
+ @contract.account txnfield_opcode('ConfigAssetReserve', *args)
224
+ end
225
+
226
+ # @return [[]byte] 32 byte address (v2)
227
+ def config_asset_freeze(*args)
228
+ @contract.account txnfield_opcode('ConfigAssetFreeze', *args)
229
+ end
230
+
231
+ # @return [[]byte] 32 byte address (v2)
232
+ def config_asset_clawback(*args)
233
+ @contract.account txnfield_opcode('ConfigAssetClawback', *args)
234
+ end
235
+
236
+ # @return [uint64] Asset ID being frozen or un-frozen (v2)
237
+ def freeze_asset(*args)
238
+ @contract.asset txnfield_opcode('FreezeAsset', *args)
239
+ end
240
+
241
+ # @return [[]byte] 32 byte address of the account whose asset slot is being frozen or un-frozen (v2)
242
+ def freeze_asset_account(*args)
243
+ @contract.account txnfield_opcode('FreezeAssetAccount', *args)
244
+ end
245
+
246
+ # @return [uint64] The new frozen value, 0 or 1 (v2)
247
+ def freeze_asset_frozen(*args)
248
+ txnfield_opcode('FreezeAssetFrozen', *args)
249
+ end
250
+
251
+ # @return [uint64] Foreign Assets listed in the ApplicationCall transaction (v3)
252
+ def assets(*args)
253
+ txnfield_opcode('Assets', *args)
254
+ end
255
+
256
+ # @return [uint64] Number of Assets (v3)
257
+ def num_assets(*args)
258
+ txnfield_opcode('NumAssets', *args)
259
+ end
260
+
261
+ # @return [uint64] Foreign Apps listed in the ApplicationCall transaction (v3)
262
+ def applications(*args)
263
+ txnfield_opcode('Applications', *args)
264
+ end
265
+
266
+ # @return [uint64] Number of Applications (v3)
267
+ def num_applications(*args)
268
+ txnfield_opcode('NumApplications', *args)
269
+ end
270
+
271
+ # @return [uint64] Number of global state integers in ApplicationCall (v3)
272
+ def global_num_uint(*args)
273
+ txnfield_opcode('GlobalNumUint', *args)
274
+ end
275
+
276
+ # @return [uint64] Number of global state byteslices in ApplicationCall (v3)
277
+ def global_num_byte_slice(*args)
278
+ txnfield_opcode('GlobalNumByteSlice', *args)
279
+ end
280
+
281
+ # @return [uint64] Number of local state integers in ApplicationCall (v3)
282
+ def local_num_uint(*args)
283
+ txnfield_opcode('LocalNumUint', *args)
284
+ end
285
+
286
+ # @return [uint64] Number of local state byteslices in ApplicationCall (v3)
287
+ def local_num_byte_slice(*args)
288
+ txnfield_opcode('LocalNumByteSlice', *args)
289
+ end
290
+
291
+ # @return [uint64] Number of additional pages for each of the application's approval and clear state programs.
292
+ # An ExtraProgramPages of 1 means 2048 more total bytes, or 1024 for each program. (v4)
293
+ def extra_program_pages(*args)
294
+ txnfield_opcode('ExtraProgramPages', *args)
295
+ end
296
+
297
+ # @return [uint64] Marks an account nonparticipating for rewards (v5)
298
+ def nonparticipation(*args)
299
+ txnfield_opcode('Nonparticipation', *args)
300
+ end
301
+
302
+ # @return [[]byte] Log messages emitted by an application call (only with itxn in v5). Application mode only (v5)
303
+ def logs(*args)
304
+ txnfield_opcode('Logs', *args)
305
+ end
306
+
307
+ # @return [uint64] Number of Logs (only with itxn in v5). Application mode only (v5)
308
+ def num_logs(*args)
309
+ txnfield_opcode('NumLogs', *args)
310
+ end
311
+
312
+ # @return [uint64] Asset ID allocated by the creation of an ASA (only with itxn in v5). Application mode only (v5)
313
+ def created_asset_id(*args)
314
+ @contract.asset txnfield_opcode('CreatedAssetID', *args)
315
+ end
316
+
317
+ # @return [uint64] ApplicationID allocated by the creation of an application (only with itxn in v5).
318
+ # Application mode only (v5)
319
+ def created_application_id(*args)
320
+ @contract.app txnfield_opcode('CreatedApplicationID', *args)
321
+ end
322
+
323
+ # @return [[]byte] The last message emitted. Empty bytes if none were emitted. Application mode only (v6)
324
+ def last_log(*args)
325
+ txnfield_opcode('LastLog', *args)
326
+ end
327
+
328
+ # @return [[]byte] 64 byte state proof public key commitment (v6)
329
+ def state_proof_pk(*args)
330
+ txnfield_opcode('StateProofPK', *args)
331
+ end
332
+ end
333
+ end
data/lib/tealrb.rb CHANGED
@@ -3,32 +3,39 @@
3
3
  require 'method_source'
4
4
  require 'rubocop'
5
5
  require 'yard'
6
+ require 'faraday'
7
+ require 'source_map'
6
8
 
7
9
  require_relative 'tealrb/constants'
8
10
  require_relative 'tealrb/abi'
9
11
  require_relative 'tealrb/opcodes'
10
- require_relative 'tealrb/opcode_modules'
11
- require_relative 'tealrb/rewriters'
12
- require_relative 'tealrb/if_block'
12
+ require_relative 'tealrb/maybe_ops'
13
+ require_relative 'tealrb/byte_opcodes'
14
+ require_relative 'tealrb/txn_fields'
15
+ require_relative 'tealrb/opcode_type'
16
+ require_relative 'tealrb/account'
17
+ require_relative 'tealrb/this_txn'
18
+ require_relative 'tealrb/box'
19
+ require_relative 'tealrb/inner_txn'
20
+ require_relative 'tealrb/group_txn'
21
+ require_relative 'tealrb/global'
22
+ require_relative 'tealrb/app'
23
+ require_relative 'tealrb/asset'
24
+ require_relative 'tealrb/logs'
25
+ require_relative 'tealrb/app_args'
26
+ require_relative 'tealrb/local'
27
+ require_relative 'tealrb/enums'
13
28
  require_relative 'tealrb/scratch'
29
+ require_relative 'tealrb/algod'
30
+ require_relative 'tealrb/rewriters'
14
31
  require_relative 'tealrb/contract'
15
32
  require_relative 'tealrb/cmd_line/teal2tealrb'
16
33
 
17
34
  module TEALrb
18
35
  class TEAL < Array
19
- class << self
20
- attr_writer :instance
21
-
22
- def instance
23
- raise 'TEALrb does not support multi-threading' if Thread.current != Thread.main
24
-
25
- @instance
26
- end
27
- end
28
-
29
- def initialize(teal_array)
30
- self.class.instance = self
31
- super
36
+ def initialize(teal_array, contract)
37
+ @contract = contract
38
+ super(teal_array)
32
39
  end
33
40
 
34
41
  def teal
@@ -39,19 +46,41 @@ module TEALrb
39
46
  self << '&&'
40
47
  end
41
48
 
49
+ def <<(value)
50
+ return super unless @contract.class.src_map
51
+ return super if caller.join['src_map']
52
+ return super unless @contract.eval_location
53
+
54
+ eval_location = caller.reverse.find { _1[/^\(eval/] }&.split(':')
55
+ return super unless eval_location
56
+
57
+ eval_line = eval_location[1].to_i
58
+ src_map(@contract.eval_location.first, @contract.eval_location.last + eval_line)
59
+ super
60
+ end
61
+
62
+ def src_map(file, line_number)
63
+ ln = "// src_map:#{File.basename(file)}:#{line_number}"
64
+ return if ln == @last_src_map
65
+
66
+ @last_src_map = ln
67
+
68
+ self << ln
69
+ end
70
+
42
71
  def boolean_or(_other)
43
72
  self << '||'
44
73
  end
45
74
 
46
75
  TEALrb::Opcodes::BINARY_OPCODE_METHOD_MAPPING.each do |meth, opcode|
47
76
  define_method(meth) do |other|
48
- TEALrb::Opcodes::ExtendedOpcodes.send(opcode, self, other)
77
+ @contract.send(opcode, self, other)
49
78
  end
50
79
  end
51
80
 
52
81
  TEALrb::Opcodes::UNARY_OPCODE_METHOD_MAPPING.each do |meth, opcode|
53
82
  define_method(meth) do
54
- TEALrb::Opcodes::ExtendedOpcodes.send(opcode, self)
83
+ @contract.send(opcode, self)
55
84
  end
56
85
  end
57
86
  end