tealrb 0.5.0 → 0.8.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 +36 -19
- data/lib/tealrb/if_block.rb +16 -17
- data/lib/tealrb/opcode_modules.rb +60 -20
- data/lib/tealrb/opcodes.rb +155 -155
- data/lib/tealrb/rewriters.rb +64 -22
- data/lib/tealrb/scratch.rb +19 -4
- data/lib/tealrb.rb +10 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2480b69400b8916b30ebd58c19b804190a6390780ad335006ac0364ea9d4ad4e
|
4
|
+
data.tar.gz: 6cf7f7f79217b1938f71bf07348923a7d31d3d83d76a4219f43e58bb1db2e3bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8220e4aadbdcbe9a992ada723431281665edda6a19c07771978b5a8b4ae9cf987a208ed69e9c96f4360a6a3ace9762dc930e4bab99574b2114effc0ffd1060e
|
7
|
+
data.tar.gz: 47790d4ee2171f4c2e95473f7c7cc6674d9634804c8c0dac2eeafff368df073166d9dfd371efc24026e1c94f4c333b1904af9fa4a959992116df7859dc314875
|
data/lib/tealrb/contract.rb
CHANGED
@@ -6,11 +6,13 @@ 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
|
|
12
13
|
class << self
|
13
|
-
attr_accessor :subroutines, :version, :teal_methods, :abi_method_hash, :abi_description, :debug
|
14
|
+
attr_accessor :subroutines, :version, :teal_methods, :abi_method_hash, :abi_description, :debug,
|
15
|
+
:disable_abi_routing
|
14
16
|
|
15
17
|
private
|
16
18
|
|
@@ -21,6 +23,7 @@ module TEALrb
|
|
21
23
|
klass.abi_description = ABI::ABIDescription.new
|
22
24
|
klass.abi_method_hash = {}
|
23
25
|
klass.debug = false
|
26
|
+
klass.disable_abi_routing = false
|
24
27
|
super
|
25
28
|
end
|
26
29
|
end
|
@@ -69,7 +72,8 @@ module TEALrb
|
|
69
72
|
# sets the `#pragma version`, defines teal methods, and defines subroutines
|
70
73
|
def initialize
|
71
74
|
@teal = TEAL.new ["#pragma version #{self.class.version}"]
|
72
|
-
|
75
|
+
IfBlock.id = 0
|
76
|
+
@scratch = Scratch.new
|
73
77
|
|
74
78
|
self.class.subroutines.each_key do |name|
|
75
79
|
define_singleton_method(name) do |*_args|
|
@@ -86,13 +90,16 @@ module TEALrb
|
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
93
|
+
# return the input without transpiling to TEAL
|
94
|
+
def rb(input)
|
95
|
+
input
|
96
|
+
end
|
97
|
+
|
89
98
|
# defines a method that is transpiled to TEAL
|
90
99
|
# @param name [Symbol] name of the method
|
91
100
|
# @param definition [Lambda, Proc, UnboundMethod] the method definition
|
92
101
|
# @return [nil]
|
93
102
|
def define_teal_method(name, definition)
|
94
|
-
@teal.set_as_current
|
95
|
-
|
96
103
|
new_source = generate_method_source(name, definition)
|
97
104
|
|
98
105
|
define_singleton_method(name) do |*_args|
|
@@ -107,13 +114,11 @@ module TEALrb
|
|
107
114
|
# @param definition [Lambda, Proc, UnboundMethod] the method definition
|
108
115
|
# @return [nil]
|
109
116
|
def define_subroutine(name, definition)
|
110
|
-
@teal.set_as_current
|
111
|
-
|
112
117
|
define_singleton_method(name) do |*_args|
|
113
118
|
callsub(name)
|
114
119
|
end
|
115
120
|
|
116
|
-
|
121
|
+
TEAL.instance << 'b main' unless TEAL.instance.include? 'b main'
|
117
122
|
|
118
123
|
label(name) # add teal label
|
119
124
|
|
@@ -135,17 +140,17 @@ module TEALrb
|
|
135
140
|
def comment(content, inline: false)
|
136
141
|
content = " #{content}" unless content[0] == ' '
|
137
142
|
if inline
|
138
|
-
last_line =
|
139
|
-
|
143
|
+
last_line = TEAL.instance.pop
|
144
|
+
TEAL.instance << "#{last_line} //#{content}"
|
140
145
|
else
|
141
|
-
|
146
|
+
TEAL.instance << "//#{content}"
|
142
147
|
end
|
143
148
|
end
|
144
149
|
|
145
150
|
# inserts a string into TEAL source
|
146
151
|
# @param string [String] the string to insert
|
147
152
|
def placeholder(string)
|
148
|
-
|
153
|
+
TEAL.instance << string
|
149
154
|
end
|
150
155
|
|
151
156
|
# the hash of the abi description
|
@@ -157,20 +162,32 @@ module TEALrb
|
|
157
162
|
# @param string [String] string to transpile
|
158
163
|
# @return [nil]
|
159
164
|
def compile_string(string)
|
160
|
-
@teal.set_as_current
|
161
165
|
eval_tealrb(rewrite(string), debug_context: 'compile_string')
|
162
166
|
nil
|
163
167
|
end
|
164
168
|
|
165
|
-
# transpiles #main
|
169
|
+
# transpiles #main and routes abi methods. To disable abi routing, set `@disable_abi_routing` to true in your
|
170
|
+
# Contract subclass
|
166
171
|
def compile
|
167
|
-
|
168
|
-
|
169
|
-
eval_tealrb(rewrite(method(:main).source, method_rewriter: true), debug_context: 'main')
|
172
|
+
TEAL.instance << 'main:' if TEAL.instance.include? 'b main'
|
173
|
+
route_abi_methods unless self.class.disable_abi_routing
|
174
|
+
eval_tealrb(rewrite(method(:main).source, method_rewriter: true), debug_context: 'main') if respond_to? :main
|
170
175
|
end
|
171
176
|
|
172
177
|
private
|
173
178
|
|
179
|
+
def route_abi_methods
|
180
|
+
self.class.abi_description.methods.each do |meth|
|
181
|
+
signature = "#{meth[:name]}(#{meth[:args].map{ _1[:type]}.join(',')})#{meth[:returns][:type]}"
|
182
|
+
selector = OpenSSL::Digest.new('SHA512-256').hexdigest(signature)[..7]
|
183
|
+
|
184
|
+
IfBlock.new(AppArgs[0] == byte(selector)) do
|
185
|
+
callsub(meth[:name])
|
186
|
+
approve
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
174
191
|
def generate_method_source(name, definition)
|
175
192
|
new_source = rewrite(definition.source, method_rewriter: true)
|
176
193
|
|
@@ -206,7 +223,7 @@ module TEALrb
|
|
206
223
|
puts ''
|
207
224
|
end
|
208
225
|
|
209
|
-
[CommentRewriter, ComparisonRewriter, IfRewriter, OpRewriter, AssignRewriter].each do |rw|
|
226
|
+
[CommentRewriter, ComparisonRewriter, WhileRewriter, IfRewriter, OpRewriter, AssignRewriter].each do |rw|
|
210
227
|
string = rewrite_with_rewriter(string, rw)
|
211
228
|
end
|
212
229
|
|
@@ -222,7 +239,7 @@ module TEALrb
|
|
222
239
|
end
|
223
240
|
|
224
241
|
def eval_tealrb(s, debug_context:)
|
225
|
-
pre_teal = Array.new
|
242
|
+
pre_teal = Array.new TEAL.instance
|
226
243
|
|
227
244
|
if self.class.debug
|
228
245
|
puts "DEBUG: Evaluating the following code (#{debug_context}):"
|
@@ -234,7 +251,7 @@ module TEALrb
|
|
234
251
|
|
235
252
|
if self.class.debug
|
236
253
|
puts "DEBUG: Resulting TEAL (#{debug_context}):"
|
237
|
-
puts Array.new(
|
254
|
+
puts Array.new(TEAL.instance) - pre_teal
|
238
255
|
puts ''
|
239
256
|
end
|
240
257
|
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
|
|
@@ -724,5 +716,53 @@ module TEALrb
|
|
724
716
|
Txna.application_args[index]
|
725
717
|
end
|
726
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
|
765
|
+
end
|
766
|
+
end
|
727
767
|
end
|
728
768
|
end
|