asmrb 0.0.2.6.2.1 → 0.0.2.6.2.2

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.
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