asmrb 0.0.2.6.2.0 → 0.0.2.6.2.1

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