tealrb 0.4.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|