ytl 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ytl/macro.rb ADDED
@@ -0,0 +1,419 @@
1
+ module YTLJit
2
+ module VM
3
+ class ToRubyContext
4
+ def initialize
5
+ @ret_code = [""]
6
+ @jmp_tab = {}
7
+ @defined_method = {}
8
+ @work_prefix = []
9
+ end
10
+
11
+ attr :ret_code
12
+ attr :jmp_tab
13
+ attr :defined_method
14
+ attr :work_prefix
15
+ end
16
+
17
+ module Node
18
+ class BaseNode
19
+ def to_ruby(context)
20
+ context
21
+ end
22
+ end
23
+
24
+ class DummyNode
25
+ def to_ruby(context)
26
+ context
27
+ end
28
+ end
29
+
30
+ class TopNode
31
+ end
32
+
33
+ class MethodTopNode
34
+ def to_ruby(context)
35
+ # context.ret_code.last << "{ #{@name} "
36
+ context.ret_code.last << "{ "
37
+ context.ret_code.push ""
38
+ context = @body.to_ruby(context)
39
+ args = context.ret_code.pop
40
+ pre = context.work_prefix.join('_')
41
+ if args != "" then
42
+ context.ret_code.last << "|#{args}|"
43
+ end
44
+ context.ret_code.last << "#{pre}state = 0\n"
45
+ context.ret_code.last << "#{pre}value = nil\n"
46
+ context.ret_code.last << "evalstr = []\n"
47
+ context.ret_code.last << "[while true\n"
48
+ # context.ret_code.last << "p #{pre}state\n"
49
+ context.ret_code.last << "case #{pre}state\n"
50
+ context.ret_code.last << "when 0\n"
51
+ context = @body.body.to_ruby(context)
52
+ context.ret_code.last << "end\n"
53
+ context.ret_code.last << "end, evalstr]\n"
54
+ context.ret_code.last << "}\n"
55
+ context
56
+ end
57
+ end
58
+
59
+ class BlockTopNode
60
+ def to_ruby(context)
61
+ context.ret_code.last << "{ "
62
+ context.ret_code.push ""
63
+ context = @body.to_ruby(context)
64
+ args = context.ret_code.pop
65
+ if args != "" then
66
+ context.ret_code.last << "| #{args} | \n"
67
+ end
68
+ pre = context.work_prefix.join('_')
69
+ context.ret_code.last << "#{pre}state = 0\n"
70
+ context.ret_code.last << "#{pre}value = nil\n"
71
+ context.ret_code.last << "while true\n"
72
+ # context.ret_code.last << "p #{pre}state\n"
73
+ context.ret_code.last << "case #{pre}state\n"
74
+ context.ret_code.last << "when 0\n"
75
+ context = @body.body.to_ruby(context)
76
+ context.ret_code.last << "end\n"
77
+ context.ret_code.last << "end\n"
78
+ context.ret_code.last << "}\n"
79
+ context
80
+ end
81
+ end
82
+
83
+ class ClassTopNode
84
+ end
85
+
86
+ class TopTopNode
87
+ end
88
+
89
+ class LocalFrameInfoNode
90
+ def to_ruby(context)
91
+ argpos = 0
92
+ visitsys = false
93
+ @frame_layout.each do |vinf|
94
+ if vinf.is_a?(LocalVarNode) then
95
+ argpos = argpos + 1
96
+ if argpos > 3 and visitsys then
97
+ context = vinf.to_ruby(context)
98
+ context.ret_code.last << ", "
99
+ end
100
+ else
101
+ visitsys = true
102
+ argpos = 0
103
+ end
104
+ end
105
+ context.ret_code.last.chop!
106
+ context.ret_code.last.chop!
107
+
108
+ context
109
+ end
110
+ end
111
+
112
+ class LocalVarNode
113
+ def to_ruby(context)
114
+ case kind
115
+ when :arg, :local_var
116
+ context.ret_code.last << "_#{@name.to_s}"
117
+
118
+ when :rest_arg
119
+ context.ret_code.last << "*_#{@name.to_s}"
120
+
121
+ else
122
+ p kind
123
+
124
+ end
125
+
126
+ context
127
+ end
128
+ end
129
+
130
+ class SystemValueNode
131
+ end
132
+
133
+ class GuardNode
134
+ end
135
+
136
+ class MethodEndNode
137
+ end
138
+
139
+ class BlockEndNode
140
+ end
141
+
142
+ class ClassEndNode
143
+ end
144
+
145
+ class SetResultNode
146
+ def to_ruby(context)
147
+ context.ret_code.last << "break "
148
+ context = @value_node.to_ruby(context)
149
+ context.ret_code.last << "\n"
150
+ @body.to_ruby(context)
151
+ end
152
+ end
153
+
154
+ class PhiNode
155
+ def to_ruby(context)
156
+ pre = context.work_prefix.join('_')
157
+ context.ret_code.last << "#{pre}value"
158
+ context
159
+ end
160
+ end
161
+
162
+ class LocalLabel
163
+ def to_ruby(context)
164
+ context.ret_code.last << "when #{context.jmp_tab[self]}\n"
165
+ @body.to_ruby(context)
166
+ end
167
+ end
168
+
169
+ class BranchCommonNode
170
+ def to_ruby_common(context, unlessp)
171
+ nf = false
172
+ if context.jmp_tab[@jmp_to_node] == nil then
173
+ context.jmp_tab[@jmp_to_node] = context.jmp_tab.size + 1
174
+ nf = true
175
+ end
176
+ jlab = context.jmp_tab[@jmp_to_node]
177
+
178
+ blab = context.jmp_tab.size + 1
179
+ context.jmp_tab[@body] = blab
180
+
181
+ context.ret_code.push ""
182
+ context = @cond.to_ruby(context)
183
+ cc = context.ret_code.pop
184
+ pre = context.work_prefix.join('_')
185
+ context.ret_code.last << "if #{cc} then\n"
186
+ if unlessp then
187
+ context.ret_code.last << "#{pre}state = #{blab}\n"
188
+ context.ret_code.last << "else\n"
189
+ context.ret_code.last << "#{pre}state = #{jlab}\n"
190
+ else
191
+ context.ret_code.last << "#{pre}state = #{jlab}\n"
192
+ context.ret_code.last << "else\n"
193
+ context.ret_code.last << "#{pre}state = #{blab}\n"
194
+ end
195
+ context.ret_code.last << "end\n"
196
+
197
+ if nf then
198
+ context = @jmp_to_node.to_ruby(context)
199
+ end
200
+
201
+ context.ret_code.last << "when #{context.jmp_tab[@body]}\n"
202
+ context = @body.to_ruby(context)
203
+ end
204
+ end
205
+
206
+ class BranchIfNode
207
+ def to_ruby(context)
208
+ to_ruby_common(context, false)
209
+ end
210
+ end
211
+
212
+ class BranchUnlessNode
213
+ def to_ruby(context)
214
+ to_ruby_common(context, true)
215
+ end
216
+ end
217
+
218
+ class JumpNode
219
+ def to_ruby(context)
220
+ nf = false
221
+ if context.jmp_tab[@jmp_to_node] == nil then
222
+ context.jmp_tab[@jmp_to_node] = context.jmp_tab.size + 1
223
+ nf = true
224
+ end
225
+ pre = context.work_prefix.join('_')
226
+ nestat = context.jmp_tab[@jmp_to_node]
227
+ context.ret_code.last << "#{pre}state = #{nestat}\n"
228
+ valnode = @jmp_to_node.come_from[self]
229
+ if valnode then
230
+ context.ret_code.push ""
231
+ context = valnode.to_ruby(context)
232
+ val = context.ret_code.pop
233
+ context.ret_code.last << "#{pre}value = #{val}\n"
234
+ end
235
+ if nf then
236
+ @jmp_to_node.to_ruby(context)
237
+ else
238
+ context
239
+ end
240
+ end
241
+ end
242
+
243
+ class LetNode
244
+ end
245
+
246
+ class LiteralNode
247
+ def to_ruby(context)
248
+ context.ret_code.last << get_constant_value[0].inspect
249
+ context
250
+ end
251
+ end
252
+
253
+ class ClassValueNode
254
+ end
255
+
256
+ class SpecialObjectNode
257
+ end
258
+
259
+ class YieldNode
260
+ def to_ruby(context)
261
+ arg = @parent.arguments
262
+ context.ret_code.last << "yield"
263
+ context.ret_code.last << "("
264
+ arg[3..-1].each do |ae|
265
+ context = ae.to_ruby(context)
266
+ context.ret_code.last << ", "
267
+ end
268
+ context.ret_code.last.chop!
269
+ context.ret_code.last.chop!
270
+ context.ret_code.last << ")\n"
271
+ context
272
+ end
273
+ end
274
+
275
+ class FixArgCApiNode
276
+ API_TAB = {
277
+ "rb_str_append" => "+",
278
+ "rb_obj_as_string" => "to_s",
279
+ }
280
+ def to_ruby(context)
281
+ arg = @parent.arguments
282
+ context.ret_code.last << "("
283
+ context = arg[0].to_ruby(context)
284
+ context.ret_code.last << "."
285
+ context.ret_code.last << API_TAB[@name]
286
+ if arg[1] then
287
+ context.ret_code.last << "("
288
+ arg[1..-1].each do |ae|
289
+ context = ae.to_ruby(context)
290
+ context.ret_code.last << ", "
291
+ end
292
+ context.ret_code.last.chop!
293
+ context.ret_code.last.chop!
294
+ context.ret_code.last << ")"
295
+ end
296
+ context.ret_code.last << ")\n"
297
+ context
298
+ end
299
+ end
300
+
301
+ class MethodSelectNode
302
+ def to_ruby(context)
303
+ arg = @parent.arguments
304
+ context.ret_code.last << "("
305
+ if @parent.is_fcall or @parent.is_vcall then
306
+ context.ret_code.last << @name.to_s
307
+ else
308
+ context = arg[2].to_ruby(context)
309
+ context.ret_code.last << ".#{@name}"
310
+ end
311
+ if arg[3] then
312
+ context.ret_code.last << "("
313
+ arg[3..-1].each do |ae|
314
+ context = ae.to_ruby(context)
315
+ context.ret_code.last << ", "
316
+ end
317
+ context.ret_code.last.chop!
318
+ context.ret_code.last.chop!
319
+ context.ret_code.last << ")"
320
+ end
321
+ if arg[1].is_a?(BlockTopNode) then
322
+ context.ret_code.last << " "
323
+ context.work_prefix.push "bl"
324
+ context = arg[1].to_ruby(context)
325
+ context.work_prefix.pop
326
+ end
327
+ context.ret_code.last << ")\n"
328
+ context
329
+ end
330
+ end
331
+
332
+ class VariableRefCommonNode
333
+ end
334
+
335
+ class LocalVarRefCommonNode
336
+ end
337
+
338
+ class LocalVarRefNode
339
+ def to_ruby(context)
340
+ cfi = @current_frame_info
341
+ off = cfi.real_offset(@offset)
342
+ lv = cfi.frame_layout[off]
343
+ context.ret_code.last << " _#{lv.name.to_s} "
344
+ context
345
+ end
346
+ end
347
+
348
+ class SelfRefNode
349
+ def to_ruby(context)
350
+ context.ret_code.last << " self "
351
+ context
352
+ end
353
+ end
354
+
355
+ class LocalAssignNode
356
+ def to_ruby(context)
357
+ cfi = @current_frame_info
358
+ off = cfi.real_offset(@offset)
359
+ lv = cfi.frame_layout[off]
360
+ context.ret_code.last << "_#{lv.name.to_s} = "
361
+ context = @val.to_ruby(context)
362
+ context.ret_code.last << "\n"
363
+ @body.to_ruby(context)
364
+ end
365
+ end
366
+
367
+ class InstanceVarRefCommonNode
368
+ end
369
+
370
+ class InstanceVarRefNode
371
+ def to_ruby(context)
372
+ context.ret_code.last << " #{@name.to_s} "
373
+ context
374
+ end
375
+ end
376
+
377
+ class InstanceVarAssignNode
378
+ def to_ruby(context)
379
+ context.ret_code.last << "#{@name.to_s} = "
380
+ context = @val.to_ruby(context)
381
+ context.ret_code.last << "\n"
382
+ context
383
+ end
384
+ end
385
+
386
+ class ConstantRefNode
387
+ def to_ruby(context)
388
+ context.ret_code.last << @name.to_s
389
+ context
390
+ end
391
+ end
392
+
393
+ class ConstantAssignNode
394
+ def to_ruby(context)
395
+ context.ret_code.last << "#{@name.to_s} = "
396
+ context = @val.to_ruby(context)
397
+ context.ret_code.last << "\n"
398
+ context
399
+ end
400
+ end
401
+
402
+ class SendNode
403
+ def to_ruby(context)
404
+ context = @func.to_ruby(context)
405
+ @body.to_ruby(context)
406
+ end
407
+ end
408
+
409
+ class SendEvalNode
410
+ def to_ruby(context)
411
+ context.ret_code.last << "evalstr <<"
412
+ context = @arguments[3].to_ruby(context)
413
+ context.ret_code.last << "\n"
414
+ @body.to_ruby(context)
415
+ end
416
+ end
417
+ end
418
+ end
419
+ end
data/lib/ytl.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'ytljit'
2
2
  require 'ytl/accmem.rb'
