ytl 0.0.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.
- data/README +37 -0
- data/bin/ytl +11 -0
- data/lib/ytl/accmem.rb +334 -0
- data/lib/ytl/importobj.rb +10 -0
- data/lib/ytl.rb +131 -0
- data/runtime/prelude.rb +30 -0
- data/runtime/type.rb +10 -0
- data/test/basictest.rb +146 -0
- data/test/classtest.rb +50 -0
- data/test/exceptiontest.rb +21 -0
- data/test/exttest.rb +35 -0
- data/test/floattest.rb +4 -0
- data/test/looptest.rb +20 -0
- data/test/tmp.rb +7 -0
- metadata +97 -0
data/README
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
1. Waht is ytl
|
2
|
+
|
3
|
+
Ytl is translator from CRuby VM (aka YARV) to X86-32/X86-64 Native Code.
|
4
|
+
Ytl uses ytljit as code generate library.
|
5
|
+
|
6
|
+
2. Install
|
7
|
+
|
8
|
+
Install ytljit
|
9
|
+
gem install ytljit
|
10
|
+
|
11
|
+
Enjoy or take pains
|
12
|
+
|
13
|
+
3. Sample
|
14
|
+
|
15
|
+
ruby lib/ytl.rb test/basictest.rb
|
16
|
+
|
17
|
+
"copy" # This message is for debug
|
18
|
+
"copy" # This message is for debug
|
19
|
+
"copy" # This message is for debug
|
20
|
+
"copy" # This message is for debug
|
21
|
+
1
|
22
|
+
1.9
|
23
|
+
3
|
24
|
+
14930352
|
25
|
+
4
|
26
|
+
14
|
27
|
+
|
28
|
+
3. License
|
29
|
+
|
30
|
+
Ruby's
|
31
|
+
|
32
|
+
4. Author
|
33
|
+
|
34
|
+
Miura Hideki
|
35
|
+
m-72 at tf6.so-net.ne.jp (e-mail)
|
36
|
+
http://twitter.com/miura1729 (twitter)
|
37
|
+
http://d.hatena.ne.jp/miura1729 (blog in japanese)
|
data/bin/ytl
ADDED
data/lib/ytl/accmem.rb
ADDED
@@ -0,0 +1,334 @@
|
|
1
|
+
module YTL
|
2
|
+
class Memory
|
3
|
+
end
|
4
|
+
TheMemory = Memory.new
|
5
|
+
end
|
6
|
+
|
7
|
+
module YTLJit
|
8
|
+
module VM
|
9
|
+
module Node
|
10
|
+
|
11
|
+
class SendElementRefMemoryNode<SendElementRefNode
|
12
|
+
include SendUtil
|
13
|
+
include X86
|
14
|
+
include X64
|
15
|
+
|
16
|
+
add_special_send_node :[]
|
17
|
+
|
18
|
+
def fill_result_cache(context)
|
19
|
+
slf = @arguments[2]
|
20
|
+
slfval = @arguments[2].get_constant_value
|
21
|
+
if slfval then
|
22
|
+
slfval =slfval[0]
|
23
|
+
|
24
|
+
idxval = @arguments[3].get_constant_value
|
25
|
+
if idxval then
|
26
|
+
idxval = idxval[0]
|
27
|
+
@result_cache = slfval[idxval]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context
|
32
|
+
end
|
33
|
+
|
34
|
+
def collect_candidate_type_regident(context, slf)
|
35
|
+
if slf.ruby_type <= YTL::Memory then
|
36
|
+
kind = @arguments[4]
|
37
|
+
kvalue = kind.get_constant_value
|
38
|
+
|
39
|
+
if kvalue then
|
40
|
+
kvalue =kvalue[0]
|
41
|
+
|
42
|
+
case kvalue
|
43
|
+
when :char, :word, :dword, :machine_word
|
44
|
+
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
45
|
+
add_type(context.to_signature, fixtype)
|
46
|
+
|
47
|
+
when :float
|
48
|
+
floattype = RubyType::BaseType.from_ruby_class(Float)
|
49
|
+
add_type(context.to_signature, floattype)
|
50
|
+
|
51
|
+
when AsmType::StructMember
|
52
|
+
if kvalue.type.is_a?(AsmType::Scalar) then
|
53
|
+
if kvalue.type.kind == :int then
|
54
|
+
ttype = RubyType::BaseType.from_ruby_class(Fixnum)
|
55
|
+
add_type(context.to_signature, ttype)
|
56
|
+
else
|
57
|
+
raise "Unkown type #{kvalue.type} #{kvalue.type.kind}"
|
58
|
+
end
|
59
|
+
else
|
60
|
+
raise "Unkown type #{kvalue}"
|
61
|
+
end
|
62
|
+
|
63
|
+
when AsmType::Scalar
|
64
|
+
if kvalue.kind == :int then
|
65
|
+
ttype = RubyType::BaseType.from_ruby_class(Fixnum)
|
66
|
+
add_type(context.to_signature, ttype)
|
67
|
+
|
68
|
+
else
|
69
|
+
raise "Unkown type"
|
70
|
+
end
|
71
|
+
|
72
|
+
else
|
73
|
+
raise "Unkown type #{kvalue}"
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
else
|
78
|
+
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
79
|
+
add_type(context.to_signature, fixtype)
|
80
|
+
end
|
81
|
+
|
82
|
+
context
|
83
|
+
|
84
|
+
elsif slf.ruby_type <= AsmType::Pointer or
|
85
|
+
slf.ruby_type <= AsmType::Array then
|
86
|
+
tt = AsmType::PointedData
|
87
|
+
pointedtype = RubyType::BaseType.from_ruby_class(tt)
|
88
|
+
add_type(context.to_signature, pointedtype)
|
89
|
+
context
|
90
|
+
|
91
|
+
elsif slf.ruby_type <= AsmType::Struct or
|
92
|
+
slf.ruby_type <= AsmType::Union or
|
93
|
+
slf.ruby_type <= AsmType::StructMember then
|
94
|
+
tt = AsmType::StructMember
|
95
|
+
stmemtype = RubyType::BaseType.from_ruby_class(tt)
|
96
|
+
add_type(context.to_signature, stmemtype)
|
97
|
+
context
|
98
|
+
|
99
|
+
else
|
100
|
+
super
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def compile_ref_scalar(context, typeobj)
|
105
|
+
context
|
106
|
+
end
|
107
|
+
|
108
|
+
def gen_read_mem(context, size)
|
109
|
+
asm = context.assembler
|
110
|
+
case size
|
111
|
+
when 8
|
112
|
+
asm.with_retry do
|
113
|
+
if context.ret_reg != RAX then
|
114
|
+
asm.mov(RAX, context.ret_reg)
|
115
|
+
end
|
116
|
+
asm.mov(RAX, INDIRECT_RAX)
|
117
|
+
end
|
118
|
+
context.ret_reg = RAX
|
119
|
+
|
120
|
+
when 4
|
121
|
+
asm.with_retry do
|
122
|
+
if context.ret_reg != EAX then
|
123
|
+
asm.mov(EAX, context.ret_reg)
|
124
|
+
end
|
125
|
+
asm.mov(EAX, INDIRECT_EAX)
|
126
|
+
end
|
127
|
+
context.ret_reg = EAX
|
128
|
+
|
129
|
+
when 2
|
130
|
+
asm.with_retry do
|
131
|
+
asm.mov(AL, context.ret_reg)
|
132
|
+
asm.mov(AL, INDIRECT_AL)
|
133
|
+
end
|
134
|
+
context.ret_reg = EAX
|
135
|
+
|
136
|
+
else
|
137
|
+
raise "Unkown Scalar size #{kvalue}"
|
138
|
+
end
|
139
|
+
|
140
|
+
context
|
141
|
+
end
|
142
|
+
|
143
|
+
def compile(context)
|
144
|
+
slf = @arguments[2]
|
145
|
+
slf.decide_type_once(context.to_signature)
|
146
|
+
if slf.type.ruby_type <= YTL::Memory then
|
147
|
+
asm = context.assembler
|
148
|
+
|
149
|
+
kind = @arguments[4]
|
150
|
+
kvalue = nil
|
151
|
+
case kind
|
152
|
+
when LiteralNode
|
153
|
+
kvalue = kind.value
|
154
|
+
|
155
|
+
else
|
156
|
+
context = kind.compile(context)
|
157
|
+
if context.ret_reg.is_a?(OpVarImmidiateAddress) then
|
158
|
+
objid = (context.ret_reg.value >> 1)
|
159
|
+
kvalue = ObjectSpace._id2ref(objid)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context = @arguments[3].compile(context)
|
164
|
+
|
165
|
+
case kvalue
|
166
|
+
when :machine_word
|
167
|
+
asm.with_retry do
|
168
|
+
if context.ret_reg != TMPR then
|
169
|
+
asm.mov(TMPR, context.ret_reg)
|
170
|
+
end
|
171
|
+
asm.mov(RETR, INDIRECT_TMPR)
|
172
|
+
end
|
173
|
+
context.ret_reg = RETR
|
174
|
+
|
175
|
+
when :float
|
176
|
+
asm.with_retry do
|
177
|
+
if context.ret_reg != TMPR then
|
178
|
+
asm.mov(TMPR, context.ret_reg)
|
179
|
+
end
|
180
|
+
asm.mov(RETFR, INDIRECT_TMPR)
|
181
|
+
end
|
182
|
+
context.ret_reg = RETFR
|
183
|
+
|
184
|
+
when AsmType::Scalar
|
185
|
+
context = gen_read_mem(context, kvalue.size)
|
186
|
+
|
187
|
+
when AsmType::StructMember
|
188
|
+
typeobj = kvalue.type
|
189
|
+
case typeobj
|
190
|
+
when AsmType::Scalar
|
191
|
+
context = gen_read_mem(context, typeobj.size)
|
192
|
+
|
193
|
+
else
|
194
|
+
raise "Unkown Struct Member type #{kvalue}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context.ret_node = self
|
199
|
+
return context
|
200
|
+
|
201
|
+
elsif slf.type.ruby_type <= AsmType::TypeCommon then
|
202
|
+
context = @arguments[2].compile(context)
|
203
|
+
obj = slf.get_constant_value
|
204
|
+
|
205
|
+
if obj == nil and
|
206
|
+
context.ret_reg.is_a?(OpVarImmidiateAddress) then
|
207
|
+
objid = (context.ret_reg.value >> 1)
|
208
|
+
obj = ObjectSpace._id2ref(objid)
|
209
|
+
else
|
210
|
+
obj = obj[0]
|
211
|
+
end
|
212
|
+
|
213
|
+
if obj then
|
214
|
+
index = @arguments[3].get_constant_value
|
215
|
+
|
216
|
+
if index then
|
217
|
+
index = index[0]
|
218
|
+
val = obj[index]
|
219
|
+
add = lambda { val.address }
|
220
|
+
context.ret_reg = OpVarImmidiateAddress.new(add)
|
221
|
+
context.ret_node = self
|
222
|
+
|
223
|
+
return context
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
super
|
228
|
+
else
|
229
|
+
super
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class SendNewArenaNode<SendNewNode
|
235
|
+
add_special_send_node :new
|
236
|
+
|
237
|
+
def traverse_childlen
|
238
|
+
@arguments.each do |arg|
|
239
|
+
yield arg
|
240
|
+
end
|
241
|
+
yield @func
|
242
|
+
yield @body
|
243
|
+
end
|
244
|
+
|
245
|
+
def collect_candidate_type_regident(context, slf)
|
246
|
+
if Runtime::Arena.is_a?(slf.ruby_type) then
|
247
|
+
slfcls = @arguments[2].get_constant_value
|
248
|
+
tt = RubyType::BaseType.from_ruby_class(slfcls[0])
|
249
|
+
add_type(context.to_signature, tt)
|
250
|
+
|
251
|
+
if @initmethod.is_a?(SendInitializeNode) then
|
252
|
+
# Get alloc method call node
|
253
|
+
@initmethod = @initmethod.arguments[2]
|
254
|
+
end
|
255
|
+
|
256
|
+
return context
|
257
|
+
end
|
258
|
+
|
259
|
+
return super
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
class SendAddressNode<SendNode
|
264
|
+
include InternalRubyType
|
265
|
+
add_special_send_node :address
|
266
|
+
|
267
|
+
def collect_candidate_type_regident(context, slf)
|
268
|
+
if slf.ruby_type == Runtime::Arena then
|
269
|
+
tt = RubyType::BaseType.from_ruby_class(Fixnum)
|
270
|
+
add_type(context.to_signature, tt)
|
271
|
+
|
272
|
+
return context
|
273
|
+
end
|
274
|
+
|
275
|
+
super
|
276
|
+
end
|
277
|
+
|
278
|
+
def compile(context)
|
279
|
+
context = @arguments[2].compile(context)
|
280
|
+
@arguments[2].decide_type_once(context.to_signature)
|
281
|
+
rtype = @arguments[2].type
|
282
|
+
rrtype = rtype.ruby_type
|
283
|
+
if rrtype == Runtime::Arena then
|
284
|
+
asm = context.assembler
|
285
|
+
rsdata = TypedData.new(RData, context.ret_reg)
|
286
|
+
asm.with_retry do
|
287
|
+
dmy, arena = asm.mov(TMPR, rsdata[:data])
|
288
|
+
asm.mov(TMPR, arena[0][:body])
|
289
|
+
end
|
290
|
+
context.ret_reg = TMPR
|
291
|
+
context.ret_node = self
|
292
|
+
context
|
293
|
+
else
|
294
|
+
super
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
class SendInstanceMemoryNode<SendNode
|
300
|
+
add_special_send_node :instance
|
301
|
+
|
302
|
+
def collect_candidate_type_regident(context, slf)
|
303
|
+
if YTL::Memory.is_a?(slf.ruby_type) then
|
304
|
+
slfcls = @arguments[2].get_constant_value
|
305
|
+
if slfcls then
|
306
|
+
tt = RubyType::BaseType.from_ruby_class(slfcls[0])
|
307
|
+
add_type(context.to_signature, tt)
|
308
|
+
end
|
309
|
+
|
310
|
+
return context
|
311
|
+
end
|
312
|
+
|
313
|
+
super
|
314
|
+
end
|
315
|
+
|
316
|
+
def compile(context)
|
317
|
+
@arguments[2].decide_type_once(context.to_signature)
|
318
|
+
rtype = @arguments[2].type
|
319
|
+
rrtype = rtype.ruby_type
|
320
|
+
if YTL::Memory.is_a?(rrtype) then
|
321
|
+
objadd = lambda {
|
322
|
+
YTL::TheMemory.address
|
323
|
+
}
|
324
|
+
context.ret_reg = OpVarImmidiateAddress.new(objadd)
|
325
|
+
context.ret_node = self
|
326
|
+
context
|
327
|
+
else
|
328
|
+
super
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
data/lib/ytl.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'ytljit'
|
2
|
+
require 'ytl/accmem.rb'
|
3
|
+
require 'ytl/importobj.rb'
|
4
|
+
require 'pp'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
include YTLJit
|
8
|
+
module YTL
|
9
|
+
include YTLJit
|
10
|
+
|
11
|
+
ISEQ_OPTS = {
|
12
|
+
:peephole_optimization => true,
|
13
|
+
:inline_const_cache => false,
|
14
|
+
:specialized_instruction => false,
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.parse_opt(argv)
|
18
|
+
ytlopt = {}
|
19
|
+
prelude = File.join(File.dirname(__FILE__), "..", "runtime", "prelude.rb")
|
20
|
+
ytlopt[:execute_before_compile] = [prelude]
|
21
|
+
opt = OptionParser.new
|
22
|
+
|
23
|
+
opt.on('--disasm', 'Disasemble generated code') do |f|
|
24
|
+
ytlopt[:disasm] = f
|
25
|
+
end
|
26
|
+
|
27
|
+
opt.on('--dump-yarv', 'Dump YARV byte code') do |f|
|
28
|
+
ytlopt[:dump_yarv] = f
|
29
|
+
end
|
30
|
+
|
31
|
+
opt.on('--disp-signature', 'Display signature of method') do |f|
|
32
|
+
ytlopt[:disp_signature] = f
|
33
|
+
end
|
34
|
+
|
35
|
+
opt.on('--dump-context', 'Dump context(registor/stack) for debug') do |f|
|
36
|
+
ytlopt[:dump_context] = f
|
37
|
+
end
|
38
|
+
|
39
|
+
opt.on('--write-code =FILE', 'Write generating code') do |f|
|
40
|
+
ytlopt[:write_code] = f
|
41
|
+
end
|
42
|
+
|
43
|
+
opt.on('--write-node-before-type-inference =FILE',
|
44
|
+
'Write node of before type inference') do |f|
|
45
|
+
ytlopt[:write_node_before_ti] = f
|
46
|
+
end
|
47
|
+
|
48
|
+
opt.on('--write-node-after-type-inference =FILE',
|
49
|
+
'Write node of after type inference') do |f|
|
50
|
+
ytlopt[:write_node_after_ti] = f
|
51
|
+
end
|
52
|
+
|
53
|
+
opt.on('-r FILE', '--execute-before-compile =FILE',
|
54
|
+
'Execute ruby program (execute by CRuby)') do |f|
|
55
|
+
ytlopt[:execute_before_compile].push f
|
56
|
+
end
|
57
|
+
|
58
|
+
opt.parse!(argv)
|
59
|
+
ytlopt
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.main(options)
|
63
|
+
tr_context = VM::YARVContext.new
|
64
|
+
progs = []
|
65
|
+
|
66
|
+
import_ruby_object(tr_context)
|
67
|
+
options[:execute_before_compile].each do |fn|
|
68
|
+
rf = File.read(fn)
|
69
|
+
prog = eval(rf)
|
70
|
+
progs.push prog
|
71
|
+
end
|
72
|
+
|
73
|
+
prog = progs.join("\n") + File.read(ARGV[0])
|
74
|
+
is = RubyVM::InstructionSequence.compile(prog, ARGV[0],
|
75
|
+
"", 0, ISEQ_OPTS).to_a
|
76
|
+
iseq = VMLib::InstSeqTree.new(nil, is)
|
77
|
+
if options[:dump_yarv] then
|
78
|
+
pp iseq
|
79
|
+
end
|
80
|
+
|
81
|
+
tr = VM::YARVTranslatorCRubyObject.new([iseq])
|
82
|
+
tnode = tr.translate(tr_context)
|
83
|
+
ci_context = VM::CollectInfoContext.new(tnode)
|
84
|
+
tnode.collect_info(ci_context)
|
85
|
+
|
86
|
+
if fn = options[:write_node_before_ti] then
|
87
|
+
File.open(fn, "w") do |fp|
|
88
|
+
fp.print Marshal.dump(tnode)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
dmylit = VM::Node::LiteralNode.new(tnode, nil)
|
93
|
+
arg = [dmylit, dmylit, dmylit]
|
94
|
+
sig = []
|
95
|
+
arg.each do |ele|
|
96
|
+
sig.push RubyType::BaseType.from_ruby_class(NilClass)
|
97
|
+
end
|
98
|
+
|
99
|
+
ti_context = VM::TypeInferenceContext.new(tnode)
|
100
|
+
begin
|
101
|
+
tnode.collect_candidate_type(ti_context, arg, sig)
|
102
|
+
end until ti_context.convergent
|
103
|
+
ti_context = tnode.collect_candidate_type(ti_context, arg, sig)
|
104
|
+
|
105
|
+
c_context = VM::CompileContext.new(tnode)
|
106
|
+
c_context.current_method_signature.push sig
|
107
|
+
c_context.options = options
|
108
|
+
c_context = tnode.compile(c_context)
|
109
|
+
|
110
|
+
if fn = options[:write_node_after_ti] then
|
111
|
+
File.open(fn, "w") do |fp|
|
112
|
+
fp.print Marshal.dump(tnode)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
if options[:disasm] then
|
117
|
+
tnode.code_space_tab.each do |cs|
|
118
|
+
cs.fill_disasm_cache
|
119
|
+
end
|
120
|
+
tnode.code_space.disassemble
|
121
|
+
end
|
122
|
+
|
123
|
+
tcs = tnode.code_space
|
124
|
+
STDOUT.flush
|
125
|
+
tcs.call(tcs.base_address)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
if __FILE__ == $0 then
|
130
|
+
YTL::main(YTL::parse_opt(ARGV))
|
131
|
+
end
|
data/runtime/prelude.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# runtime library written in ytl
|
2
|
+
<<-'EOS'
|
3
|
+
#
|
4
|
+
class Array
|
5
|
+
def each
|
6
|
+
i = 0
|
7
|
+
e = self.size
|
8
|
+
while i < e
|
9
|
+
yield self[i]
|
10
|
+
i = i + 1
|
11
|
+
end
|
12
|
+
|
13
|
+
self
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Fixnum
|
18
|
+
def times
|
19
|
+
i = 0
|
20
|
+
while i < self
|
21
|
+
yield i
|
22
|
+
i = i + 1
|
23
|
+
end
|
24
|
+
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
EOS
|
30
|
+
|
data/runtime/type.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
include YTLJit
|
2
|
+
include InternalRubyType
|
3
|
+
|
4
|
+
tr_context.import_object(YTLJit::AsmType, :VALUE, VALUE)
|
5
|
+
tr_context.import_object(YTLJit::AsmType, :P_CHAR, P_CHAR)
|
6
|
+
tr_context.import_object(YTLJit::AsmType, :RBasic, RBasic)
|
7
|
+
tr_context.import_object(YTLJit::AsmType, :RString, RString)
|
8
|
+
tr_context.import_object(YTLJit::AsmType, :RFloat, RFloat)
|
9
|
+
tr_context.import_object(YTLJit::Runtime, :Arena, Runtime::Arena)
|
10
|
+
""
|
data/test/basictest.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
def id (x)
|
2
|
+
x
|
3
|
+
end
|
4
|
+
|
5
|
+
p id(1)
|
6
|
+
p id(1.9)
|
7
|
+
|
8
|
+
def array
|
9
|
+
a = [3, 5, 6]
|
10
|
+
p a
|
11
|
+
a[1] = 1
|
12
|
+
p a
|
13
|
+
[1, 2, 3][0] + [1, 2, 3][1]
|
14
|
+
end
|
15
|
+
p array
|
16
|
+
|
17
|
+
def fib(x)
|
18
|
+
if x < 2 then
|
19
|
+
1
|
20
|
+
else
|
21
|
+
fib(x-1) + fib(x-2)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
p fib(35)
|
26
|
+
|
27
|
+
def fib2(x)
|
28
|
+
if x < 2 then
|
29
|
+
1.0
|
30
|
+
else
|
31
|
+
fib2(x-1) + fib2(x-2)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
p fib2(35)
|
36
|
+
|
37
|
+
def blk0(x)
|
38
|
+
yield(x) + 2
|
39
|
+
end
|
40
|
+
|
41
|
+
def blk1(x)
|
42
|
+
yield(x) + 10
|
43
|
+
end
|
44
|
+
|
45
|
+
p blk0(1) {|a| a + 1}
|
46
|
+
p blk1(1) {|a| blk0(a) {|b| b + a}}
|
47
|
+
|
48
|
+
def blk3
|
49
|
+
yield
|
50
|
+
end
|
51
|
+
|
52
|
+
p id(blk3 { "abc"})
|
53
|
+
p id(blk3 { 1 })
|
54
|
+
|
55
|
+
def mul(x, y)
|
56
|
+
x * y
|
57
|
+
end
|
58
|
+
|
59
|
+
p mul(30, 40)
|
60
|
+
p mul(30, -40)
|
61
|
+
p mul(-30, 40)
|
62
|
+
p mul(-30, -40)
|
63
|
+
p mul(30.0, 40.0)
|
64
|
+
p mul(30.0, -40.0)
|
65
|
+
p mul(-30.0, 40.0)
|
66
|
+
p mul(-30.0, -40.0)
|
67
|
+
|
68
|
+
def div(x, y)
|
69
|
+
x / y
|
70
|
+
end
|
71
|
+
|
72
|
+
p div(30, 4)
|
73
|
+
p div(30, -4)
|
74
|
+
p div(-30, 4)
|
75
|
+
p div(-30, -4)
|
76
|
+
p div(30.0, 7.0)
|
77
|
+
p div(30.0, -7.0)
|
78
|
+
p div(-30.0, 7.0)
|
79
|
+
p div(-30.0, -7.0)
|
80
|
+
p div(35, 7)
|
81
|
+
p div(35, -7)
|
82
|
+
p div(-35, 7)
|
83
|
+
p div(-35, -7)
|
84
|
+
|
85
|
+
p 1 < 1
|
86
|
+
p 1 > 1
|
87
|
+
p 1 <= 1
|
88
|
+
p 1 >= 1
|
89
|
+
|
90
|
+
p 1 < 2
|
91
|
+
p 1 > 2
|
92
|
+
p 1 <= 2
|
93
|
+
p 1 >= 2
|
94
|
+
|
95
|
+
p 1.0 < 2.0
|
96
|
+
p 1.0 > 2.0
|
97
|
+
p 1.0 <= 2.0
|
98
|
+
p 1.0 >= 2.0
|
99
|
+
|
100
|
+
p 1.0 < 1e-17
|
101
|
+
p 1.0 > 1e-17
|
102
|
+
p 1.0 <= 1e-17
|
103
|
+
p 3.0 > 2.0
|
104
|
+
p :foo
|
105
|
+
p :foo == :foo
|
106
|
+
p :foo == :bar
|
107
|
+
p :foo != :foo
|
108
|
+
p :foo != :bar
|
109
|
+
|
110
|
+
def multi_type_var
|
111
|
+
a = 1
|
112
|
+
p a
|
113
|
+
a = "a"
|
114
|
+
p a
|
115
|
+
a = 1.0
|
116
|
+
p a
|
117
|
+
# p 1.0
|
118
|
+
end
|
119
|
+
|
120
|
+
multi_type_var
|
121
|
+
|
122
|
+
def test_while
|
123
|
+
i = 10
|
124
|
+
j = 0
|
125
|
+
k = 10
|
126
|
+
while i > 0
|
127
|
+
while k > 0
|
128
|
+
j = j + i
|
129
|
+
k = k - 1
|
130
|
+
end
|
131
|
+
i = i - 1
|
132
|
+
k = 10
|
133
|
+
end
|
134
|
+
p j
|
135
|
+
|
136
|
+
i = 10
|
137
|
+
j = 0
|
138
|
+
while i > 0
|
139
|
+
i = i - 1
|
140
|
+
j = j + i
|
141
|
+
end
|
142
|
+
p j
|
143
|
+
end
|
144
|
+
|
145
|
+
test_while
|
146
|
+
|
data/test/classtest.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
class Foo
|
2
|
+
def bar
|
3
|
+
p "Foo#bar"
|
4
|
+
end
|
5
|
+
|
6
|
+
def baz
|
7
|
+
p "Foo#baz"
|
8
|
+
p @a
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@a = 4
|
13
|
+
p "initialize Foo"
|
14
|
+
p self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Bar<Foo
|
19
|
+
def bar
|
20
|
+
p "Bar#bar"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
a = Foo.new
|
25
|
+
p a
|
26
|
+
a.bar
|
27
|
+
a.baz
|
28
|
+
b = Bar.new
|
29
|
+
p b
|
30
|
+
b.bar
|
31
|
+
b.baz
|
32
|
+
|
33
|
+
class Baz
|
34
|
+
def self.alloc
|
35
|
+
p "alloc"
|
36
|
+
end
|
37
|
+
p self
|
38
|
+
end
|
39
|
+
|
40
|
+
p Baz.new
|
41
|
+
p Baz.alloc
|
42
|
+
|
43
|
+
#=end
|
44
|
+
=begin
|
45
|
+
class Asd
|
46
|
+
end
|
47
|
+
|
48
|
+
class <<self
|
49
|
+
end
|
50
|
+
=end
|
data/test/exttest.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# Please Execute
|
2
|
+
# ruby -I lib lib/ytl.rb -r runtime/type.rb test/exttest.rb
|
3
|
+
module YTL
|
4
|
+
class Memory
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module YTLJit
|
9
|
+
module AsmType
|
10
|
+
end
|
11
|
+
|
12
|
+
module Runtime
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def id(x)
|
17
|
+
x
|
18
|
+
end
|
19
|
+
|
20
|
+
c = YTLJit::Runtime::Arena.new
|
21
|
+
a = YTL::Memory.instance
|
22
|
+
# b = 0x1046ce30
|
23
|
+
b = c.address
|
24
|
+
p b
|
25
|
+
p c
|
26
|
+
p YTLJit::AsmType::VALUE
|
27
|
+
p YTLJit::AsmType::RBasic[:klass]
|
28
|
+
p YTLJit::AsmType::RString[:as][:heap][:len]
|
29
|
+
p YTLJit::AsmType::RString[:basic][:flags]
|
30
|
+
p a[b, :machine_word]
|
31
|
+
p a[b, :float]
|
32
|
+
#p a[0x106667b8, YTLJit::AsmType::RString[:as][:heap][:ptr]]
|
33
|
+
p a[b, YTLJit::AsmType::RString[:basic][:flags]]
|
34
|
+
p a[b, YTLJit::AsmType::RString[:as][:heap][:len]]
|
35
|
+
p a[b, :machine_word]
|
data/test/floattest.rb
ADDED
data/test/looptest.rb
ADDED
data/test/tmp.rb
ADDED
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ytl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 0.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Hideki Miura
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-10 00:00:00 +09:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: ytljit
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 0
|
31
|
+
- 4
|
32
|
+
version: 0.0.4
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description:
|
36
|
+
email:
|
37
|
+
executables:
|
38
|
+
- ytl
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- lib/ytl.rb
|
45
|
+
- lib/ytl/accmem.rb
|
46
|
+
- lib/ytl/importobj.rb
|
47
|
+
- runtime/prelude.rb
|
48
|
+
- runtime/type.rb
|
49
|
+
- test/basictest.rb
|
50
|
+
- test/classtest.rb
|
51
|
+
- test/exceptiontest.rb
|
52
|
+
- test/exttest.rb
|
53
|
+
- test/floattest.rb
|
54
|
+
- test/looptest.rb
|
55
|
+
- test/tmp.rb
|
56
|
+
- bin/ytl
|
57
|
+
- README
|
58
|
+
has_rdoc: true
|
59
|
+
homepage:
|
60
|
+
licenses: []
|
61
|
+
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.3.7
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Very tiny subset of YARV to native code translator
|
90
|
+
test_files:
|
91
|
+
- test/basictest.rb
|
92
|
+
- test/classtest.rb
|
93
|
+
- test/exceptiontest.rb
|
94
|
+
- test/exttest.rb
|
95
|
+
- test/floattest.rb
|
96
|
+
- test/looptest.rb
|
97
|
+
- test/tmp.rb
|