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 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