asmrb 0.0.2.6.2.0 → 0.0.2.6.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asmrb.rb +182 -183
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79a3be83135d9b7accc927496c57331b8000503f
4
- data.tar.gz: 3552bee762676c442b75cc34c07b4357a1273c2f
3
+ metadata.gz: c1efa63d1755144b58eaf04c1080f10adcbe553d
4
+ data.tar.gz: 5c0d8d57c3a6381621cb5364092b9bed60a41b42
5
5
  SHA512:
6
- metadata.gz: dae555426663211d7f2e90eee12552d7463d3869e30292a9dbea3654313ec669ed8b6097b881af890320740a698037a38cd4e09ba22dbcf5d2c37b82a3051da4
7
- data.tar.gz: ea5b941af24650381ae07ee1f38e8b4e9a546e6693c77f41849fcbaf8f4dada9c61623f23e7568de5bd4c2c744caa41cbdb5080241ce3279f2f7d5cf532eda87
6
+ metadata.gz: 80a48ffe33a30e325e8c1b51fb0d27da0a0253c1cc16c682ac891026addc1eecd394cb87633aebb26034209c8eeb74469431698fceb428d4dbcd9141d6347071
7
+ data.tar.gz: 447314ecf0c95a76529dc7d6c8c58dfcd5cf4eb3d60c7e74fb79d27b6c8b4db897626885c5f8c05b0111198f6f5a0fa053349c8819365fb91816a0dadf80855a
data/lib/asmrb.rb CHANGED
@@ -10,7 +10,7 @@ class Asmrb
10
10
  # Sample with recursion:
11
11
  #
12
12
  # Asmrb.new do
13
- # defn :rec_print # define a function, also a label to jump.
13
+ # fun :rec_print # define a function, also a label to jump.
14
14
  # arg arr # arguments
15
15
  # push 0 # get value to l variable
16
16
  # len arr # get length of arr as array
@@ -36,7 +36,7 @@ class Asmrb
36
36
  # => rec_print [1,2,3]
37
37
  #
38
38
 
39
- attr_reader :variables, :stack, :source, :name, :result, :params,:is_debug
39
+ attr_reader :variables, :stack, :source, :ruby_source, :name, :result, :params, :is_debug, :extension
40
40
  attr_writer :is_debug
41
41
 
42
42
  def initialize &block
@@ -45,7 +45,7 @@ class Asmrb
45
45
  end
46
46
 
47
47
  def compiled?
48
- !@source.nil?
48
+ !@ruby_source.nil?
49
49
  end
50
50
 
51
51
  def invoke *args
@@ -57,13 +57,14 @@ class Asmrb
57
57
  # need parititioning first..
58
58
  partition
59
59
  unless @partitions.empty?
60
- @source = Array.new
60
+ @compile_stack = Array.new
61
+ @ruby_source = Array.new
61
62
  block_labels = @partitions.map &:first
62
63
  @entry_point = @partitions.first.first
63
64
  @partitions.each.with_index do |partition, index|
64
65
  define_block partition, index, block_labels
65
66
  end
66
- @source = @source.join "\n"
67
+ @ruby_source = @ruby_source.join "\n"
67
68
  end
68
69
  end
69
70
 
@@ -73,7 +74,7 @@ class Asmrb
73
74
  end
74
75
  end
75
76
 
76
- def all_opcodes
77
+ def implementation_status
77
78
  puts "[OPCODES] check:".green
78
79
  OPS.map do |k, v|
79
80
  check = OPCODES.include?(k.to_sym) ? :implemented : :not_yet
@@ -89,24 +90,53 @@ class Asmrb
89
90
  puts "-------------------------".green
90
91
  end
91
92
 
