rubylabs 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.3
1
+ 0.9.0
data/lib/bitlab.rb CHANGED
@@ -590,7 +590,6 @@ module BitLab
590
590
  Canvas.move(tree.drawing.rseg, dx, dy)
591
591
  move_tree(tree.right, dx, dy)
592
592
  end
593
- Canvas.sync
594
593
  end
595
594
 
596
595
  def draw_root(node, left, right)
@@ -598,8 +597,10 @@ module BitLab
598
597
  x = (left.coords.x + right.coords.x) / 2
599
598
  y = left.coords.y - 2 * @@unit
600
599
  draw_node(node, x, y)
601
- node.drawing.lseg = Canvas.line(x, y, left.coords.x, left.coords.y).lower
602
- node.drawing.rseg = Canvas.line(x, y, right.coords.x, right.coords.y).lower
600
+ node.drawing.lseg = Canvas::Line.new(x, y, left.coords.x, left.coords.y)
601
+ node.drawing.rseg = Canvas::Line.new(x, y, right.coords.x, right.coords.y)
602
+ node.drawing.lseg.lower
603
+ node.drawing.rseg.lower
603
604
  # [left, right].each do |desc|
604
605
  # desc.drawing.ftext.delete
605
606
  # desc.drawing.ftext = nil
@@ -610,9 +611,9 @@ module BitLab
610
611
  return nil unless @@drawing
611
612
  opts = @@drawing.options
612
613
  d = @@unit
613
- circ = Canvas.circle( x, y, d / 2, :fill => opts[:nodefill] )
614
- text = Canvas.text( node.char, x, y, :anchor => :center )
615
- ftext = Canvas.text( node.freq.to_s, x, y-d, {:font => opts[:freqfont], :anchor => :center} )
614
+ circ = Canvas::Circle.new( x, y, d / 2, :fill => opts[:nodefill] )
615
+ text = Canvas::Text.new( node.char, x, y, :anchor => :center )
616
+ ftext = Canvas::Text.new( node.freq.to_s, x, y-d, {:font => opts[:freqfont].name, :anchor => :center} )
616
617
  node.drawing = NodeView.new(circ, text, ftext, nil, nil)
617
618
  node.coords = NodeCoords.new(x, y, x, 0, x, 0)
618
619
  end
@@ -626,17 +627,23 @@ module BitLab
626
627
  Canvas.init(options[:width], options[:height], "BitLab")
627
628
  @@drawing = QueueView.new(pq, options)
628
629
  options[:nodefill] = "lightgray"
629
- options[:freqfont] = Canvas.font(:family => 'Helvetica', :size => 10)
630
+ options[:freqfont] = Canvas::Font.new('freqfont', :family => 'Helvetica', :size => 10)
630
631
  pq.on_canvas = true
631
632
  x = options[:qx]
632
633
  pq.each_with_index do |node, i|
633
634
  draw_node(node, x, options[:qy])
634
635
  x += 3 * @@unit
635
636
  end
636
- Canvas.sync
637
637
  return true
638
638
  end
639
639
 
640
+ # def test_setup
641
+ # vf = read_frequencies(:hvfreq)
642
+ # pq = init_queue(vf)
643
+ # view_queue(pq)
644
+ # return pq
645
+ # end
646
+
640
647
  @@unit = 24 # pixels per "tree unit"
641
648
 