3
+ require 'ytl/macro.rb'
3
4
  require 'ytl/importobj.rb'
4
5
  require 'pp'
5
6
  require 'optparse'
@@ -111,6 +112,7 @@ module YTL
111
112
  c_context.current_method_signature.push sig
112
113
  c_context.options = options
113
114
  c_context = tnode.compile(c_context)
115
+ tnode.make_frame_struct_tab
114
116
 
115
117
  if fn = options[:write_node_after_ti] then
116
118
  File.open(fn, "w") do |fp|
data/runtime/prelude.rb CHANGED
@@ -1,6 +1,19 @@
1
1
  # runtime library written in ytl
2
2
  <<-'EOS'
3
3
  #
4
+ def attr(*x)
5
+ x.each do |ele|
6
+ eval "def #{ele}; @#{ele} ; end"
7
+ end
8
+ end
9
+
10
+ def attr_accessor(*x)
11
+ x.each do |ele|
12
+ eval "def #{ele}; @#{ele} ; end\n"
13
+ eval "def #{ele}=(val); @#{ele} = val ; end"
14
+ end
15
+ end
16
+
4
17
  class Array
5
18
  def each
6
19
  i = 0
@@ -14,6 +27,26 @@ class Array
14
27
  end
15
28
  end
16
29
 