93
+ def new_instruction key, block
94
+ @extension[key] = block
95
+ end
96
+
97
+ def extend_program &block
98
+ self.instance_exec &block
99
+ end
100
+
101
+ def patch_line number, block=[]
102
+ @source.insert number, block
103
+ puts "patched at line #{number}: #{block}".light_green
104
+ rebuild_source
105
+ end
106
+
107
+ def remove_line line_number
108
+ puts "remove line #{line_number}: #{@source[line_number]}".light_yellow
109
+ @source.delete_at line_number
110
+ rebuild_source
111
+ end
112
+
113
+ def rebuild_source
114
+ @source.each do |statement|
115
+ build_statement statement.first, statement.last
116
+ end
117
+ end
118
+
92
119
  private
93
120
  def new_scope
94
- @variables = {}
95
- @source = []
96
- @program = []
121
+ @variables = Hash.new
122
+ @source = Array.new
123
+ @ruby_source = Array.new
124
+ @program = Array.new
97
125
  @params = 0
98
126
  @name = "it"
99
- @labels = {}
100
- @stack = []
127
+ @labels = Hash.new
128
+ @stack = Array.new
101
129
  @pc = 0
102
130
  @result = nil
103
131
  @is_debug = false
104
132
  @compile_stack = Array.new
133
+ @extension = Hash.new
105
134
  end
106
135
 
107
136
  def define_block partition, index, block_labels
108
137
  func = partition.first
109
138
  body = partition.last
139
+
110
140
  args = body.first.first.to_sym == :arg ? body.first.last.join(', ') : ""
111
141
 
112
142
  block = Array.new
@@ -135,8 +165,10 @@ class Asmrb
135
165
  if index != block_labels.length-1 && ![:rec, :ret, :exi].include?(body.last[0].to_sym)
136
166
  func = block_labels[index+1]
137
167
  body = @partitions[func].first
168
+
138
169
  #binding.pry
139
- if body.first.to_sym == :arg
170
+
171
+ if body.first == :arg
140
172
  args = "#{body.last.join(', ')}"
141
173
  block << " #{func} #{args}"
142
174
  else
@@ -147,12 +179,9 @@ class Asmrb
147
179
 
148
180
  def finalize_block block
149
181
  block << "end\n"
150
- @source << block.join("\n")
182
+ @ruby_source << block.join("\n")
151
183
 
152
- if @is_debug
153
- puts @source.last.light_yellow
154
- puts "-------------------"
155
- end
184
+ puts "-------------------" if @is_debug
156
185
  end
157
186
 
158
187
  def refvar val
@@ -169,116 +198,128 @@ class Asmrb
169
198
  end
170
199
 
