tealrb 0.6.0 → 0.9.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 +4 -4
- data/lib/tealrb/contract.rb +53 -20
- data/lib/tealrb/if_block.rb +16 -17
- data/lib/tealrb/opcode_modules.rb +345 -188
- data/lib/tealrb/opcodes.rb +478 -476
- data/lib/tealrb/rewriters.rb +54 -24
- data/lib/tealrb/scratch.rb +3 -4
- data/lib/tealrb.rb +12 -7
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d027d915afa0ccb6383791a694d6ca747bd07c14a2803d6ecaa8119b3277ffe9
|
4
|
+
data.tar.gz: e09162d147464ba6a7c0ada5c18bc9884832f164bb43f02a87d6d3f733093ce4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9b80748e7716e45b0bb87efcd0e70560bbb46fde5f6907ca6beaac59cd77ba4518acb41337df2fb5bb0aa6c9c8c86a6cfb28042ae95736028f4bcbdffc30c96
|
7
|
+
data.tar.gz: 791cb92688f986e2807770797c4ba5f61cd20e675c2887169126eb34bbbc40196e9a52ac64ecc79a4a9338ddb37632d20b5e08828a3d5b7cce9a2aa122ee2c57
|
data/lib/tealrb/contract.rb
CHANGED
@@ -4,13 +4,15 @@ module TEALrb
|
|
4
4
|
class Contract
|
5
5
|
include TEALrb
|
6
6
|
include Opcodes
|
7
|
+
include Opcodes::AllOpcodes
|
7
8
|
include ABI
|
8
9
|
include Rewriters
|
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
|
-
|
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,6 +90,25 @@ module TEALrb
|
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
93
|
+
def teal_source
|
94
|
+
teal_lines = []
|
95
|
+
|
96
|
+
@teal.each do |line|
|
97
|
+
ln = line.strip
|
98
|
+
|
99
|
+
if (ln[%r{\S+:($| //)}] && !ln[/^if\d+/]) || ln == 'b main' || ln[/^#/]
|
100
|
+
teal_lines << ln
|
101
|
+
elsif ln == 'retsub'
|
102
|
+
teal_lines << " #{ln}"
|
103
|
+
teal_lines << ''
|
104
|
+
else
|
105
|
+
teal_lines << " #{ln}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
teal_lines.join("\n")
|
110
|
+
end
|
111
|
+
|
89
112
|
# return the input without transpiling to TEAL
|
90
113
|
def rb(input)
|
91
114
|
input
|
@@ -96,8 +119,6 @@ module TEALrb
|
|
96
119
|
# @param definition [Lambda, Proc, UnboundMethod] the method definition
|
97
120
|
# @return [nil]
|
98
121
|
def define_teal_method(name, definition)
|
99
|
-
@teal.set_as_current
|
100
|
-
|
101
122
|
new_source = generate_method_source(name, definition)
|
102
123
|
|
103
124
|
define_singleton_method(name) do |*_args|
|
@@ -112,13 +133,11 @@ module TEALrb
|
|
112
133
|
# @param definition [Lambda, Proc, UnboundMethod] the method definition
|
113
134
|
# @return [nil]
|
114
135
|
def define_subroutine(name, definition)
|
115
|
-
@teal.set_as_current
|
116
|
-
|
117
136
|
define_singleton_method(name) do |*_args|
|
118
137
|
callsub(name)
|
119
138
|
end
|
120
139
|
|
121
|
-
|
140
|
+
TEAL.instance << 'b main' unless TEAL.instance.include? 'b main'
|
122
141
|
|
123
142
|
label(name) # add teal label
|
124
143
|
|
@@ -140,17 +159,18 @@ module TEALrb
|
|
140
159
|
def comment(content, inline: false)
|
141
160
|
content = " #{content}" unless content[0] == ' '
|
142
161
|
if inline
|
143
|
-
last_line =
|
144
|
-
|
162
|
+
last_line = TEAL.instance.pop
|
163
|
+
TEAL.instance << "#{last_line} //#{content}"
|
145
164
|
else
|
146
|
-
|
165
|
+
TEAL.instance << '' unless TEAL.instance.last[%r{^//}]
|
166
|
+
TEAL.instance << "//#{content}"
|
147
167
|
end
|
148
168
|
end
|
149
169
|
|
150
170
|
# inserts a string into TEAL source
|
151
171
|
# @param string [String] the string to insert
|
152
172
|
def placeholder(string)
|
153
|
-
|
173
|
+
TEAL.instance << string
|
154
174
|
end
|
155
175
|
|
156
176
|
# the hash of the abi description
|
@@ -162,20 +182,32 @@ module TEALrb
|
|
162
182
|
# @param string [String] string to transpile
|
163
183
|
# @return [nil]
|
164
184
|
def compile_string(string)
|
165
|
-
@teal.set_as_current
|
166
185
|
eval_tealrb(rewrite(string), debug_context: 'compile_string')
|
167
186
|
nil
|
168
187
|
end
|
169
188
|
|
170
|
-
# transpiles #main
|
189
|
+
# transpiles #main and routes abi methods. To disable abi routing, set `@disable_abi_routing` to true in your
|
190
|
+
# Contract subclass
|
171
191
|
def compile
|
172
|
-
|
173
|
-
|
174
|
-
eval_tealrb(rewrite(method(:main).source, method_rewriter: true), debug_context: 'main')
|
192
|
+
TEAL.instance << 'main:' if TEAL.instance.include? 'b main'
|
193
|
+
route_abi_methods unless self.class.disable_abi_routing
|
194
|
+
eval_tealrb(rewrite(method(:main).source, method_rewriter: true), debug_context: 'main') if respond_to? :main
|
175
195
|
end
|
176
196
|
|
177
197
|
private
|
178
198
|
|
199
|
+
def route_abi_methods
|
200
|
+
self.class.abi_description.methods.each do |meth|
|
201
|
+
signature = "#{meth[:name]}(#{meth[:args].map { _1[:type] }.join(',')})#{meth[:returns][:type]}"
|
202
|
+
selector = OpenSSL::Digest.new('SHA512-256').hexdigest(signature)[..7]
|
203
|
+
|
204
|
+
IfBlock.new(AppArgs[0] == byte(selector)) do
|
205
|
+
callsub(meth[:name])
|
206
|
+
approve
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
179
211
|
def generate_method_source(name, definition)
|
180
212
|
new_source = rewrite(definition.source, method_rewriter: true)
|
181
213
|
|
@@ -211,7 +243,8 @@ module TEALrb
|
|
211
243
|
puts ''
|
212
244
|
end
|
213
245
|
|
214
|
-
[CommentRewriter, ComparisonRewriter, WhileRewriter, IfRewriter, OpRewriter,
|
246
|
+
[CommentRewriter, ComparisonRewriter, WhileRewriter, InlineIfRewriter, IfRewriter, OpRewriter,
|
247
|
+
AssignRewriter].each do |rw|
|
215
248
|
string = rewrite_with_rewriter(string, rw)
|
216
249
|
end
|
217
250
|
|
@@ -227,7 +260,7 @@ module TEALrb
|
|
227
260
|
end
|
228
261
|
|
229
262
|
def eval_tealrb(s, debug_context:)
|
230
|
-
pre_teal = Array.new
|
263
|
+
pre_teal = Array.new TEAL.instance
|
231
264
|
|
232
265
|
if self.class.debug
|
233
266
|
puts "DEBUG: Evaluating the following code (#{debug_context}):"
|
@@ -239,13 +272,13 @@ module TEALrb
|
|
239
272
|
|
240
273
|
if self.class.debug
|
241
274
|
puts "DEBUG: Resulting TEAL (#{debug_context}):"
|
242
|
-
puts Array.new(
|
275
|
+
puts Array.new(TEAL.instance) - pre_teal
|
243
276
|
puts ''
|
244
277
|
end
|
245
278
|
rescue SyntaxError, StandardError => e
|
246
279
|
@eval_tealrb_rescue_count ||= 0
|
247
280
|
|
248
|
-
eval_locations = e.backtrace.select {_1[/\(eval\)/]}
|
281
|
+
eval_locations = e.backtrace.select { _1[/\(eval\)/] }
|
249
282
|
error_line = eval_locations[@eval_tealrb_rescue_count].split(':')[1].to_i
|
250
283
|
|
251
284
|
warn "'#{e}' when evaluating transpiled TEALrb source" if @eval_tealrb_rescue_count.zero?
|
data/lib/tealrb/if_block.rb
CHANGED
@@ -6,39 +6,38 @@ module TEALrb
|
|
6
6
|
attr_accessor :id
|
7
7
|
end
|
8
8
|
|
9
|
-
@id =
|
9
|
+
@id = 0
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
self.class.id
|
13
|
-
@teal = teal
|
11
|
+
def initialize(_cond, &blk)
|
12
|
+
self.class.id ||= 0
|
14
13
|
@else_count = 0
|
15
|
-
@id = self.class.id
|
14
|
+
@id = self.class.id
|
16
15
|
@end_label = "if#{@id}_end:"
|
17
16
|
|
18
|
-
self.class.id
|
17
|
+
self.class.id += 1
|
19
18
|
|
20
|
-
|
19
|
+
TEAL.instance << "bz if#{@id}_else0"
|
21
20
|
blk.call
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
30
|
-
|
28
|
+
TEAL.instance.delete @end_label
|
29
|
+
TEAL.instance << "bz if#{@id}_else#{@else_count}"
|
31
30
|
blk.call
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
38
|
+
TEAL.instance.delete @end_label
|
40
39
|
blk.call
|
41
|
-
|
40
|
+
TEAL.instance << @end_label
|
42
41
|
end
|
43
42
|
end
|
44
43
|
end
|