tealrb 0.4.0 → 0.7.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.
- checksums.yaml +4 -4
- data/lib/tealrb/contract.rb +43 -37
- data/lib/tealrb/if_block.rb +16 -17
- data/lib/tealrb/opcode_modules.rb +61 -21
- data/lib/tealrb/opcodes.rb +155 -155
- data/lib/tealrb/rewriters.rb +64 -20
- data/lib/tealrb/scratch.rb +53 -0
- data/lib/tealrb.rb +11 -5
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94ca888a944ccee0517d5e543498570af448a9eb3ea1ba74d3d3261ffc4b86f0
|
4
|
+
data.tar.gz: 54ac7826a7af43fb82fa17cf010a2ce869511546067f7a151181b86d3445b0bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f986ae5a4e3c37460142951923c3908ec95b58d0d91f695a49a07f8e8eee062499d496b185e1f2eafec8ed2020ca9d83a4c8c50c97531a8a67e26057e7bb794
|
7
|
+
data.tar.gz: c73f78d20f1c76ccc41e42450f713b14dc42049d8d44ee1498c59e38cda3e7699e4f1e655932f5b86c68d707d1a1abba7d59fc5c92244552236bb2a472a3d4c2
|
data/lib/tealrb/contract.rb
CHANGED
@@ -6,6 +6,7 @@ module TEALrb
|
|
6
6
|
include Opcodes
|
7
7
|
include ABI
|
8
8
|
include Rewriters
|
9
|
+
include MaybeOps
|
9
10
|
|
10
11
|
attr_reader :teal
|
11
12
|
|
@@ -69,6 +70,8 @@ module TEALrb
|
|
69
70
|
# sets the `#pragma version`, defines teal methods, and defines subroutines
|
70
71
|
def initialize
|
71
72
|
@teal = TEAL.new ["#pragma version #{self.class.version}"]
|
73
|
+
IfBlock.id = 0
|
74
|
+
@scratch = Scratch.new
|
72
75
|
|
73
76
|
self.class.subroutines.each_key do |name|
|
74
77
|
define_singleton_method(name) do |*_args|
|
@@ -85,25 +88,18 @@ module TEALrb
|
|
85
88
|
end
|
86
89
|
end
|
87
90
|
|
91
|
+
# return the input without transpiling to TEAL
|
92
|
+
def rb(input)
|
93
|
+
input
|
94
|
+
end
|
95
|
+
|
88
96
|
# defines a method that is transpiled to TEAL
|
89
97
|
# @param name [Symbol] name of the method
|
90
98
|
# @param definition [Lambda, Proc, UnboundMethod] the method definition
|
91
99
|
# @return [nil]
|
92
100
|
def define_teal_method(name, definition)
|
93
|
-
|
94
|
-
|
95
|
-
new_source = rewrite(definition.source, method_rewriter: true)
|
96
|
-
|
97
|
-
pre_string = StringIO.new
|
98
|
-
|
99
|
-
definition.parameters.reverse.each_with_index do |param, i|
|
100
|
-
param_name = param.last
|
101
|
-
pre_string.puts "store #{200 + i}"
|
102
|
-
pre_string.puts "comment('#{param_name}', inline: true)"
|
103
|
-
pre_string.puts "#{param_name} = -> { load #{200 + i}; comment('#{param_name}', inline: true) }"
|
104
|
-
end
|
101
|
+
new_source = generate_method_source(name, definition)
|
105
102
|
|
106
|
-
new_source = "#{pre_string.string}#{new_source}"
|
107
103
|
define_singleton_method(name) do |*_args|
|
108
104
|
eval_tealrb(new_source, debug_context: "teal method: #{name}")
|
109
105
|
end
|
@@ -116,13 +112,11 @@ module TEALrb
|
|
116
112
|
# @param definition [Lambda, Proc, UnboundMethod] the method definition
|
117
113
|
# @return [nil]
|
118
114
|
def define_subroutine(name, definition)
|
119
|
-
@teal.set_as_current
|
120
|
-
|
121
115
|
define_singleton_method(name) do |*_args|
|
122
116
|
callsub(name)
|
123
117
|
end
|
124
118
|
|
125
|
-
|
119
|
+
TEAL.instance << 'b main' unless TEAL.instance.include? 'b main'
|
126
120
|
|
127
121
|
label(name) # add teal label
|
128
122
|
|
@@ -130,18 +124,9 @@ module TEALrb
|
|
130
124
|
comment_content = "#{name}(#{comment_params})"
|
131
125
|
comment(comment_content, inline: true)
|
132
126
|
|
133
|
-
new_source =
|
134
|
-
|
135
|
-
pre_string = StringIO.new
|
136
|
-
|
137
|
-
definition.parameters.reverse.each_with_index do |param, i|
|
138
|
-
param_name = param.last
|
139
|
-
pre_string.puts "store #{200 + i}"
|
140
|
-
pre_string.puts "comment('#{param_name}', inline: true)"
|
141
|
-
pre_string.puts "#{param_name} = -> { load #{200 + i}; comment('#{param_name}', inline: true) }"
|
142
|
-
end
|
127
|
+
new_source = generate_method_source(name, definition)
|
128
|
+
new_source = "#{new_source}retsub"
|
143
129
|
|
144
|
-
new_source = "#{pre_string.string}#{new_source}retsub"
|
145
130
|
eval_tealrb(new_source, debug_context: "subroutine: #{name}")
|
146
131
|
|
147
132
|
nil
|
@@ -153,17 +138,17 @@ module TEALrb
|
|
153
138
|
def comment(content, inline: false)
|
154
139
|
content = " #{content}" unless content[0] == ' '
|
155
140
|
if inline
|
156
|
-
last_line =
|
157
|
-
|
141
|
+
last_line = TEAL.instance.pop
|
142
|
+
TEAL.instance << "#{last_line} //#{content}"
|
158
143
|
else
|
159
|
-
|
144
|
+
TEAL.instance << "//#{content}"
|
160
145
|
end
|
161
146
|
end
|
162
147
|
|
163
148
|
# inserts a string into TEAL source
|
164
149
|
# @param string [String] the string to insert
|
165
150
|
def placeholder(string)
|
166
|
-
|
151
|
+
TEAL.instance << string
|
167
152
|
end
|
168
153
|
|
169
154
|
# the hash of the abi description
|
@@ -175,20 +160,41 @@ module TEALrb
|
|
175
160
|
# @param string [String] string to transpile
|
176
161
|
# @return [nil]
|
177
162
|
def compile_string(string)
|
178
|
-
@teal.set_as_current
|
179
163
|
eval_tealrb(rewrite(string), debug_context: 'compile_string')
|
180
164
|
nil
|
181
165
|
end
|
182
166
|
|
183
167
|
# transpiles #main
|
184
168
|
def compile
|
185
|
-
|
186
|
-
@teal << 'main:' if @teal.include? 'b main'
|
169
|
+
TEAL.instance << 'main:' if TEAL.instance.include? 'b main'
|
187
170
|
eval_tealrb(rewrite(method(:main).source, method_rewriter: true), debug_context: 'main')
|
188
171
|
end
|
189
172
|
|
190
173
|
private
|
191
174
|
|
175
|
+
def generate_method_source(name, definition)
|
176
|
+
new_source = rewrite(definition.source, method_rewriter: true)
|
177
|
+
|
178
|
+
pre_string = StringIO.new
|
179
|
+
|
180
|
+
scratch_names = []
|
181
|
+
definition.parameters.reverse.each_with_index do |param, _i|
|
182
|
+
param_name = param.last
|
183
|
+
scratch_name = [name, param_name].map(&:to_s).join(': ')
|
184
|
+
scratch_names << scratch_name
|
185
|
+
|
186
|
+
pre_string.puts "@scratch.store('#{scratch_name}')"
|
187
|
+
pre_string.puts "#{param_name} = -> { @scratch['#{scratch_name}'] }"
|
188
|
+
end
|
189
|
+
|
190
|
+
post_string = StringIO.new
|
191
|
+
scratch_names.each do |n|
|
192
|
+
post_string.puts "@scratch.delete '#{n}'"
|
193
|
+
end
|
194
|
+
|
195
|
+
"#{pre_string.string}#{new_source}#{post_string.string}"
|
196
|
+
end
|
197
|
+
|
192
198
|
def rewrite_with_rewriter(string, rewriter)
|
193
199
|
process_source = RuboCop::ProcessedSource.new(string, RUBY_VERSION[/\d\.\d/].to_f)
|
194
200
|
rewriter.new.rewrite(process_source)
|
@@ -201,7 +207,7 @@ module TEALrb
|
|
201
207
|
puts ''
|
202
208
|
end
|
203
209
|
|
204
|
-
[CommentRewriter, ComparisonRewriter, IfRewriter, OpRewriter, AssignRewriter].each do |rw|
|
210
|
+
[CommentRewriter, ComparisonRewriter, WhileRewriter, IfRewriter, OpRewriter, AssignRewriter].each do |rw|
|
205
211
|
string = rewrite_with_rewriter(string, rw)
|
206
212
|
end
|
207
213
|
|
@@ -217,7 +223,7 @@ module TEALrb
|
|
217
223
|
end
|
218
224
|
|
219
225
|
def eval_tealrb(s, debug_context:)
|
220
|
-
pre_teal = Array.new
|
226
|
+
pre_teal = Array.new TEAL.instance
|
221
227
|
|
222
228
|
if self.class.debug
|
223
229
|
puts "DEBUG: Evaluating the following code (#{debug_context}):"
|
@@ -229,7 +235,7 @@ module TEALrb
|
|
229
235
|
|
230
236
|
if self.class.debug
|
231
237
|
puts "DEBUG: Resulting TEAL (#{debug_context}):"
|
232
|
-
puts Array.new(
|
238
|
+
puts Array.new(TEAL.instance) - pre_teal
|
233
239
|
puts ''
|
234
240
|
end
|
235
241
|
rescue SyntaxError, StandardError => e
|
data/lib/tealrb/if_block.rb
CHANGED
@@ -6,39 +6,38 @@ module TEALrb
|
|
6
6
|
attr_accessor :id
|
7
7
|
end
|
8
8
|
|
9
|
-
@id =
|
9
|
+
@id = 0
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
self.class.id
|
13
|
-
@teal = teal
|
11
|
+
def initialize(_cond, &blk)
|
12
|
+
self.class.id ||= 0
|
14
13
|
@else_count = 0
|
15
|
-
@id = self.class.id
|
14
|
+
@id = self.class.id
|
16
15
|
@end_label = "if#{@id}_end:"
|
17
16
|
|
18
|
-
self.class.id
|
17
|
+
self.class.id += 1
|
19
18
|
|
20
|
-
|
19
|
+
TEAL.instance << "bz if#{@id}_else0"
|
21
20
|
blk.call
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
TEAL.instance << "b if#{@id}_end"
|
22
|
+
TEAL.instance << "if#{@id}_else0:"
|
23
|
+
TEAL.instance << @end_label
|
25
24
|
end
|
26
25
|
|
27
26
|
def elsif(_cond, &blk)
|
28
27
|
@else_count += 1
|
29
|
-
|
30
|
-
|
28
|
+
TEAL.instance.delete @end_label
|
29
|
+
TEAL.instance << "bz if#{@id}_else#{@else_count}"
|
31
30
|
blk.call
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
TEAL.instance << "b if#{@id}_end"
|
32
|
+
TEAL.instance << "if#{@id}_else#{@else_count}:"
|
33
|
+
TEAL.instance << @end_label
|
35
34
|
self
|
36
35
|
end
|
37
36
|
|
38
37
|
def else(&blk)
|
39
|
-
|
38
|
+
TEAL.instance.delete @end_label
|
40
39
|
blk.call
|
41
|
-
|
40
|
+
TEAL.instance << @end_label
|
42
41
|
end
|
43
42
|
end
|
44
43
|
end
|
@@ -33,7 +33,7 @@ module TEALrb
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def txn_type_int(type)
|
36
|
-
|
36
|
+
TEAL.instance << "int #{type}"
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -603,7 +603,6 @@ module TEALrb
|
|
603
603
|
extend AppFields
|
604
604
|
|
605
605
|
def self.opcode(field, app_id = nil)
|
606
|
-
@teal = TEALrb::TEAL.current[Thread.current]
|
607
606
|
app_params_get field, app_id
|
608
607
|
end
|
609
608
|
end
|
@@ -613,7 +612,6 @@ module TEALrb
|
|
613
612
|
extend AssetFields
|
614
613
|
|
615
614
|
def self.opcode(field, asset = nil)
|
616
|
-
@teal = TEALrb::TEAL.current[Thread.current]
|
617
615
|
asset_params_get field, asset
|
618
616
|
end
|
619
617
|
end
|
@@ -623,7 +621,6 @@ module TEALrb
|
|
623
621
|
extend AccountFields
|
624
622
|
|
625
623
|
def self.opcode(field, account = nil)
|
626
|
-
@teal = TEALrb::TEAL.current[Thread.current]
|
627
624
|
acct_params_get field, account
|
628
625
|
end
|
629
626
|
end
|
@@ -642,7 +639,6 @@ module TEALrb
|
|
642
639
|
extend Opcodes
|
643
640
|
|
644
641
|
def self.opcode(field, index)
|
645
|
-
@teal = TEALrb::TEAL.current[Thread.current]
|
646
642
|
gtxn index, field
|
647
643
|
end
|
648
644
|
|
@@ -667,37 +663,34 @@ module TEALrb
|
|
667
663
|
class TxnaField
|
668
664
|
include Opcodes
|
669
665
|
|
670
|
-
def initialize(field
|
666
|
+
def initialize(field)
|
671
667
|
@field = field
|
672
|
-
@teal = TEALrb::TEAL.current[Thread.current]
|
673
|
-
txna(field, index) if index
|
674
668
|
end
|
675
669
|
|
676
670
|
def [](index)
|
677
|
-
@teal = TEALrb::TEAL.current[Thread.current]
|
678
671
|
txna @field, index
|
679
672
|
end
|
680
673
|
end
|
681
674
|
|
682
675
|
module Txna
|
683
|
-
def self.application_args
|
684
|
-
TxnaField.new('ApplicationArgs'
|
676
|
+
def self.application_args
|
677
|
+
TxnaField.new('ApplicationArgs')
|
685
678
|
end
|
686
679
|
|
687
|
-
def self.accounts
|
688
|
-
TxnaField.new('Accounts'
|
680
|
+
def self.accounts
|
681
|
+
TxnaField.new('Accounts')
|
689
682
|
end
|
690
683
|
|
691
|
-
def self.assets
|
692
|
-
TxnaField.new('Assets'
|
684
|
+
def self.assets
|
685
|
+
TxnaField.new('Assets')
|
693
686
|
end
|
694
687
|
|
695
|
-
def self.applications
|
696
|
-
TxnaField.new('Applications'
|
688
|
+
def self.applications
|
689
|
+
TxnaField.new('Applications')
|
697
690
|
end
|
698
691
|
|
699
|
-
def self.logs
|
700
|
-
TxnaField.new('Logs'
|
692
|
+
def self.logs
|
693
|
+
TxnaField.new('Logs')
|
701
694
|
end
|
702
695
|
end
|
703
696
|
|
@@ -706,7 +699,6 @@ module TEALrb
|
|
706
699
|
extend GlobalFields
|
707
700
|
|
708
701
|
def self.opcode(field)
|
709
|
-
@teal = TEALrb::TEAL.current[Thread.current]
|
710
702
|
global field
|
711
703
|
end
|
712
704
|
|
@@ -721,7 +713,55 @@ module TEALrb
|
|
721
713
|
|
722
714
|
module AppArgs
|
723
715
|
def self.[](index)
|
724
|
-
Txna.application_args
|
716
|
+
Txna.application_args[index]
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
720
|
+
module MaybeOps
|
721
|
+
include Opcodes
|
722
|
+
|
723
|
+
def app_param_exists?(field, _app_id = nil)
|
724
|
+
app_params_get field
|
725
|
+
swap
|
726
|
+
pop
|
727
|
+
end
|
728
|
+
|
729
|
+
def app_param_value(field, _app_id = nil)
|
730
|
+
app_params_get field
|
731
|
+
pop
|
732
|
+
end
|
733
|
+
|
734
|
+
def asset_param_exists?(field, _asset_id = nil)
|
735
|
+
asset_params_get field
|
736
|
+
swap
|
737
|
+
pop
|
738
|
+
end
|
739
|
+
|
740
|
+
def asset_param_value(field, _asset_id = nil)
|
741
|
+
asset_params_get field
|
742
|
+
pop
|
743
|
+
end
|
744
|
+
|
745
|
+
def app_local_ex_exists?(_account = nil, _applicaiton = nil, _key = nil)
|
746
|
+
app_local_get_ex
|
747
|
+
swap
|
748
|
+
pop
|
749
|
+
end
|
750
|
+
|
751
|
+
def app_local_ex_value(_account = nil, _applicaiton = nil, _key = nil)
|
752
|
+
app_local_get_ex
|
753
|
+
pop
|
754
|
+
end
|
755
|
+
|
756
|
+
def app_global_ex_exists?(_account = nil, _applicaiton = nil, _key = nil)
|
757
|
+
app_global_get_ex
|
758
|
+
swap
|
759
|
+
pop
|
760
|
+
end
|
761
|
+
|
762
|
+
def app_global_ex_value(_account = nil, _applicaiton = nil, _key = nil)
|
763
|
+
app_global_get_ex
|
764
|
+
pop
|
725
765
|
end
|
726
766
|
end
|
727
767
|
end
|