asmrb 0.0.2.6.2.1 → 0.0.2.6.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +143 -0
  3. data/bin/asmrb +30 -0
  4. data/lib/asmrb.rb +120 -82
  5. data/lib/ast.rb +3 -0
  6. data/lib/llvm_sample.rb +109 -0
  7. metadata +58 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c1efa63d1755144b58eaf04c1080f10adcbe553d
4
- data.tar.gz: 5c0d8d57c3a6381621cb5364092b9bed60a41b42
3
+ metadata.gz: d060fb46ed0c1da76426e94cc0f8a315cb5b5464
4
+ data.tar.gz: 2dd5ec988a198e5ef3b432dd1a1edc27d671f79e
5
5
  SHA512:
6
- metadata.gz: 80a48ffe33a30e325e8c1b51fb0d27da0a0253c1cc16c682ac891026addc1eecd394cb87633aebb26034209c8eeb74469431698fceb428d4dbcd9141d6347071
7
- data.tar.gz: 447314ecf0c95a76529dc7d6c8c58dfcd5cf4eb3d60c7e74fb79d27b6c8b4db897626885c5f8c05b0111198f6f5a0fa053349c8819365fb91816a0dadf80855a
6
+ metadata.gz: 6985a71aa49990685e5d6af7023ff03cac9439bea40ff1c2427921eac17880437a8d151926f21e68f1f7ddef65927ba383f2629446f077d898652aded36f8dd8
7
+ data.tar.gz: a4d2eaa1eb1b368b41577bd2ed192cf478a612dfb08f045006ce58d94c21c7e71e369bccaab0fc12aad71596ad58deac54c26be55fae4a630e9c38e47d1f6398
@@ -0,0 +1,143 @@
1
+ asmrb
2
+ =======
3
+
4
+ I. Intro
5
+
6
+ Asmrb is my intend over making a high-level assembly language.
7
+ Which shorten your horizonal source, better flow and readability.
8
+
9
+ And to solve my question about how recursion loop through assembly
10
+ by just jumping from label to label.
11
+
12
+ Have fun !
13
+
14
+ Just a prototype, play around if you know Ruby.
15
+ Get the Gem: https://rubygems.org/gems/asmrb
16
+
17
+ II. Install
18
+
19
+ \* asmrb is at very early state of experiment,
20
+ so all required gems would be pretty light-weight
21
+ and just for debugging and colorful printing.
22
+
23
+ gem install asmrb
24
+
25
+ III. Usage
26
+
27
+ Let's create one as below:
28
+
29
+ a = Asmrb.new do
30
+ fun :rec_print # define a function, also label to jump.
31
+ arg arr # arguments
32
+ psh 0
33
+ len arr # get length of arr as array
34
+ jge :print # then jump to :print block
35
+ ret # else, jump to :exit block
36
+ blo :print # start of :print
37
+ car arr # get out first element of arr
38
+ cal :puts # call ruby's puts
39
+ cdr arr # get rest of arr Array to @stack
40
+ rec # jump back to :rec_print ( or start of this _fntion )
41
+ end
42
+
43
+ toggle the debug mode to see steps:
44
+
45
+ a.is_debug = true
46
+
47
+ invoke it with right arugument type:
48
+
49
+ a.invoke [1, 2]
50
+
51
+ convert it to ruby code:
52
+
53
+ a.to_ruby
54
+
55
+ Asmrb can run "infinite recursion" without being overflow,
56
+ by storing value with its own stack.
57
+
58
+ Look at "rake test" for more samples.
59
+
60
+ \* Execute source file:
61
+
62
+ To execute a source file like `demo.arb`:
63
+
64
+ asmrb demo.arb
65
+
66
+ VI. Features
67
+
68
+ * I actually created asmrb to see how it change the coding style
69
+ while still remain all high-level ruby functions. There're early
70
+ plans on making LLVM underhood to improve overall performance,
71
+ or just compiling down to ruby for maximum compatiability and
72
+ go on with all ruby implementations.
73
+
74
+ \* currently implemented:
75
+
76
+ Note: to see all implemented operators, run:
77
+ Asmrb.new.all_ops
78
+
79
+ \* operations:
80
+
81
+ all ops follow the rule:
82
+
83
+ psh 2
84
+ psh 1
85
+ add # push (1 + 2) to stack
86
+
87
+
88
+ to remove top-most element off stack:
89
+
90
+ psh 1
91
+ pop
92
+
93
+ same to above, when pushed values:
94
+
95
+ sub # 1 - 2
96
+ add # 1 + 2
97
+ mul # 1 * 2
98
+ div # 1 / 2
99
+ icr a # a = a + 1
100
+ dcr a # a = a - 1
101
+ dpl # duplicate top-most value on stack
102
+
103
+ \* array:
104
+
105
+ car arr # get first element of array
106
+ cdr arr # get rest element of array
107
+ len arr # get length of array
108
+ los arr # load all array elements on stack
109
+ los :a # load all elements in :a variable
110
+
111
+ \* jump:
112
+
113
+ blo :name # create a label/block
114
+
115
+ jlt :label # jump if a < b
116
+ jge :label # jump if a > b
117
+ jeq :label # jump if a = b
118
+ jnz :label # jump if not zero
119
+ jmp :label # jump to certain labeled immediately
120
+ jnl :label # jump if nil
121
+
122
+ \* function define:
123
+
124
+ fun :function # define function name and also a label to jump.
125
+ arg a,b # function parameters binded to a and b.
126
+ req 3 # function require 3 arguments.
127
+ rec # to recursively call function again.
128
+ lea :a # load top-most value to variable a
129
+
130
+ \* high-level:
131
+
132
+ mov 1, :a # there is still this, but it will soon be removed.
133
+
134
+
135
+ red :+ # reduce current stack frame by :+ operator
136
+ map :o # map as usual to current stack
137
+ cal :puts # calling ruby function
138
+
139
+ inv :a, :f # invoke function "f" of object "a" with n "args"
140
+
141
+ dbg # debug by pry at local instruction
142
+ ret # exit and return top-most stack value
143
+ exi # force exit
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ dir = File.expand_path(File.dirname(__FILE__))
3
+ require dir + '/../lib/asmrb.rb'
4
+
5
+ require 'oyster'
6
+ spec = Oyster.spec do
7
+ name "asmrb -- Lisp to ruby transformation"#, v. #{Heist::VERSION}"
8
+ author 'The Trung <deulamco@mail.com>'
9
+
10
+ synopsis <<-EOS
11
+ asmrb -i [OPTIONS]
12
+ asmrb FILE_NAME [OPTIONS]
13
+ EOS
14
+
15
+ flag :interactive, :desc =>
16
+ 'Start an interactive Scheme session'
17
+ end
18
+
19
+
20
+ begin
21
+ options = spec.parse
22
+
23
+ if options[:interactive] or options[:unclaimed].empty?
24
+ puts "Not implemented yet"
25
+ else
26
+ Asmrb.new.eval_file File.expand_path(options[:unclaimed].first)
27
+ end
28
+
29
+ rescue Oyster::HelpRendered
30
+ end
@@ -44,6 +44,24 @@ class Asmrb
44
44
  assemble &block unless block.nil?
