tealrb 0.3.1 → 0.6.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: def52b90a6225a1e78408d4b4ec6d65c7504d03a5512bcde9b03cad284bf34df
4
- data.tar.gz: d4d23914a76b46bdf6ec45a7c9f087262531d26499967770b6965f63508a9e5e
3
+ metadata.gz: 4ebe163f8903cf66046698ddfebe36e615359bd568e76be4eb30f368011b1ce0
4
+ data.tar.gz: 64db7183fe7b170d7b80881cd66272e5016e6a50cb6886a5300df729520d539d
5
5
  SHA512:
6
- metadata.gz: cfbfc5ebd26982b646a8a1d1de65a741a5e5711d9cccf822a3abcf1698b42977fa309d409c95b569521b289a4bf73b334f574bf3fe113c8616b02c662c7da60c
7
- data.tar.gz: 7996f80823ca5cdac127207bef2899d42fe6f668b2d0d5a813c9d1d141b5521b703ef177621fe0cc64a12f7b8365bb65c604d8cf0f0158595c952e42be80e135
6
+ metadata.gz: 94f4791ca50e11afb7937670b976a87f75aaeaa4b364e5eea104541c571fce4f2b41e73c05c7d743772fb37657cf9dc3690e869d49007b3bd77ea4c5168ff1e5
7
+ data.tar.gz: f77f3513679a82d255a8a1e10cc51c8e593b66d0faae844df461a36d50b211a62b5cd9761a93c1f34591b375439766eba38238f4670a7205cc00eb72bd553c57
@@ -69,6 +69,7 @@ module TEALrb
69
69
  # sets the `#pragma version`, defines teal methods, and defines subroutines
70
70
  def initialize
71
71
  @teal = TEAL.new ["#pragma version #{self.class.version}"]
72
+ @scratch = Scratch.new(@teal)
72
73
 
73
74
  self.class.subroutines.each_key do |name|
74
75
  define_singleton_method(name) do |*_args|
@@ -85,6 +86,11 @@ module TEALrb
85
86
  end
86
87
  end
87
88
 
89
+ # return the input without transpiling to TEAL
90
+ def rb(input)
91
+ input
92
+ end
93
+
88
94
  # defines a method that is transpiled to TEAL
89
95
  # @param name [Symbol] name of the method
90
96
  # @param definition [Lambda, Proc, UnboundMethod] the method definition
@@ -92,18 +98,8 @@ module TEALrb
92
98
  def define_teal_method(name, definition)
93
99
  @teal.set_as_current
94
100
 
95
- new_source = rewrite(definition.source, method_rewriter: true)
101
+ new_source = generate_method_source(name, definition)
96
102
 
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
105
-
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
@@ -130,18 +126,9 @@ module TEALrb
130
126
  comment_content = "#{name}(#{comment_params})"
131
127
  comment(comment_content, inline: true)
132
128
 
133
- new_source = rewrite(definition.source, method_rewriter: true)
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
129
+ new_source = generate_method_source(name, definition)
130
+ new_source = "#{new_source}retsub"
143
131
 
144
- new_source = "#{pre_string.string}#{new_source}retsub"
145
132
  eval_tealrb(new_source, debug_context: "subroutine: #{name}")
146
133
 
147
134
  nil
@@ -189,6 +176,29 @@ module TEALrb
189
176
 
190
177
  private
191
178
 
179
+ def generate_method_source(name, definition)
180
+ new_source = rewrite(definition.source, method_rewriter: true)
181
+
182
+ pre_string = StringIO.new
183
+
184
+ scratch_names = []
185
+ definition.parameters.reverse.each_with_index do |param, _i|
186
+ param_name = param.last
187
+ scratch_name = [name, param_name].map(&:to_s).join(': ')
188
+ scratch_names << scratch_name
189
+
190
+ pre_string.puts "@scratch.store('#{scratch_name}')"
191
+ pre_string.puts "#{param_name} = -> { @scratch['#{scratch_name}'] }"
192
+ end
193
+
194
+ post_string = StringIO.new
195
+ scratch_names.each do |n|
196
+ post_string.puts "@scratch.delete '#{n}'"
197
+ end
198
+
199
+ "#{pre_string.string}#{new_source}#{post_string.string}"
200
+ end
201
+
192
202
  def rewrite_with_rewriter(string, rewriter)
193
203
  process_source = RuboCop::ProcessedSource.new(string, RUBY_VERSION[/\d\.\d/].to_f)
194
204
  rewriter.new.rewrite(process_source)
@@ -201,7 +211,7 @@ module TEALrb
201
211
  puts ''
202
212
  end
203
213
 
204
- [CommentRewriter, ComparisonRewriter, IfRewriter, OpRewriter, AssignRewriter].each do |rw|
214
+ [CommentRewriter, ComparisonRewriter, WhileRewriter, IfRewriter, OpRewriter, AssignRewriter].each do |rw|
205
215
  string = rewrite_with_rewriter(string, rw)
206
216
  end
207
217
 
@@ -664,31 +664,38 @@ module TEALrb
664
664
  end
665
665
  end
666
666
 
667
- class TxnArrayIndex
667
+ class TxnaField
668
668
  include Opcodes
669
- include TxnFields
670
669
 
671
- def initialize(index)
672
- @index = index
670
+ def initialize(field)
671
+ @field = field
673
672
  end
674
673
 
675
- def opcode(field)
674
+ def [](index)
676
675
  @teal = TEALrb::TEAL.current[Thread.current]