171
200
  OPS = {
172
- "los" => lambda { | args |
173
- args = @variables[args] if @variables.include?(args)
174
- args.reverse.each {|arg| @stack.push arg}
201
+ :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
175
213
  },
176
214
 
177
- "lea" => lambda { | name |
215
+ :lea => lambda { | name |
178
216
  @variables[name] = @stack.pop
179
217
  },
180
218
 
181
- "len" => lambda { | lst |
219
+ :len => lambda { | lst |
182
220
  @stack.push @variables[lst].length
183
221
  },
184
222
 
185
- "cdr" => lambda { | lst |
223
+ :cdr => lambda { | lst |
186
224
  @stack.push @variables[lst].drop 1
187
225
  },
188
226
 
189
- "car" => lambda { | lst |
227
+ :car => lambda { | lst |
190
228
  @stack.push @variables[lst].first
191
229
  },
192
230
 
193
- "map" => lambda { | ops |
231
+ :map => lambda { | ops |
194
232
  eval "@stack.map(&:#{ops})"
195
233
  },
196
234
 
197
- "red" => lambda { | ops |
235
+ :red => lambda { | ops |
198
236
  e = eval "@stack.reduce(:#{ops})"
199
237
  @stack.clear
200
238
  @stack.push e
201
239
  },
202
240
 
203
- "dpl" => lambda {
241
+ :dpl => lambda {
204
242
  @stack.push @stack.last
205
243
  },
206
244
 
207
- "add" => lambda {
208
- @stack.push @stack.pop + @stack.pop
209
- },
245
+ :add => lambda { @stack.push @stack.pop + @stack.pop },
246
+ :sub => lambda { @stack.push @stack.pop - @stack.pop },
247
+ :mul => lambda { @stack.push @stack.pop * @stack.pop },
248
+ :div => lambda { @stack.push @stack.pop / @stack.pop },
210
249
 
211
- "sub" => lambda {
212
- @stack.push @stack.pop - @stack.pop
213
- },
214
-
215
- "mul" => lambda {
216
- @stack.push @stack.pop * @stack.pop
217
- },
218
-
219
- "div" => lambda {
220
- @stack.push @stack.pop / @stack.pop
221
- },
222
-
223
- "icr" => lambda { |dest, incval = 1|
224
- @variables[dest] += incval
225
- },
250
+ :icr => lambda { |dest, val = 1| @variables[dest] += val },
251
+ :dcr => lambda { |dest, val = 1| @variables[dest] -= val },
226
252
 
227
- "dcr" => lambda { |dest, decrval = 1|
228
- @variables[dest] -= decrval
229
- },
230
-
231
- "mov" => lambda { | src , dest |
253
+ :mov => lambda { | src , dest |
232
254
  @variables[dest] =
233
255
  src.is_a?(Symbol) ?
234
256
  @variables[src] : src
235
257
  },
236
258
 
237
- "jnl" => lambda { | name |
259
+ :jnl => lambda { | name |
238
260
  req_args "jnl", 1
239
- @pc = @labels[name] if @stack.pop.nil?
261
+ if @stack.pop.nil?
262
+ @pc = @labels[name]
263
+ new_title "[#{name}]" if @is_debug
264
+ end
240
265
  },
241
266
 
242
- "jz" => lambda { | name |
267
+ :jz => lambda { | name |
243
268
  req_args "jz", 1
244
- @pc = @labels[name] if @stack.pop == 0
269
+ if @stack.pop == 0
270
+ @pc = @labels[name]
271
+ new_title "[#{name}]" if @is_debug
272
+ end
245
273
  },
246
274
 
247
- "jnz" => lambda { | name |
275
+ :jnz => lambda { | name |
248
276
  req_args "jnz", 1
249
- @pc = @labels[name] if @stack.pop != 0
277
+ if @stack.pop != 0
278
+ @pc = @labels[name]
279
+ new_title "[#{name}]" if @is_debug
280
+ end
250
281
  },
251
282
 
252
- "jge" => lambda { |name|
283
+ :jge => lambda { |name|
253
284
  req_args "jge", 2
254
- @pc = @labels[name] if @stack.pop > @stack.pop
285
+ if @stack.pop > @stack.pop
286
+ @pc = @labels[name]
287
+ new_title "[#{name}]" if @is_debug
288
+ end
255
289
  },
256
290
 
257
- "jlt" => lambda { |name|
291
+ :jlt => lambda { |name|
258
292
  req_args "jlt", 2
259
- @pc = @labels[name] if @stack.pop < @stack.pop
293
+ if @stack.pop < @stack.pop
294
+ @pc = @labels[name]
295
+ new_title "[#{name}]" if @is_debug
296
+ end
297
+
260
298
  },
261
299
 
262
- "jeq" => lambda { |name|
300
+ :jeq => lambda { |name|
263
301
  req_args "jeq", 2
264
- @pc = @labels[name] if @stack.pop == @stack.pop
302
+ if @stack.pop == @stack.pop
303
+ @pc = @labels[name]
304
+ new_title "[#{name}]" if @is_debug
305
+ end
265
306
  },
266
307
 
267
- "jmp" => lambda { |name|
308
+ :jmp => lambda { |name|
268
309
  @pc = @labels[name]
269
310
  new_title "[#{name}]" if @is_debug
270
311
  },
271
312
 
272
- "pop" => lambda {|val|
313
+ :pop => lambda {|val|
273
314
  @stack.pop
274
315
  },
275
316
 
276
- "psh" => lambda {|src|
317
+ :psh => lambda {|src|
277
318
  @stack.push(
278
319
  src.is_a?(Symbol) ? @variables[src] : src )
279
320
  },
280
321
 
281
- "arg" => lambda { |*args|
322
+ :arg => lambda { |*args|
282
323
  if @stack.length < args.length
283
324
  raise Exception.new "require (#{args.join(', ')}) on stack: #{@stack}"
284
325
  else
@@ -288,16 +329,16 @@ class Asmrb
288
329
  end
289
330
  },
290
331
 
291
- "req" => lambda {|amount|
332
+ :req => lambda {|amount|
292
333
  raise Exception.new "require #{amount} arg." if @stack.length < amount
293
334
  },
294
335
 
295
- "dbg" => lambda {
336
+ :dbg => lambda {
296
337
  puts "#{@stack} > #{@program[@pc][0]}".light_green
297
338
  binding.pry if @is_debug
298
339
  },
299
340
 
300
- "inv" => lambda { |obj, f|
341
+ :inv => lambda { |obj, f|
301
342
  args = Array.new
302
343
  @stack.each { args << @stack.pop } if @stack.length > 0
303
344
  if args.length > 0
@@ -307,7 +348,7 @@ class Asmrb
307
348
  end
308
349
  },
309
350
 
310
- "cal" => lambda {|fname|
351
+ :cal => lambda {|fname|
311
352
  _method = method fname
312
353
  if _method && _method.parameters.length > 0
313
354
  args = Array.new
@@ -320,15 +361,16 @@ class Asmrb
320
361
  end
321
362
  @stack.push invoke if !invoke.nil?
322
363
  },
323
- "rec" => lambda {
364
+ :rec => lambda {
324
365
  @pc = -1
366
+ new_title "[#{@name}]" if @is_debug
325
367
  },
326
368
 
327
- "ret" => lambda {
369
+ :ret => lambda {
328
370
  @pc = @program.length-1
329
371
  },
330
372
 
331
- "exi" => lambda {
373
+ :exi => lambda {
332
374
  exit
333
375
  }
334
376
  }
@@ -338,24 +380,28 @@ class Asmrb
338
380
  puts "#{@label[blo]}: #{blo}".purple if @is_debug
339
381
  end
340
382
 
341
- def method_missing(name, *args)
383
+ def method_missing name, *args
384
+ build_statement name, *args
385
+ end
386
+
387
+ def build_statement name, *args
342
388
  # save source
343
389
  @source << [name, args]
344
390
 
345
- # :name => "name"
346
- sname = name.to_s.gsub "_", ""
391
+ # :_name => :name
392
+ name = name.to_s.gsub("_", "").to_sym
347
393
 
348
- if OPS.keys.include? sname
349
- @program << [sname, args]
394
+ if OPS.keys.include? name
395
+ @program << [name, args]
350
396
  # get parameter amount:
351
- @params = args.length if sname == "arg"
397
+ @params = args.length if name == :arg
352
398
  else
353
- case sname
399
+ case name
354
400
 
355
- when "blo"
401
+ when :blo
356
402
  create_label args.first
357
403
 
358
- when "fun"
404
+ when :fun
359
405
  @name = args.first
360
406
  create_label @name
361
407
 
@@ -365,26 +411,24 @@ class Asmrb
365
411
  end
366
412
  end
367
413
 
368
- def load_program &block
369
- self.instance_exec &block
370
- end
371
-
372
414
  def execute debug=false
373
415
  new_line if debug
374
416
  puts "#{@stack} > #{@name}".yellow if debug
375
417
  begin
376
418
  @pc = 0
419
+ @variables = Hash.new
377
420
  until @pc == @program.length
378
- # get instruction:
421
+
379
422
  instr = @program[@pc]
423
+
380
424
  puts "#{@pc}: #{instr[0]} #{instr[1].join " "}".light_green if debug
381
- # execute proc: arg , proc
425
+
382
426
  self.instance_exec *instr[1], &OPS[instr[0]]
427
+
383
428
  @pc += 1
384
429
  end
385
- #binding.pry
386
430
  @result = @stack.last
387
- clear
431
+ @stack.clear
388
432
  rescue Exception => e
389
433
  debug e, instr
390
434
  end
@@ -392,20 +436,6 @@ class Asmrb
392
436
  @result
393
437
  end
394
438
 
395
- def fast_execute *args
396
- arguments args
397
- @pc = 0
398
- until @pc == @program.length
399
- # execute proc:
400
- self.instance_exec *@program[@pc].last,
401
- &OPS[@program[@pc].first]
402
- @pc += 1
403
- end
404
- @result = @stack.last
405
- clear
406
- @result
407
- end
408
-
409
439
  def new_title title
410
440
  puts "\n::#{title}"
411
441
  end
@@ -427,6 +457,7 @@ class Asmrb
427
457
  (scope_begin..scope_end).each do | i |
428
458
  instr = @program[i]
429
459
  color = i != @pc ? :light_green : :magenta
460
+ binding.pry
430
461
  puts "#{i}: #{instr[0]} #{instr[1]}".colorize color
431
462
  end
432
463
  unless instr.nil?
@@ -438,6 +469,7 @@ class Asmrb
438
469
  end
439
470
 
440
471
  def ops_info name
472
+ return if OPS[name].nil?
441
473
  parameters = Array.new
442
474
  OPS[name].parameters.each do |pair|
443
475
  parameters << pair.last
@@ -451,14 +483,8 @@ class Asmrb
451
483
  end
452
484
  end
453
485
 
454
- def clear
455
- @pc = 0
456
- @variables = { }
457
- @stack = []
458
- end
459
-
460
486
  def assemble &block
461
- load_program &block
487
+ extend_program &block
462
488
  eval "$#{@name} = self.clone"
463
489
  eval "$#{@name}"
464
490
  end
@@ -509,7 +535,16 @@ class Asmrb
509
535
  end
510
536
 
511
537
  def patched_arg label
512
- "#{label} #{@labels_arg[label].join(', ') if @labels_arg.include?(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
513
548
  end
514
549
 
515
550
  def opcode_operator op
@@ -527,7 +562,12 @@ class Asmrb
527
562
  nil
528
563
  end
529
564
 
565
+ def fetch statement
566
+ @compile_stack << statement
567
+ end
568
+
530
569
  OPCODES = {
570
+ :slp => lambda {|amount| "sleep #{amount}"},
531
571
  :dbg => lambda {"binding.pry"},
532
572
  :req => lambda {|_|},
533
573
 
@@ -535,26 +575,26 @@ class Asmrb
535
575
  :red => lambda {|op| "#{@compile_stack}.reduce :#{op}" },
536
576
 
537
577
  :pop => lambda { @compile_stack.pop },
538
- :icr => lambda {|arg| @compile_stack << "#{arg} = #{arg} + 1" },
539
- :dcr => lambda {|arg| @compile_stack << "#{arg} = #{arg} - 1" },
578
+ :icr => lambda {|arg| fetch "#{arg} = #{arg} + 1" },
579
+ :dcr => lambda {|arg| fetch "#{arg} = #{arg} - 1" },
540
580
 
541
581
  :mov => lambda {|src, dest| "#{dest} = #{src}" },
542
- :dpl => lambda { @compile_stack << @compile_stack.last },
582
+ :dpl => lambda { fetch @compile_stack.last },
543
583
 
544
- :car => lambda {|arg| @compile_stack << "#{arg}.first" },
545
- :cdr => lambda {|arg| @compile_stack << "#{arg}.drop(1)" },
546
- :len => lambda {|arg| @compile_stack << "#{arg}.length" },
584
+ :car => lambda {|arg| fetch "#{arg}.first" },
585
+ :cdr => lambda {|arg| fetch "#{arg}.drop(1)" },
586
+ :len => lambda {|arg| fetch "#{arg}.length" },
547
587
 
548
588
  :arg => lambda {|*args|
549
589
  # ignore it
550
590
  },
551
591
  :los => lambda {|*args|
552
- args.reverse.each{|arg| @compile_stack << arg}
592
+ args.reverse.each{|arg| fetch arg}
553
593
  nil
554
594
  },
555
595
  :psh => lambda {|arg|
556
596
  arg = "\"#{arg}\"" if arg.class == String
557
- @compile_stack << arg
597
+ fetch arg
558
598
  nil
559
599
  },
560
600
  :lea => lambda {|var|
@@ -596,10 +636,10 @@ class Asmrb
596
636
  :inv => lambda {|obj, f|
597
637
  begin
598
638
  if method(f).parameters.length == 0
599
- @compile_stack << "#{obj}.#{f}"
639
+ fetch "#{obj}.#{f}"
600
640
  else
601
641
  args = method(f).parameters.collect{@compile_stack.pop}
602
- @compile_stack << "#{obj}.#{f} #{args.join(', ')}"
642
+ fetch "#{obj}.#{f} #{args.join(', ')}"
603
643
  end
604
644
  nil
605
645
  rescue Exception => e
@@ -609,80 +649,39 @@ class Asmrb
609
649
  }
610
650
  end
611
651
 
612
- # demo for testing
613
- # @x = Asmrb.new do
614
- # fun :play
615
- # arg :toy
616
- # psh :toy
617
- # cal :puts
618
-
619
- # blo :after_print
620
- # psh :@times
621
- # jnl :init_timer
622
-
623
- # blo :append
624
- # inv :@times, :to_s
625
- # psh "X"
626
- # add
627
- # cal :puts
628
-
629
- # blo :count
630
- # psh :@times
631
- # psh 1
632
- # add
633
- # lea :@times
634
- # psh :@times
635
- # psh 10
636
- # jeq :final
637
- # psh "__"
638
- # rec
639
-
640
- # blo :final
641
- # psh "__"
642
- # cal :puts
643
- # inv :@times, :to_s
644
- # psh "Final result = "
645
- # add
646
- # cal :puts
647
- # exi
648
-
649
- # blo :init_timer
650
- # psh 0
651
- # lea :@times
652
- # jmp :append
653
- # end
654
-
655
- # @x.is_debug = false
656
- # test = @x.to_ruby
657
- # puts test.light_green
658
- # eval test
659
- # play "I'm The Trung, here we go:"
652
+ def asmrb &block
653
+ Asmrb.new &block
654
+ end
660
655
 
661
656
  # # applying: argumented block ( lambda )
662
657
  # # should be "inline block" technique also,
663
658
  # # to improve performance and local variable sharing.
664
- # @f = Asmrb.new do
659
+ # @y = asmrb do
665
660
  # fun :factorial
666
661
  # arg :acc, :n
662
+ # los :acc, :n
667
663
  # los :n, 1
668
- # jlt :final
664
+ # jlt :result
669
665
 
670
- # blo :cont
666
+ # blo :else_block
671
667
  # arg :acc, :n
672
- # los :n, :acc
668
+ # los :acc, :n
673
669
  # mul
674
670
  # los :n, 1
675
671
  # sub
676
- # rec
677
-
678
- # blo :final
672
+ # rec
673
+
674
+ # blo :result
679
675
  # arg :acc
680
676
  # psh :acc
681
- # cal :puts
682
- # exi # no return yet, because return doesn't mean anything inside a block. we can't escape.
677
+ # ret
683
678
  # end
684
679
 
685
- # source = @f.to_ruby
686
- # puts source
687
- # eval source
688
- # factorial 1, 3
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}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asmrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2.6.2.0
4
+ version: 0.0.2.6.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Trung