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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94e31d86149bd0b29c7f7a08f2cabd94866246808315a3f70e8ac8fc35ea4e8e
4
- data.tar.gz: e63533e3a902192d6425594109ea5a5e72b92eeea5f45956dc73ad093a05ceee
3
+ metadata.gz: 2480b69400b8916b30ebd58c19b804190a6390780ad335006ac0364ea9d4ad4e
4
+ data.tar.gz: 6cf7f7f79217b1938f71bf07348923a7d31d3d83d76a4219f43e58bb1db2e3bc
5
5
  SHA512:
6
- metadata.gz: 4a5c009da5923b564565b8c78f6e62bd75e17bcac9c19d2ae883d7a789a02ddbefc2e28732b0a278d1b8c868a0728f6ecd81d5cb29eaffc8e2b4a3f808c7acd0
7
- data.tar.gz: f9310e249ad33ed5199628483916d7e4299da7dbbf76b294cf8fc22d9c6223a58f63135d7ef24d985c3773d3b89a17acffb59bcf9d1cd89c2984be234afdf4c4
6
+ metadata.gz: c8220e4aadbdcbe9a992ada723431281665edda6a19c07771978b5a8b4ae9cf987a208ed69e9c96f4360a6a3ace9762dc930e4bab99574b2114effc0ffd1060e
7
+ data.tar.gz: 47790d4ee2171f4c2e95473f7c7cc6674d9634804c8c0dac2eeafff368df073166d9dfd371efc24026e1c94f4c333b1904af9fa4a959992116df7859dc314875
@@ -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
- @scratch = Scratch.new(@teal)
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
- @teal << 'b main' unless @teal.include? 'b main'
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 = @teal.pop
139
- @teal << "#{last_line} //#{content}"
143
+ last_line = TEAL.instance.pop
144
+ TEAL.instance << "#{last_line} //#{content}"
140
145
  else
141
- @teal << "//#{content}"
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
- @teal << string
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
- @teal.set_as_current
168
- @teal << 'main:' if @teal.include? 'b main'
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 @teal
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(@teal) - pre_teal
254
+ puts Array.new(TEAL.instance) - pre_teal
238
255
  puts ''
239
256
  end
240
257
  rescue SyntaxError, StandardError => e
@@ -6,39 +6,38 @@ module TEALrb
6
6
  attr_accessor :id
7
7
  end
8
8
 
9
- @id = {}.compare_by_identity
9
+ @id = 0
10
10
 
11
- def initialize(teal, _cond, &blk)
12
- self.class.id[teal] ||= 0
13
- @teal = teal
11
+ def initialize(_cond, &blk)
12
+ self.class.id ||= 0
14
13
  @else_count = 0
15
- @id = self.class.id[@teal]
14
+ @id = self.class.id
16
15
  @end_label = "if#{@id}_end:"
17
16
 
18
- self.class.id[@teal] += 1
17
+ self.class.id += 1
19
18
 
20
- @teal << "bz if#{@id}_else0"
19
+ TEAL.instance << "bz if#{@id}_else0"
21
20
  blk.call
22
- @teal << "b if#{@id}_end"
23
- @teal << "if#{@id}_else0:"
24
- @teal << @end_label
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
- @teal.delete @end_label
30
- @teal << "bz if#{@id}_else#{@else_count}"
28
+ TEAL.instance.delete @end_label
29
+ TEAL.instance << "bz if#{@id}_else#{@else_count}"
31
30
  blk.call
32
- @teal << "b if#{@id}_end"
33
- @teal << "if#{@id}_else#{@else_count}:"
34
- @teal << @end_label
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
- @teal.delete @end_label
38
+ TEAL.instance.delete @end_label
40
39
  blk.call
41
- @teal << @end_label
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
- TEALrb::TEAL.current[Thread.current] << "int #{type}"
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, index = nil)
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(index = nil)
684
- TxnaField.new('ApplicationArgs', index)
676
+ def self.application_args
677
+ TxnaField.new('ApplicationArgs')
685
678
  end
686
679
 
687
- def self.accounts(index = nil)
688
- TxnaField.new('Accounts', index)
680
+ def self.accounts
681
+ TxnaField.new('Accounts')
689
682
  end
690
683
 
691
- def self.assets(index = nil)
692
- TxnaField.new('Assets', index)
684
+ def self.assets
685
+ TxnaField.new('Assets')
693
686
  end
694
687
 
695
- def self.applications(index = nil)
696
- TxnaField.new('Applications', index)
688
+ def self.applications
689
+ TxnaField.new('Applications')
697
690
  end
698
691
 
699
- def self.logs(index = nil)
700
- TxnaField.new('Logs', index)
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