677
- txna field, @index
676
+ txna @field, index
678
677
  end
679
678
  end
680
679
 
681
680
  module Txna
682
- extend Opcodes
683
- extend TxnFields
681
+ def self.application_args
682
+ TxnaField.new('ApplicationArgs')
683
+ end
684
684
 
685
- def self.opcode(field, index)
686
- @teal = TEALrb::TEAL.current[Thread.current]
687
- txna field, index
685
+ def self.accounts
686
+ TxnaField.new('Accounts')
688
687
  end
689
688
 
690
- def self.[](index)
691
- TxnArrayIndex.new(index)
689
+ def self.assets
690
+ TxnaField.new('Assets')
691
+ end
692
+
693
+ def self.applications
694
+ TxnaField.new('Applications')
695
+ end
696
+
697
+ def self.logs
698
+ TxnaField.new('Logs')
692
699
  end
693
700
  end
694
701
 
@@ -712,7 +719,7 @@ module TEALrb
712
719
 
713
720
  module AppArgs
714
721
  def self.[](index)
715
- Txna.application_args index
722
+ Txna.application_args[index]
716
723
  end
717
724
  end
718
725
  end
@@ -66,7 +66,8 @@ module TEALrb
66
66
  end
67
67
 
68
68
  def on_ivar(node)
69
- insert_after(node.loc.name, '.call') unless ['@teal', '@teal_methods', '@subroutines'].include? node.source
69
+ insert_after(node.loc.name, '.call') unless ['@teal', '@teal_methods', '@subroutines',
70
+ '@scratch'].include? node.source
70
71
  super
71
72
  end
72
73
  end
@@ -116,6 +117,7 @@ module TEALrb
116
117
 
117
118
  def on_ivar(node)
118
119
  @skips = 2 if node.source == '@teal_methods'
120
+ @skips = 1 if node.source == '@scratch'
119
121
  end
120
122
 
121
123
  def on_send(node)
@@ -128,8 +130,8 @@ module TEALrb
128
130
  params = TEALrb::Opcodes.instance_method(meth_name).parameters
129
131
  @skips = params.count { |param| param[0] == :req }
130
132
  end
131
- elsif %i[comment placeholder].include? meth_name
132
- @skips = 1
133
+ elsif %i[comment placeholder rb].include? meth_name
134
+ @skips = node.children.last.children.size
133
135
  end
134
136
  super
135
137
  end
@@ -166,5 +168,30 @@ module TEALrb
166
168
  super
167
169
  end
168
170
  end
171
+
172
+ class WhileRewriter < Rewriter
173
+ class << self
174
+ attr_accessor :while_count
175
+ end
176
+
177
+ def initialize(*args)
178
+ self.class.while_count = {}
179
+ self.class.while_count[Thread.current] ||= 0
180
+ super
181
+ end
182
+
183
+ def while_count
184
+ self.class.while_count[Thread.current]
185
+ end
186
+
187
+ def on_while(node)
188
+ cond_node = node.children.first
189
+ replace(node.loc.keyword, ":while#{while_count}\n#{cond_node.source}\nbz :end_while#{while_count}")
190
+ replace(node.loc.begin, '') if node.loc.begin
191
+ replace(node.loc.end, "b :while#{while_count}\n:end_while#{while_count}")
192
+ replace(cond_node.loc.expression, '')
193
+ super
194
+ end
195
+ end
169
196
  end
170
197
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TEALrb
4
+ class Scratch
5
+ def initialize(teal)
6
+ @teal = teal
7
+ @open_slots = (0..256).to_a
8
+ @named_slots = {}
9
+ end
10
+
11
+ def [](key)
12
+ @teal << "load #{@named_slots[key]} // #{key}"
13
+ end
14
+
15
+ def []=(key, _value)
16
+ store(key)
17
+ end
18
+
19
+ def store(key)
20
+ @teal << "store #{@named_slots[key] ||= @open_slots.shift} // #{key}"
21
+ end
22
+
23
+ def delete(key)
24
+ @open_slots << @named_slots.delete(key)
25
+ end
26
+
27
+ def reserve(slot)
28
+ name = @named_slots.key(slot)
29
+ raise ArgumentError, "Attempted to reserve a slot (#{slot}) that corresponds to a named slot (#{name})" if name
30
+
31
+ @open_slots.delete slot
32
+ end
33
+
34
+ def unreserve(slot)
35
+ @open_slots << slot
36
+ end
37
+ end
38
+ end
data/lib/tealrb.rb CHANGED
@@ -9,6 +9,7 @@ require_relative 'tealrb/opcodes'
9
9
  require_relative 'tealrb/opcode_modules'
10
10
  require_relative 'tealrb/rewriters'
11
11
  require_relative 'tealrb/if_block'
12
+ require_relative 'tealrb/scratch'
12
13
  require_relative 'tealrb/contract'
13
14
  require_relative 'tealrb/cmd_line/teal2tealrb'
14
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tealrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Polny
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-15 00:00:00.000000000 Z
11
+ date: 2022-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: method_source
@@ -152,6 +152,7 @@ files:
152
152
  - lib/tealrb/opcodes.rb
153
153
  - lib/tealrb/patches.rb
154
154
  - lib/tealrb/rewriters.rb
155
+ - lib/tealrb/scratch.rb
155
156
  homepage: https://github.com/joe-p/tealrb
156
157
  licenses:
157
158
  - MIT