tealrb 0.6.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|