tealrb 0.3.1 → 0.6.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: 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