30
+ class Range
31
+ def each
32
+ i = self.first
33
+ e = self.last
34
+ if self.exclude_end? then
35
+ while i < e
36
+ yield i
37
+ i = i + 1
38
+ end
39
+ else
40
+ while i <= e
41
+ yield i
42
+ i = i + 1
43
+ end
44
+ end
45
+
46
+ e
47
+ end
48
+ end
49
+
17
50
  class Fixnum
18
51
  def times
19
52
  i = 0
@@ -24,6 +57,25 @@ class Fixnum
24
57
 
25
58
  self
26
59
  end
60
+
61
+ def step(max, st)
62
+ i = self
63
+ while i < max
64
+ yield i
65
+ i = i + st
66
+ end
67
+
68
+ self
69
+ end
70
+
71
+ def **(n)
72
+ a = 1
73
+ while n > 0
74
+ a = a * self
75
+ n = n - 1
76
+ end
77
+ a
78
+ end
27
79
  end
28
80
 
29
81
  EOS
data/test/basictest.rb CHANGED
@@ -14,6 +14,16 @@ def array
14
14
  end
15
15
  p array
16
16
 
17
+ def array2
18
+ b = 3
19
+ a = [3, b, 6]
20
+ p a
21
+ a[1] = 1
22
+ p a
23
+ [1, 2, 2 * 3][0] + [1 * 2, 2 * 4, 3][1]
24
+ end
25
+ p array2
26
+
17
27
  def fib(x)
