tealrb 0.4.0 → 0.7.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.
@@ -66,7 +66,7 @@ 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_methods', '@subroutines', '@scratch'].include? node.source
70
70
  super
71
71
  end
72
72
  end
@@ -82,7 +82,7 @@ module TEALrb
82
82
 
83
83
  class OpRewriter < Rewriter
84
84
  def initialize
85
- @skips = 0
85
+ @skips = []
86
86
  super
87
87
  end
88
88
 
@@ -109,43 +109,62 @@ module TEALrb
109
109
 
110
110
  OPCODE_METHODS = TEALrb::Opcodes.instance_methods.freeze
111
111
 
112
- def on_const(node)
113
- @skips = 1 if %w[Txna Gtxn AppArgs].include? node.loc.name.source
114
- super
115
- end
116
-
117
- def on_ivar(node)
118
- @skips = 2 if node.source == '@teal_methods'
119
- end
120
-
121
112
  def on_send(node)
122
- meth_name = node.loc.selector.source.to_sym
113
+ meth_name = node.children[1]
123
114
 
124
115
  if OPCODE_METHODS.include? meth_name
125
116
  if meth_name[/(byte|int)cblock/]
126
- @skips = node.children.size - 2
117
+ @skips += node.children[2..]
127
118
  else
128
119
  params = TEALrb::Opcodes.instance_method(meth_name).parameters
129
- @skips = params.count { |param| param[0] == :req }
120
+ req_params = params.count { |param| param[0] == :req }
121
+ @skips += node.children[2..(1 + req_params.size)] unless req_params.zero?
130
122
  end
131
- elsif %i[comment placeholder].include? meth_name
132
- @skips = 1
123
+ elsif %i[comment placeholder rb].include?(meth_name) ||
124
+ (%i[[] []=].include?(meth_name) &&
125
+ (
126
+ %i[@scratch @teal_methods Gtxn
127
+ AppArgs].include?(node.children[0].children.last) ||
128
+ node.children[0].children.first&.children&.last == :Txna
129
+ ))
130
+
131
+ @skips << node.children[2]
132
+ elsif node.children.first&.children&.last == :@scratch && meth_name[/=$/]
133
+ nil
134
+ elsif %i[@scratch Gtxn].include? node.children.first&.children&.last
135
+ @skips << node.children.last
133
136
  end
137
+
134
138
  super
135
139
  end
136
140
 
137
141
  def on_int(node)
138
- wrap(node.source_range, 'int(', ')') if (@skips -= 1).negative?
142
+ if @skips.include? node
143
+ @skips.delete(node)
144
+ else
145
+ wrap(node.source_range, 'int(', ')')
146
+ end
147
+
139
148
  super
140
149
  end
141
150
 
142
151
  def on_str(node)
143
- wrap(node.source_range, 'byte(', ')') if (@skips -= 1).negative?
152
+ if @skips.include? node
153
+ @skips.delete(node)
154
+ else
155
+ wrap(node.source_range, 'byte(', ')')
156
+ end
157
+
144
158
  super
145
159
  end
146
160
 
147
161
  def on_sym(node)
148
- wrap(node.source_range, 'label(', ')') if node.source_range.source[/^:/] && (@skips -= 1).negative?
162
+ if @skips.include? node
163
+ @skips.delete(node)
164
+ elsif node.source_range.source[/^:/]
165
+ wrap(node.source_range, 'label(', ')')
166
+ end
167
+
149
168
  super
150
169
  end
151
170
  end
@@ -154,7 +173,7 @@ module TEALrb
154
173
  def on_if(node)
155
174
  case node.loc.keyword.source
156
175
  when 'if'
157
- replace(node.loc.keyword, 'IfBlock.new(@teal, ')
176
+ replace(node.loc.keyword, 'IfBlock.new(')
158
177
  when 'elsif'
159
178
  replace(node.loc.keyword, 'end.elsif(')
160
179
  end
@@ -166,5 +185,30 @@ module TEALrb
166
185
  super
167
186
  end
168
187
  end
188
+
189
+ class WhileRewriter < Rewriter
190
+ class << self
191
+ attr_accessor :while_count
192
+ end
193
+
194
+ def initialize(*args)
195
+ self.class.while_count = {}
196
+ self.class.while_count[Thread.current] ||= 0
197
+ super
198
+ end
199
+
200
+ def while_count
201
+ self.class.while_count[Thread.current]
202
+ end
203
+
204
+ def on_while(node)
205
+ cond_node = node.children.first
206
+ replace(node.loc.keyword, ":while#{while_count}\n#{cond_node.source}\nbz :end_while#{while_count}")
207
+ replace(node.loc.begin, '') if node.loc.begin
208
+ replace(node.loc.end, "b :while#{while_count}\n:end_while#{while_count}")
209
+ replace(cond_node.loc.expression, '')
210
+ super
211
+ end
212
+ end
169
213
  end
170
214
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TEALrb
4
+ class Scratch
5
+ def initialize
6
+ @open_slots = (0..256).to_a
7
+ @named_slots = {}
8
+ end
9
+
10
+ def [](key)
11
+ TEAL.instance << "load #{@named_slots[key]} // #{key}"
12
+ end
13
+
14
+ def []=(key, _value)
15
+ store(key)
16
+ end
17
+
18
+ def store(key)
19
+ TEAL.instance << "store #{@named_slots[key] ||= @open_slots.shift} // #{key}"
20
+ end
21
+
22
+ def delete(key)
23
+ @open_slots << @named_slots.delete(key)
24
+ end
25
+
26
+ def reserve(slot)
27
+ name = @named_slots.key(slot)
28
+ raise ArgumentError, "Attempted to reserve a slot (#{slot}) that corresponds to a named slot (#{name})" if name
29
+
30
+ @open_slots.delete slot
31
+ end
32
+
33
+ def unreserve(slot)
34
+ @open_slots << slot
35
+ end
36
+
37
+ def respond_to_missing?
38
+ !!(meth[/=$/] || @named_slots.key?(meth.to_s))
39
+ end
40
+
41
+ def method_missing(meth, *args, &block)
42
+ super unless block.nil?
43
+
44
+ if meth[/=$/]
45
+ store(meth.to_s.chomp('='))
46
+ elsif @named_slots.key?(meth.to_s)
47
+ self[meth.to_s]
48
+ else
49
+ super
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/tealrb.rb CHANGED
@@ -9,19 +9,25 @@ 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
 
15
16
  module TEALrb
16
17
  class TEAL < Array
17
18
  class << self
18
- attr_accessor :current
19
- end
19
+ attr_writer :instance
20
+
21
+ def instance
22
+ raise 'TEALrb does not support multi-threading' if Thread.current != Thread.main
20
23
 
21
- @current = {}
24
+ @instance
25
+ end
26
+ end
22
27
 
23
- def set_as_current
24
- self.class.current[Thread.current] = self
28
+ def initialize(teal_array)
29
+ self.class.instance = self
30
+ super
25
31
  end
26
32
 
27
33
  def teal
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.4.0
4
+ version: 0.7.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-16 00:00:00.000000000 Z
11
+ date: 2022-07-28 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