45
45
  end
46
46
 
47
+ def eval_file path
48
+ source = File.read path
49
+ eval_source source
50
+ end
51
+
52
+ def eval_source source
53
+ new_scope
54
+ puts source.light_yellow
55
+ eval <<-CODE
56
+ assemble do
57
+ #{source}
58
+ end
59
+ CODE
60
+ compiled = to_ruby
61
+ puts compiled.magenta
62
+ eval compiled
63
+ end
64
+
47
65
  def compiled?
48
66
  !@ruby_source.nil?
49
67
  end
@@ -57,7 +75,6 @@ class Asmrb
57
75
  # need parititioning first..
58
76
  partition
59
77
  unless @partitions.empty?
60
- @compile_stack = Array.new
61
78
  @ruby_source = Array.new
62
79
  block_labels = @partitions.map &:first
63
80
  @entry_point = @partitions.first.first
@@ -74,7 +91,7 @@ class Asmrb
74
91
  end
75
92
  end
76
93
 
77
- def implementation_status
94
+ def all_opcodes
78
95
  puts "[OPCODES] check:".green
79
96
  OPS.map do |k, v|
80
97
  check = OPCODES.include?(k.to_sym) ? :implemented : :not_yet
@@ -136,7 +153,6 @@ class Asmrb
136
153
  def define_block partition, index, block_labels