18
28
  if x < 2 then
19
29
  1
@@ -144,3 +154,26 @@ end
144
154
 
145
155
  test_while
146
156
 
157
+ i = 5
158
+ a = i..7
159
+ p a.first
160
+ p a.last
161
+ p a
162
+ p Range.new(i, 2, false)
163
+ p 1...3
164
+ =begin
165
+ def id(a, *b)
166
+ p a
167
+ end
168
+ id(*[1, 2, 3])
169
+
170
+ =begin
171
+ for i in 1..2
172
+ p i
173
+ end
174
+
175
+ for i in 1...2
176
+ p i
177
+ end
178
+
179
+ =end
data/test/classtest.rb CHANGED
@@ -16,6 +16,8 @@ class Foo
16
16
  end
17
17
 
18
18
  class Bar<Foo
19
+ p self
20
+ p "foobarbaz"
19
21
  def bar
20
22
  p "Bar#bar"
21
23
  end
data/test/ivtest.rb ADDED
@@ -0,0 +1,19 @@
1
+ DAYS_PER_YEAR = 365.24
2
+
3
+ class Foo
4
+ def initialize(x)
5
+ @a = x * DAYS_PER_YEAR
6
+ @b = 10.0
7
+ end
8
+
9
+ attr_accessor :a, :b
10
+
11
+ def mov(bodies)
12
+ # bodies[0].a += @a
13
+ p bodies[0].a
14
+ end
15
+ end
16
+
17
+ foo = Foo.new(1.4)
18
+ foo.mov([Foo.new(2.8)])
19
+ p [Foo.new(2.8)][0]
data/test/looptest.rb CHANGED
@@ -6,3 +6,18 @@
6
6
  end