642
649
  @@queueViewOptions = {
@@ -732,7 +739,7 @@ class PriorityQueue
732
739
  # end
733
740
  return res
734
741
  end
735
-
742
+
736
743
  end
737
744
 
738
745
  class Fixnum
@@ -768,17 +775,5 @@ class Fixnum
768
775
 
769
776
  end
770
777
 
771
- =begin
772
- TODO delete this
773
- =end
774
-
775
- def test_view
776
- vf = read_frequencies(:hafreq)
777
- pq = init_queue(vf)
778
- view_queue(pq)
779
- Canvas.sync
780
- return pq
781
- end
782
-
783
778
 
784
779
 
data/lib/hashlab.rb CHANGED
@@ -14,7 +14,7 @@ module RubyLabs
14
14
 
15
15
  module HashLab
16
16
 
17
- TableView = Struct.new(:table, :nrows)
17
+ TableView = Struct.new(:cells, :buckets, :nrows, :options)
18
18
 
19
19
  =begin rdoc
20
20
 
@@ -131,6 +131,7 @@ Ruby magic defines three new methods just for the new object:
131
131
  @@hash_functions = [:h0, :h1, :hr]
132
132
 
133
133
  attr_reader :table
134
+ attr_accessor :drawing
134
135
 
135
136
  def initialize(n, f = :hr)
136
137
  raise "HashTable: hash function must be one of #{@@hash_functions.inspect}" unless @@hash_functions.include?(f)
@@ -155,6 +156,16 @@ Ruby magic defines three new methods just for the new object:
155
156
  i = send(@hash, s, @table.length)
156
157
  @table[i] = Array.new if @table[i].nil?
157
158
  @table[i] << s
159
+ if @drawing
160
+ options = @drawing.options
161
+ if @drawing.buckets[i]
162
+ @drawing.buckets[i].update( @table[i].join(", ") )
163
+ else
164
+ y0 = options[:tableY] + i * (options[:cellHeight] + options[:cellYSpace])
165
+ @drawing.buckets[i] = Canvas::Text.new(@table[i], options[:textX], y0, {:font => :bucketfont})
166
+ @drawing.cells[i].fill = 'white'
167
+ end
168
+ end
158
169
  return i
159
170
  end
160
171
 
@@ -239,28 +250,31 @@ Ruby magic defines three new methods just for the new object:
239
250
  end
240
251
 
241
252
  =begin rdoc
242
- Initialize the canvas with a drawing of an hash table +t+ (a table is
243
- just an array augmented with a hash method)
253
+ Initialize the canvas with a drawing of an hash table +t+
244
254
  =end
245
255
 
246
256
  def view_table(t, userOptions = {} )
247
257
  options = @@tableOptions.merge(userOptions)
248
- Canvas.init(300, 500, "HashLab")
258
+ Canvas.init(400, 500, "HashLab")
259
+ Canvas::Font.new('bucketfont', :family => 'Helvetica', :size => 11)
249
260
  tbl = t.table
250
261
  x0 = options[:tableX]
251
262
  x1 = x0 + options[:cellWidth]
252
- # if nil, color = gray, else color = white and draw text
253
- # todo -- arrow
254
- # todo -- save text, update with call to insert
263
+ cells = []
264
+ buckets = []
255
265
  nrows = min(tbl.size, options[:maxRows])
256
266
  nrows.times do |i|
257
267
  y0 = options[:tableY] + i * (options[:cellHeight] + options[:cellYSpace])
258
268
  y1 = y0 + options[:cellHeight]
259
- Canvas.rectangle(x0, y0, x1, y1, :fill => options[:cellColor])
260
- # Canvas.text(tbl[i].inspect, textx, y0)
269
+ cells << Canvas::Rectangle.new(x0, y0, x1, y1)
270
+ if tbl[i]
271
+ buckets << Canvas::Text.new(tbl[i].join(", "), options[:textX], y0, {:font => :bucketfont})
272
+ cells[i].fill = 'white'
273
+ else
274
+ cells[i].fill = options[:cellColor]
275
+ end
261
276
  end
262
- @@drawing = TableView.new(t, nrows)
263
- Canvas.sync
277
+ t.drawing = TableView.new(cells, buckets, nrows, options)
264
278
  return true
265
279
  end
266
280
 
data/lib/marslab.rb CHANGED
@@ -34,6 +34,8 @@ to assemble a program call MARS.assemble(foo).
34
34
  module RubyLabs
35
35
 
36
36
  module MARSLab
37
+
38
+ MARSView = Struct.new(:cells, :palettes, :options)
37
39
 
38
40
  class MARSRuntimeException < StandardError
39
41
  end
@@ -243,7 +245,7 @@ module MARSLab
243
245
  end
244
246
  end
245
247
 
246
- # Major ambiguity here -- what does it mean for an word A to be "less than"
248
+ # Major ambiguity here -- what does it mean for a word A to be "less than"
247
249
  # word B? First assumption, don't compare opcodes. Second, we're just going
248
250
  # to implement one-field comparisons of B fields. Otherwise for full-word operands
249
251
  # we'd need to do a lexicographic compare of A and B fields of both operands, skipping
@@ -394,7 +396,7 @@ module MARSLab
394
396
 
395
397
  To help visualize the operation of a program the class keeps a history of memory
396
398
  references made by each thread. A call to next automatically records the program counter
397
- value, but a semantic routine can also all log(x) to append location x to a history.
399
+ value, but a semantic routine can also call log(x) to append location x to a history.
398
400
  Call history to get the history vectors for all threads.
399
401
  =end
400
402
 
@@ -612,91 +614,7 @@ module MARSLab
612
614
  end
613
615
 
614
616
  end # MiniMARS
615
-
616
- =begin rdoc
617
- Make a window to display the state of the machine
618
- =end
619
-
620
- class Draw
621
-
622
- @@cellSize = 8
623
- @@cellRows = 32
624
- @@cellCols = 128
625
- @@padding = @@cellSize
626
- @@traceSize = 10
627
- @@cellColor = '#CCCCCC'
628
-
629
- def paintCell(i, color)
630
- @cells[i]['fill'] = color
631
- end
632
-
633
- def fillCanvas(mem)
634
- @cells = []
635
- mem.each_with_index do |val, i|
636
- x = (i % @@cellCols) * @@cellSize + @@padding
637
- y = (i / @@cellCols) * @@cellSize + @@padding
638
- @cells << TkcRectangle.new( @canvas, x, y, x+@@cellSize, y+@@cellSize, :outline => "#888888", :fill => @@cellColor )
639
- end
640
- end
641
-
642
- def reset
643
- @cells.each do |cell|
644
- cell['fill'] = @@cellColor
645
- end
646
- end
647
-
648
- # Make a range of colors starting from first and going to last in n steps.
649
- # First and last are expected to be 3-tuples of integer RGB values. The
650
- # result is an array that starts with first, has n-1 intermediate colors,
651
- # and ends with last. Example:
652
- # makePalette( [255,0,0], [0,0,0], 10)
653
- # makes 11 colors starting with red and ending with black.
654
-
655
- def makePalette(first, last, n)
656
- d = Array.new(3)
657
- 3.times { |i| d[i] = (first[i] - last[i]) / n }
658
- a = [first]
659
- (n-1).times do |i|
660
- a << a.last.clone
661
- 3.times { |j| a.last[j] -= d[j] }
662
- end
663
- a << last
664
- a.map { |c| sprintf("#%02X%02X%02X",c[0],c[1],c[2]) }
665
- end
666
-
667
- def updateCells(pc)
668
- id = pc.id
669
- a = pc.history[pc.current[:thread]]
670
- d = @palette[id].length - a.length
671
- a.each_with_index do |x, i|
672
- paintCell(x, @palette[id][i+d])
673
- end
674
- end
675
-
676
- def initialize(parent)
677
- content = TkFrame.new(parent)
678
- @canvas = TkCanvas.new(content, :borderwidth => 1,
679
- :width => @@cellCols*@@cellSize+@@padding, :height => @@cellRows*@@cellSize+@@padding)
680
- fillCanvas(Array.new(4096))
681
-
682
- @canvas.grid :column => 0, :row => 0, :columnspan => 4, :padx => 10, :pady => 10
683
- content.pack :pady => 20
684
-
685
- # initialize palettes with blends from a dingy color to gray, then
686
- # add a bright color as the last item
687
-
688
- @palette = [
689
- makePalette( [204,204,204], [204,100,100], @@traceSize ),
690
- makePalette( [204,204,204], [100,100,204], @@traceSize ),
691
- makePalette( [204,204,204], [100,204,100], @@traceSize ),
692
- ]
693
- @palette[0] << "#FF0000"
694
- @palette[1] << "#0000FF"
695
- @palette[2] << "#00FF00"
696
- end
697
-
698
- end # class Draw
699
-
617
+
700
618
 
701
619
  =begin rdoc
702
620
  The MARS module is a package that has the methods used to assemble, load, and execute
@@ -890,7 +808,7 @@ module MARSLab
890
808
  printf("%04d: %s\n", pc.current[:addr], instr) if @@params[:tracing]
891
809
 
892
810
  if @@drawing
893
- @@drawing.updateCells(pc)
811
+ MARS.updateCells(pc)
894
812
  sleep(@@params[:pace])
895
813
  end
896
814
 
@@ -967,63 +885,89 @@ module MARSLab
967
885
  only when no programs are loaded)