137
154
  func = partition.first
138
155
  body = partition.last
139
-
140
156
  args = body.first.first.to_sym == :arg ? body.first.last.join(', ') : ""
141
157
 
142
158
  block = Array.new
@@ -165,10 +181,8 @@ class Asmrb
165
181
  if index != block_labels.length-1 && ![:rec, :ret, :exi].include?(body.last[0].to_sym)
166
182
  func = block_labels[index+1]
167
183
  body = @partitions[func].first
168
-
169
184
  #binding.pry
170
-
171
- if body.first == :arg
185
+ if body.first.to_sym == :arg
172
186
  args = "#{body.last.join(', ')}"
173
187
  block << " #{func} #{args}"
174
188
  else
@@ -181,7 +195,10 @@ class Asmrb
181
195
  block << "end\n"
182
196
  @ruby_source << block.join("\n")
183
197
 
184
- puts "-------------------" if @is_debug
198
+ if @is_debug
199
+ puts @source.last.join(" ").light_yellow
200
+ puts "-------------------"
201
+ end
185
202
  end
186
203
 
187
204
  def refvar val
@@ -199,17 +216,9 @@ class Asmrb
199
216
 
200
217
  OPS = {
201
218
  :slp => lambda { |amount| sleep amount},
202
- :los => lambda { | *args |
203
- args = args.collect do |arg|
204
- if @variables.include? arg
205
- @variables[arg]
206
- else
207
- arg
208
- end
209
- end
210
- args.reverse.each do |arg|
211
- @stack.push arg
212
- end
219
+ :los => lambda { | args |
220
+ args = @variables[args] if @variables.include?(args)
221
+ args.reverse.each {|arg| @stack.push arg}
213
222
  },
214
223
 
215
224
  :lea => lambda { | name |
@@ -258,51 +267,32 @@ class Asmrb
258
267
 
259
268
  :jnl => lambda { | name |
260
269
  req_args "jnl", 1
261
- if @stack.pop.nil?
262
- @pc = @labels[name]
263
- new_title "[#{name}]" if @is_debug
264
- end
270
+ @pc = @labels[name] if @stack.pop.nil?
265
271
  },
266
272
 
267
273
  :jz => lambda { | name |
268
274
  req_args "jz", 1
269
- if @stack.pop == 0
270
- @pc = @labels[name]
271
- new_title "[#{name}]" if @is_debug
272
- end
275
+ @pc = @labels[name] if @stack.pop == 0
273
276
  },
274
277
 
275
278
  :jnz => lambda { | name |
276
279
  req_args "jnz", 1
277
- if @stack.pop != 0
278
- @pc = @labels[name]
279
- new_title "[#{name}]" if @is_debug
280
- end
280
+ @pc = @labels[name] if @stack.pop != 0
281
281
  },
282
282
 
283
283
  :jge => lambda { |name|
284
284
  req_args "jge", 2
285
- if @stack.pop > @stack.pop
286
- @pc = @labels[name]
287
- new_title "[#{name}]" if @is_debug
288
- end
285
+ @pc = @labels[name] if @stack.pop > @stack.pop
289
286
  },
290
287
 
291
288
  :jlt => lambda { |name|
292
289
  req_args "jlt", 2
293
- if @stack.pop < @stack.pop
294
- @pc = @labels[name]
295
- new_title "[#{name}]" if @is_debug
296
- end
297
-
290
+ @pc = @labels[name] if @stack.pop < @stack.pop
298
291
  },
299
292
 
300
293
  :jeq => lambda { |name|
301
294
  req_args "jeq", 2
302
- if @stack.pop == @stack.pop
303
- @pc = @labels[name]
304
- new_title "[#{name}]" if @is_debug
305
- end
295
+ @pc = @labels[name] if @stack.pop == @stack.pop
306
296
  },
307
297
 
308
298
  :jmp => lambda { |name|
@@ -363,7 +353,6 @@ class Asmrb
363
353
  },
364
354
  :rec => lambda {
365
355
  @pc = -1
366
- new_title "[#{@name}]" if @is_debug
367
356
  },
368
357
 
369
358
  :ret => lambda {
@@ -416,19 +405,17 @@ class Asmrb
416
405
  puts "#{@stack} > #{@name}".yellow if debug
417
406
  begin
418
407
  @pc = 0
419
- @variables = Hash.new
420
408
  until @pc == @program.length
421
-
409
+ # get instruction:
422
410
  instr = @program[@pc]
423
-
424
411
  puts "#{@pc}: #{instr[0]} #{instr[1].join " "}".light_green if debug
425
-
412
+ # execute proc: arg , proc
426
413
  self.instance_exec *instr[1], &OPS[instr[0]]
427
-
428
414
  @pc += 1
429
415
  end
416
+ #binding.pry
430
417
  @result = @stack.last
431
- @stack.clear
418
+ clear
432
419
  rescue Exception => e
433
420
  debug e, instr
434
421
  end
@@ -436,6 +423,20 @@ class Asmrb
436
423
  @result
437
424
  end
438
425
 
426
+ def fast_execute *args
427
+ arguments args
428
+ @pc = 0
429
+ until @pc == @program.length
430
+ # execute proc:
431
+ self.instance_exec *@program[@pc].last,
432
+ &OPS[@program[@pc].first]
433
+ @pc += 1
434
+ end
435
+ @result = @stack.last
436
+ clear
437
+ @result
438
+ end
439
+
439
440
  def new_title title
440
441
  puts "\n::#{title}"
441
442
  end
@@ -457,7 +458,6 @@ class Asmrb
457
458
  (scope_begin..scope_end).each do | i |
458
459
  instr = @program[i]
459
460
  color = i != @pc ? :light_green : :magenta
460
- binding.pry
461
461
  puts "#{i}: #{instr[0]} #{instr[1]}".colorize color
462
462
  end
463
463
  unless instr.nil?
@@ -483,6 +483,12 @@ class Asmrb
483
483
  end
484
484
  end
485
485
 
486
+ def clear
487
+ @pc = 0
488
+ @variables = { }
489
+ @stack = []
490
+ end
491
+
486
492
  def assemble &block
487
493
  extend_program &block
488
494
  eval "$#{@name} = self.clone"
@@ -535,16 +541,7 @@ class Asmrb
535
541
  end
536
542
 
537
543
  def patched_arg label
538
- patched = ""
539
- if @labels_arg.include? label
540
- patched = "#{label}(#{@labels_arg[label].join(', ')})"
541
- else
542
- patched = "#{label}"
543
- end
544
- if !@partitions[label].nil? && @partitions[label].last.first == :ret
545
- patched = "return " + patched
546
- end
547
- patched
544
+ "#{label} #{@labels_arg[label].join(', ') if @labels_arg.include?(label)}"
548
545
  end
549
546
 
550
547
  def opcode_operator op
@@ -567,7 +564,7 @@ class Asmrb
567
564
  end
568
565
 
569
566
  OPCODES = {
570
- :slp => lambda {|amount| "sleep #{amount}"},
567
+ :sleep => lambda {|amount| "sleep #{amount}"},
571
568
  :dbg => lambda {"binding.pry"},
572
569
  :req => lambda {|_|},
573
570
 
@@ -649,39 +646,80 @@ class Asmrb
649
646
  }
650
647
  end
651
648
 
652
- def asmrb &block
653
- Asmrb.new &block
654
- end
649
+ # demo for testing
650
+ # @x = Asmrb.new do
651
+ # fun :play
652
+ # arg :toy
653
+ # psh :toy
654
+ # cal :puts
655
+
656
+ # blo :after_print
657
+ # psh :@times
658
+ # jnl :init_timer
659
+
660
+ # blo :append
661
+ # inv :@times, :to_s
662
+ # psh "X"
663
+ # add
664
+ # cal :puts
665
+
666
+ # blo :count
667
+ # psh :@times
668
+ # psh 1
669
+ # add
670
+ # lea :@times
671
+ # psh :@times
672
+ # psh 10
673
+ # jeq :final
674
+ # psh "__"
675
+ # rec
676
+
677
+ # blo :final
678
+ # psh "__"
679
+ # cal :puts
680
+ # inv :@times, :to_s
681
+ # psh "Final result = "
682
+ # add
683
+ # cal :puts
684
+ # exi
685
+
686
+ # blo :init_timer
687
+ # psh 0
688
+ # lea :@times
689
+ # jmp :append
690
+ # end
691
+
692
+ # @x.is_debug = false
693
+ # test = @x.to_ruby
694
+ # puts test.light_green
695
+ # eval test
696
+ # play "I'm The Trung, here we go:"
655
697
 
656
698
  # # applying: argumented block ( lambda )
657
699
  # # should be "inline block" technique also,
658
700
  # # to improve performance and local variable sharing.
659
- # @y = asmrb do
701
+ # @f = Asmrb.new do
660
702
  # fun :factorial
661
703
  # arg :acc, :n
662
- # los :acc, :n
663
704
  # los :n, 1
664
- # jlt :result
705
+ # jlt :final
665
706
 
666
- # blo :else_block
707
+ # blo :cont
667
708
  # arg :acc, :n
668
- # los :acc, :n
709
+ # los :n, :acc
669
710
  # mul
670
711
  # los :n, 1
671
712
  # sub
672
- # rec
673
-
674
- # blo :result
713
+ # rec
714
+
715
+ # blo :final
675
716
  # arg :acc
676
717
  # psh :acc
677
- # ret
718
+ # cal :puts
719
+ # exi # no return yet, because return doesn't mean anything inside a block. we can't escape.
678
720
  # end
679
721
 
680
- # @y.is_debug = true
681
- # puts @y.invoke 1, 3
682
- # #@y.all_opcodes
683
- # test = @y.to_ruby
684
- # puts test
685
- # eval test
686
- # @y = factorial 1, 1000
687
- # puts "Start test: #{@y}"
722
+ # source = @f.to_ruby
723
+ # puts source
724
+ # eval source
725
+ # factorial 1, 3
@@ -0,0 +1,3 @@
1
+ module AST
2
+ # should include words that has interpretation and compilation.
3
+ end
@@ -0,0 +1,109 @@
1
+ require 'llvm/core'
2
+ require 'llvm/execution_engine'
3
+ require 'llvm/transforms/scalar'
4
+ require "benchmark"
5
+ require 'asmrb'
6
+
7
+ # run this with any argument to get a speed comparison between llvm and different ruby implementations
8
+
9
+ # Start the "engine" before driving
10
+ LLVM.init_jit
11
+
12
+ # modules hold functions and variables
13
+ mod = LLVM::Module.new("Factorial")
14
+
15
+ mod.functions.add("fac", [LLVM::Int], LLVM::Int) do |fac, n|
16
+ n.name = "n"
17
+ entry = fac.basic_blocks.append("entry")
18
+ recur = fac.basic_blocks.append("recur")
19
+ result = fac.basic_blocks.append("result")
20
+ n_fac_n_1 = nil # predeclare within function's scope
21
+
22
+ entry.build do |b|
23
+ test = b.icmp(:eq, n, LLVM::Int(1), "test")
24
+ b.cond(test, result, recur)
25
+ end
26
+
27
+ recur.build do |b|
28
+ n_1 = b.sub(n, LLVM::Int(1), "n-1")
29
+ fac_n_1 = b.call(fac, n_1, "fac(n-1)")
30
+ n_fac_n_1 = b.mul(n, fac_n_1, "n*fac(n-1)")
31
+ b.br(result)
32
+ end
33
+
34
+ result.build do |b|
35
+ fac = b.phi(LLVM::Int,
36
+ { entry => LLVM::Int(1),
37
+ recur => n_fac_n_1 },
38
+ "fac")
39
+ b.ret(fac)
40
+ end
41
+ end
42
+
43
+ mod.verify
44
+ mod.dump
45
+
46
+ engine = LLVM::JITCompiler.new(mod)
47
+
48
+ def rec_factorial(n)
49
+ if n <= 1
50
+ 1
51
+ else
52
+ n * rec_factorial(n - 1);
53
+ end
54
+ end
55
+ def iter_factorial(n)
56
+ nn = n
57
+ i = n - 1
58
+ while(i > 1) do
59
+ nn *= i
60
+ i -= 1
61
+ end
62
+ return nn;
63
+ end
64
+ def array_factorial(n)
65
+ (1..n).inject(:*)
66
+ end
67
+
68
+
69
+ Asm.new do
70
+ defn :factorial
71
+ arg acc, n
72
+ push 1
73
+ push n
74
+ cmp
75
+ jge :recursion
76
+ jmp :exit
77
+
78
+ label :recursion
79
+ push acc
80
+ push n
81
+ mul
82
+ push 1
83
+ push n
84
+ sub
85
+ jmp :factorial
86
+ label :exit
87
+ push acc
88
+ end
89
+
90
+
91
+ if( ARGV.length == 0 )
92
+ puts "Single run with 42 = " + engine.run_function(mod.functions["fac"], 42).to_i.to_s
93
+ exit
94
+ end
95
+ puts "Times show factorial execution times in milliseconds.".light_green
96
+ puts "Both for llvm and ruby iterative and recusive algorithms".light_green
97
+ puts ["Num" , "llvm rec","recursive" ,"iterative","array iter", "asmrb"].collect{|u|u.ljust(11)}.join
98
+ res = [ 1, 5 , 20 , 50 , 100 , 200 , 500 , 1000 , 2000 , 5000, 8710 ].each do |i|
99
+ res = [ ]
100
+ res << Benchmark.realtime {engine.run_function(mod.functions["fac"], i)}
101
+ res << Benchmark.realtime {rec_factorial(i)}
102
+ res << Benchmark.realtime {iter_factorial(i) }
103
+ res << Benchmark.realtime {array_factorial(i) }
104
+ res << Benchmark.realtime {$factorial.invoke(1,i)}
105
+ res = [i] + res.collect {|u| ((u*1000)).round(4) }
106
+ res = res.collect {|z| z.to_s.ljust(8)}
107
+ next if i < 10
108
+ puts res.join(" ")
109
+ end
metadata CHANGED
@@ -1,29 +1,80 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asmrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2.6.2.1
4
+ version: 0.0.2.6.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Trung
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-14 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2015-05-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oyster
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: colorize
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
13
55
  description: create a assembly-like toy language in ruby DSL. It can then compile
14
- into ruby code.
56
+ into ruby code. * note that I have stopped this gem development, since I saw no
57
+ potential to make it further. Have fun playing around with it!
15
58
  email: deulamco@gmail.com
16
- executables: []
59
+ executables:
60
+ - asmrb
17
61
  extensions: []
18
- extra_rdoc_files: []
62
+ extra_rdoc_files:
63
+ - README.md
19
64
  files:
65
+ - README.md
66
+ - bin/asmrb
20
67
  - lib/asmrb.rb
68
+ - lib/ast.rb
69
+ - lib/llvm_sample.rb
21
70
  homepage: http://github.com/thetrung/asmrb.git
22
71
  licenses:
23
72
  - MIT
24
73
  metadata: {}
25
74
  post_install_message:
26
- rdoc_options: []
75
+ rdoc_options:
76
+ - "--main"
77
+ - README.md
27
78
  require_paths:
28
79
  - lib
29
80
  required_ruby_version: !ruby/object:Gem::Requirement