tealrb 0.5.0 → 0.8.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 +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
|