968
886
  =end
969
887
 
970
- def MARS.set_option(key, val)
971
- if ! @@entries.empty?
972
- puts "Options can be set only when no programs are loaded (call 'reset' to clear programs)"
973
- return false
974
- end
975
- case key
976
- when :memSize
977
- if val.class != Fixnum || val < 1024 || val > 16536
978
- puts ":memSize must be an integer between 1024 and 16536"
979
- return nil
980
- end
981
- when :maxRounds, :buffer
982
- if val.class != Fixnum
983
- puts ":#{key} must be an integer"
984
- return nil
888
+ def MARS.set_option(key, val)
889
+ if ! @@entries.empty?
890
+ puts "Options can be set only when no programs are loaded (call 'reset' to clear programs)"
891
+ return false
985
892
  end
986
- when :pace
987
- if val.class != Float
988
- puts ":#{key} must be an floating point number (e.g. 0.05)"
989
- return nil
990
- end
991
- when :tracing
992
- if ! (val.class == TrueClass || val.class == FalseClass)
993
- puts ":tracing must be true or false"
893
+ case key
894
+ when :memSize
895
+ if val.class != Fixnum || val < 1024 || val > 16536
896
+ puts ":memSize must be an integer between 1024 and 16536"
897
+ return nil
898
+ end
899
+ when :maxRounds, :buffer
900
+ if val.class != Fixnum
901
+ puts ":#{key} must be an integer"
902
+ return nil
903
+ end
904
+ when :pace
905
+ if val.class != Float
906
+ puts ":#{key} must be an floating point number (e.g. 0.05)"
907
+ return nil
908
+ end
909
+ when :tracing
910
+ if ! (val.class == TrueClass || val.class == FalseClass)
911
+ puts ":tracing must be true or false"
912
+ return nil
913
+ end
914
+ else
915
+ puts "Unknown option: #{key}"
994
916
  return nil