7
7
  end
8
8
  end
9
+
10
+ a = 5
11
+ for i in a...10
12
+ for j in a..7
13
+ p i
14
+ end
15
+ end
16
+
17
+ p a..10
18
+ for i in a..10
19
+ # for j in a..20
20
+ p i
21
+ # end
22
+ end
23
+
data/test/macrotest.rb ADDED
@@ -0,0 +1,26 @@
1
+ def myattr(*x)
2
+ str = ""
3
+ x.each do |e|
4
+ eval "def #{e}; @#{e}; end\n"
5
+ end
6
+ end
7
+
8
+ myattr :foo, :bar
9
+
10
+ # Can't psss this test yet
11
+ =begin
12
+
13
+ def fact(x)
14
+ if x == 0 then
15
+ 1
16
+ else
17
+ x * fact(x - 1)
18
+ end
19
+ end
20
+
21
+ def fact_inline(x)
22
+ eval fact(x)
23
+ end
24
+
25
+ p fact_inline(5)
26
+ =end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Hideki Miura
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-17 00:00:00 +09:00
17
+ date: 2011-01-26 00:00:00 +09:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -28,8 +28,8 @@ dependencies:
28
28
  segments:
29
29
  - 0
30
30
  - 0
31
- - 5
32
- version: 0.0.5
31
+ - 6
32
+ version: 0.0.6
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
35
  description:
@@ -44,6 +44,7 @@ files:
44
44
  - lib/ytl.rb
45
45
  - lib/ytl/accmem.rb
46
46
  - lib/ytl/importobj.rb
47
+ - lib/ytl/macro.rb
47
48
  - runtime/prelude.rb
48
49
  - runtime/type.rb
49
50
  - test/basictest.rb
@@ -51,7 +52,9 @@ files:
51
52
  - test/exceptiontest.rb
52
53
  - test/exttest.rb
53
54
  - test/floattest.rb
55
+ - test/ivtest.rb
54
56
  - test/looptest.rb
57
+ - test/macrotest.rb
55
58
  - test/tmp.rb
56
59
  - bin/ytl
57
60
  - README
@@ -93,5 +96,7 @@ test_files:
93
96
  - test/exceptiontest.rb
94
97
  - test/exttest.rb
95
98
  - test/floattest.rb
99
+ - test/ivtest.rb
96
100
  - test/looptest.rb
101
+ - test/macrotest.rb
97
102
  - test/tmp.rb