995
917
  end
996
- else
997
- puts "Unknown option: #{key}"
998
- return nil
918
+ @@params[key] = val
999
919
  end
1000
- @@params[key] = val
1001
- end
1002
920
 
1003
921
  =begin rdoc
1004
922
  view() -- open a visual view of the machine state
923
+
924
+ initialize palettes with blends from a dingy color to gray, then
925
+ add a bright color as the last item
1005
926
  =end
1006
927
 
1007
- def MARS.view
1008
- require 'tk'
1009
-
1010
- if ! defined? @@tkroot
1011
- @@tkroot = TkRoot.new { title "MARS" }
1012
- end
1013
-
1014
- if @@drawing == nil
1015
- @@drawing = Draw.new(@tkroot)
1016
- @@threads = []
1017
- @@threads << Thread.new() do
1018
- Tk.mainloop
1019
- end
1020
- end
928
+ def MARS.view(userOptions = {} )
929
+
930
+ options = @@viewOptions.merge(userOptions)
931
+
932
+ cellsize = options[:cellSize]
933
+ padding = options[:padding]
934
+
935
+ width = options[:cellCols] * cellsize + 2*padding
936
+ height = options[:cellRows] * cellsize + 2*padding
937
+ Canvas.init(width, height, "MARSLab")
938
+
939
+ cells = []
940
+ for i in 0...@@displayMemSize
941
+ x = (i % options[:cellCols]) * cellsize + padding
942
+ y = (i / options[:cellCols]) * cellsize + padding
943
+ cells << Canvas::Rectangle.new( x, y, x+cellsize, y+cellsize, :outline => "#888888", :fill => options[:cellColor] )
944
+ end
945
+
946
+ palettes = [
947
+ Canvas.palette( [204,204,204], [204,100,100], options[:traceSize] ),
948
+ Canvas.palette( [204,204,204], [100,100,204], options[:traceSize] ),
949
+ Canvas.palette( [204,204,204], [100,204,100], options[:traceSize] ),
950
+ ]
951
+ palettes[0] << "#FF0000"
952
+ palettes[1] << "#0000FF"
953
+ palettes[2] << "#00FF00"
954
+
955
+ @@drawing = MARSView.new(cells, palettes, options)
956
+ return true
957
+
1021
958
  end
1022
959
 
1023
960
  def MARS.close_view
1024
- @@threads[0].kill
1025
- @@tkroot.destroy
1026
- @@drawing = nil
961
+ Canvas.close
962
+ end
963
+
964
+ def MARS.updateCells(pc)
965
+ id = pc.id
966
+ a = pc.history[pc.current[:thread]]
967
+ d = @@drawing.palettes[id].length - a.length
968
+ a.each_with_index do |x, i|
969
+ @@drawing.cells[x].fill = @@drawing.palettes[id][i+d]
970
+ end
1027
971
  end
1028
972
 
1029
973
  =begin rdoc
@@ -1052,7 +996,12 @@ module MARSLab
1052
996
  @@mem = Memory.new(@@params[:memSize])
1053
997
  @@entries = Array.new
1054
998
  Warrior.reset
1055
- @@drawing.reset if @@drawing
999
+ if @@drawing
1000
+ @@drawing.cells.each do |x|
1001
+ x.fill = @@drawing.options[:cellColor]
1002
+ end
1003
+ end
1004
+ return true
1056
1005
  end
1057
1006
 
1058
1007
  =begin rdoc
@@ -1100,7 +1049,7 @@ module MARSLab
1100
1049
  end
1101
1050
  return nil
1102
1051
  end
1103
-
1052
+
1104
1053
  end # class MARS
1105
1054
 
1106
1055
 
@@ -1136,6 +1085,15 @@ module MARSLab
1136
1085
  :pace => 0.01,
1137
1086
  }
1138
1087
 
1088
+ @@viewOptions = {
1089
+ :cellSize => 8,
1090
+ :cellRows => 32,
1091
+ :cellCols => 128,
1092
+ :padding => 20,
1093
+ :traceSize => 10,
1094
+ :cellColor => '#DDDDDD',
1095
+ }
1096
+
1139
1097
  @@drawing = nil
1140
1098
 
1141
1099
  @@pcs = Array.new
data/lib/randomlab.rb CHANGED
@@ -86,7 +86,20 @@ module RandomLab
86
86
  def new_deck
87
87
  (0..51).map { |i| Card.new(i) }
88
88
  end
89
+
90
+
91
+ =begin rdoc
92
+ Compute the probability of a duplicate item in a collection of n items
93
+ drawn from the range [1..d]. Example: call pdup(5,52) to compute the
94
+ probability if drawing the same card twice when sampling with replacement
95
+ 5 times from a deck of 52 cards.
96
+ =end
89
97
 
98
+ def pdup(n, d)
99
+ return 1.0 if n > d
100
+ return 1.0 - (1..(n-1)).inject(1.0) { |p, k| p * (1.0 - (k / 52.0)) }
101
+ end
102
+
90
103
  =begin rdoc
91
104
  A "helper method" that can be called via a probe, to print the contents
92
105
  of an array during the execution of the permute! method
@@ -272,7 +285,7 @@ module RandomLab
272
285
  def view_numberline(npoints, userOptions = {})
273
286
  Canvas.init(500, 100, "RandomLab::NumberLine")
274
287
  options = @@numberLineOptions.merge(userOptions)
275
- line = Canvas.line(0, 70, 500, 70, :width => options[:lineThickness], :fill => options[:lineColor])
288
+ line = Canvas::Line.new(0, 70, 500, 70, :width => options[:lineThickness], :fill => options[:lineColor])
276
289
  @@drawing = NumberLine.new(line, npoints, options)
277
290
  return true
278
291
  end
@@ -286,7 +299,7 @@ module RandomLab
286
299
  x0, y0, x1, y1 = @@drawing.line.coords
287
300
  tx = (i.to_f / @@drawing.npoints) * (x1-x0)
288
301
  ty = y0 - @@drawing.options[:tickHeight]
289
- Canvas.line(tx, y0, tx, ty, :width => @@drawing.options[:tickWidth], :fill => @@drawing.options[:tickColor])
302
+ Canvas::Line.new(tx, y0, tx, ty, :width => @@drawing.options[:tickWidth], :fill => @@drawing.options[:tickColor])
290
303
  sleep(@@delay)
291
304
  end
292
305
  return true
@@ -321,7 +334,7 @@ module RandomLab
321
334
  binTop = 280
322
335
  nbins.times do |i|
323
336
  x = i * binWidth + binWidth/2
324
- bins << Canvas.rectangle( x + binBorder, binTop, x + binWidth - binBorder, binTop + binHeight, :outline => options[:binColor], :fill => options[:binColor] )
337
+ bins << Canvas::Rectangle.new( x + binBorder, binTop, x + binWidth - binBorder, binTop + binHeight, :outline => options[:binColor], :fill => options[:binColor] )
325
338
  end
326
339
 
327
340
  @@drawing = Histogram.new(bins, max.to_f, keys, counts, binTop, options)
@@ -364,6 +377,7 @@ module RandomLab
364
377
  end
365
378
  @@drawing.options[:boxIncrement] /= 2
366
379
  end
380
+ sleep(@@delay)
367
381
  return true
368
382
  end
369
383
 
@@ -393,7 +407,7 @@ module RandomLab
393
407
  py = (y.to_f / @@drawing.max) * Canvas.height
394
408
  r = @@drawing.options[:dotRadius]
395
409
  color = @@drawing.options[:dotColor]
396
- Canvas.circle( px, py, r, :outline => color, :fill => color )
410
+ Canvas::Circle.new( px, py, r, :outline => color, :fill => color )
397
411
  end
398
412
  return nil
399
413
  end
@@ -422,7 +436,7 @@ module RandomLab
422
436
  }
423
437
 
424
438
  @@drawing = nil
425
- @@delay = 0.1
439
+ @@delay = 0.01
426
440
 
427
441
  end # RandomLab
428
442