redshift 1.3.17 → 1.3.18

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 (44) hide show
  1. data/.bnsignore +23 -0
  2. data/.gitignore +7 -6
  3. data/README +22 -4
  4. data/RELEASE-NOTES +16 -0
  5. data/examples/lotka-volterra.rb +1 -1
  6. data/examples/modular-component-def.rb +49 -0
  7. data/examples/robots/README +49 -0
  8. data/examples/robots/lib/base.rb +38 -0
  9. data/examples/robots/lib/explosion.rb +48 -0
  10. data/examples/robots/lib/missile.rb +75 -0
  11. data/examples/robots/lib/radar.rb +56 -0
  12. data/examples/robots/lib/robot.rb +105 -0
  13. data/examples/robots/lib/shell-world.rb +167 -0
  14. data/examples/robots/lib/tracker.rb +16 -0
  15. data/examples/robots/robots.rb +53 -0
  16. data/examples/shell.rb +1 -2
  17. data/ext/redshift/buffer/buffer.c +102 -0
  18. data/ext/redshift/buffer/buffer.h +17 -0
  19. data/ext/redshift/buffer/dir.rb +1 -0
  20. data/ext/redshift/buffer/extconf.rb +2 -0
  21. data/ext/redshift/util/isaac/extconf.rb +2 -0
  22. data/ext/redshift/util/isaac/isaac.c +129 -0
  23. data/ext/redshift/util/isaac/rand.c +140 -0
  24. data/ext/redshift/util/isaac/rand.h +61 -0
  25. data/lib/redshift/mixins/shell.rb +72 -0
  26. data/lib/redshift/redshift.rb +1 -1
  27. data/lib/redshift/syntax.rb +12 -5
  28. data/lib/redshift/target/c/component-gen.rb +11 -8
  29. data/lib/redshift/target/c/flow/buffer.rb +17 -126
  30. data/lib/redshift/target/c/flow/delay.rb +5 -5
  31. data/lib/redshift/target/c/library.rb +12 -1
  32. data/lib/redshift/util/histogram.rb +1 -1
  33. data/lib/redshift/util/irb-shell.rb +81 -0
  34. data/lib/redshift/util/isaac.rb +22 -0
  35. data/lib/redshift/util/modular.rb +48 -0
  36. data/lib/redshift/util/tkar-driver.rb +1 -2
  37. data/lib/redshift/util/tracer/var.rb +1 -1
  38. data/lib/redshift/world.rb +9 -3
  39. data/rakefile +9 -1
  40. data/test/test.rb +23 -9
  41. data/test/test_buffer.rb +1 -1
  42. data/test/test_flow_trans.rb +3 -20
  43. metadata +50 -46
  44. data/lib/redshift/mixins/irb-shell.rb +0 -151
@@ -0,0 +1,140 @@
1
+ /*
2
+ ------------------------------------------------------------------------------
3
+ rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain.
4
+ MODIFIED:
5
+ 960327: Creation (addition of randinit, really)
6
+ 970719: use context, not global variables, for internal state
7
+ 980324: added main (ifdef'ed out), also rearranged randinit()
8
+ 010626: Note that this is public domain
9
+
10
+ ADAPTED Aug2004 for use in Ruby by Joel VanderWerf
11
+ ADAPTED Jan2010 for 64 bit systems (same algorithm and results as 32 bit)
12
+ ADAPTED Jun2010 for use within the redshift project
13
+ ------------------------------------------------------------------------------
14
+ */
15
+ #ifndef RAND
16
+ #include "rand.h"
17
+ #endif
18
+
19
+
20
+ #define ind(mm,x) ((mm)[(x>>2)&(RANDSIZ-1)])
21
+ #define rngstep(mix,a,b,mm,m,m2,r,x) \
22
+ { \
23
+ x = *m; \
24
+ a = ((a^(mix)) + *(m2++)); \
25
+ *(m++) = y = (ind(mm,x) + a + b); \
26
+ *(r++) = b = (ind(mm,y>>RANDSIZL) + x); \
27
+ }
28
+
29
+ void rs_isaac_rand(ctx)
30
+ randctx *ctx;
31
+ {
32
+ register ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
33
+ mm=ctx->randmem; r=ctx->randrsl;
34
+ a = ctx->randa; b = (ctx->randb + (++ctx->randc));
35
+ for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
36
+ {
37
+ rngstep( a<<13, a, b, mm, m, m2, r, x);
38
+ rngstep( a>>6 , a, b, mm, m, m2, r, x);
39
+ rngstep( a<<2 , a, b, mm, m, m2, r, x);
40
+ rngstep( a>>16, a, b, mm, m, m2, r, x);
41
+ }
42
+ for (m2 = mm; m2<mend; )
43
+ {
44
+ rngstep( a<<13, a, b, mm, m, m2, r, x);
45
+ rngstep( a>>6 , a, b, mm, m, m2, r, x);
46
+ rngstep( a<<2 , a, b, mm, m, m2, r, x);
47
+ rngstep( a>>16, a, b, mm, m, m2, r, x);
48
+ }
49
+ ctx->randb = b; ctx->randa = a;
50
+ }
51
+
52
+
53
+ #define mix(a,b,c,d,e,f,g,h) \
54
+ { \
55
+ a^=b<<11; d+=a; b+=c; \
56
+ b^=c>>2; e+=b; c+=d; \
57
+ c^=d<<8; f+=c; d+=e; \
58
+ d^=e>>16; g+=d; e+=f; \
59
+ e^=f<<10; h+=e; f+=g; \
60
+ f^=g>>4; a+=f; g+=h; \
61
+ g^=h<<8; b+=g; h+=a; \
62
+ h^=a>>9; c+=h; a+=b; \
63
+ }
64
+
65
+ /* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
66
+ void rs_isaac_init(ctx, flag)
67
+ randctx *ctx;
68
+ int flag;
69
+ {
70
+ int i;
71
+ ub4 a,b,c,d,e,f,g,h;
72
+ ub4 *m,*r;
73
+ ctx->randa = ctx->randb = ctx->randc = 0;
74
+ m=ctx->randmem;
75
+ r=ctx->randrsl;
76
+ a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
77
+
78
+ for (i=0; i<4; ++i) /* scramble it */
79
+ {
80
+ mix(a,b,c,d,e,f,g,h);
81
+ }
82
+
83
+ if (flag)
84
+ {
85
+ /* initialize using the contents of r[] as the seed */
86
+ for (i=0; i<RANDSIZ; i+=8)
87
+ {
88
+ a+=r[i ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
89
+ e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
90
+ mix(a,b,c,d,e,f,g,h);
91
+ m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
92
+ m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
93
+ }
94
+ /* do a second pass to make all of the seed affect all of m */
95
+ for (i=0; i<RANDSIZ; i+=8)
96
+ {
97
+ a+=m[i ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
98
+ e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
99
+ mix(a,b,c,d,e,f,g,h);
100
+ m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
101
+ m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
102
+ }
103
+ }
104
+ else
105
+ {
106
+ /* fill in mm[] with messy stuff */
107
+ for (i=0; i<RANDSIZ; i+=8)
108
+ {
109
+ mix(a,b,c,d,e,f,g,h);
110
+ m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
111
+ m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
112
+ }
113
+ }
114
+
115
+ rs_isaac_rand(ctx); /* fill in the first set of results */
116
+ ctx->randcnt=RANDSIZ; /* prepare to use the first set of results */
117
+ }
118
+
119
+
120
+ #ifdef NEVER
121
+ #include <stdio.h>
122
+
123
+ int main()
124
+ {
125
+ ub4 i,j;
126
+ randctx ctx;
127
+ ctx.randa=ctx.randb=ctx.randc=(ub4)0;
128
+ for (i=0; i<RANDSIZ; ++i) ctx.randrsl[i]=(ub4)0;
129
+ rs_isaac_init(&ctx, 1);
130
+ for (i=0; i<2; ++i)
131
+ {
132
+ rs_isaac_rand(&ctx);
133
+ for (j=0; j<RANDSIZ; ++j)
134
+ {
135
+ printf("%.8lx",(long unsigned int)ctx.randrsl[j]);
136
+ if ((j&7)==7) printf("\n");
137
+ }
138
+ }
139
+ }
140
+ #endif
@@ -0,0 +1,61 @@
1
+ /*
2
+ ------------------------------------------------------------------------------
3
+ rand.h: definitions for a random number generator
4
+ By Bob Jenkins, 1996, Public Domain
5
+ MODIFIED:
6
+ 960327: Creation (addition of randinit, really)
7
+ 970719: use context, not global variables, for internal state
8
+ 980324: renamed seed to flag
9
+ 980605: recommend RANDSIZL=4 for noncryptography.
10
+ 010626: note this is public domain
11
+
12
+ ADAPTED Aug2004 for use in Ruby by Joel VanderWerf
13
+ ADAPTED Jan2010 for 64 bit systems (same algorithm and results as 32 bit)
14
+ ADAPTED Jun2010 for use within the redshift project
15
+ ------------------------------------------------------------------------------
16
+ */
17
+
18
+ #include <stdint.h>
19
+
20
+ typedef uint32_t ub4;
21
+
22
+ #ifndef RAND
23
+ #define RAND
24
+ #define RANDSIZL (8) /* I recommend 8 for crypto, 4 for simulations */
25
+ #define RANDSIZ (1<<RANDSIZL)
26
+
27
+ /* context of random number generator */
28
+ struct randctx
29
+ {
30
+ ub4 randcnt;
31
+ ub4 randrsl[RANDSIZ];
32
+ ub4 randmem[RANDSIZ];
33
+ ub4 randa;
34
+ ub4 randb;
35
+ ub4 randc;
36
+ };
37
+ typedef struct randctx randctx;
38
+
39
+ /*
40
+ ------------------------------------------------------------------------------
41
+ If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
42
+ ------------------------------------------------------------------------------
43
+ */
44
+ void rs_isaac_init(randctx *r, int flag);
45
+
46
+ void rs_isaac_rand(randctx *r);
47
+
48
+
49
+ /*
50
+ ------------------------------------------------------------------------------
51
+ Call rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
52
+ ------------------------------------------------------------------------------
53
+ */
54
+ #define rand(r) \
55
+ (!(r)->randcnt-- ? \
56
+ (rs_isaac_rand(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
57
+ (r)->randrsl[(r)->randcnt])
58
+
59
+ #endif /* RAND */
60
+
61
+
@@ -0,0 +1,72 @@
1
+ require 'redshift/util/irb-shell'
2
+
3
+ class Object
4
+ include IRB::ExtendCommandBundle
5
+ # so that Marshal.dump still works, even when doing ">> irb obj"
6
+ end
7
+
8
+ def IRB.parse_opts
9
+ # Don't touch ARGV, which belongs to the app which called this module.
10
+ end
11
+
12
+ # extend a World instance with this (or include in a World subclass)
13
+ module RedShift::Shell
14
+ def shell
15
+ @shell ||= IRBShell.new(binding, self)
16
+ end
17
+
18
+ def run(*)
19
+ shell.install_interrupt_handler
20
+ super
21
+ end
22
+
23
+ def step(*)
24
+ super do
25
+ yield self if block_given?
26
+ if shell.handle_interrupt {before_shell}
27
+ after_shell
28
+ return
29
+ end
30
+ end
31
+ end
32
+
33
+ # Override to complete some action before dropping into shell.
34
+ def before_shell
35
+ end
36
+
37
+ # Override to complete some action after leaving shell.
38
+ def after_shell
39
+ end
40
+
41
+ # Typically, call this in a rescue clause, if you to let the user
42
+ # examine state and possibly continue:
43
+ #
44
+ # rescue ... => e
45
+ # require 'redshift/mixins/irb-shell'
46
+ # world.extend RedShift::IRBShell
47
+ # world.recoverable_error e, "Assertion failure", e.backtrace
48
+ #
49
+ def recoverable_error e, msg = "Error", bt = []
50
+ puts "#{msg} at time #{clock}"
51
+ puts "From " + bt[0..2].join("\n ") unless bt.empty
52
+ puts " ..." if bt.length > 3
53
+ shell.run
54
+ end
55
+
56
+ private
57
+ def q
58
+ exit
59
+ end
60
+
61
+ ## commands:
62
+ ## step [n] {block}
63
+ ## step_until/while
64
+ ## continue -- safer than ^D, does step_discrete in case of changes
65
+ ## step_continuous
66
+ ## step_discrete [n]
67
+ ## break [class/component/transition/comp.event/condition]
68
+ ## until step_until, stops inside step_discrete
69
+ ## clear
70
+ ##
71
+ ## customize prompt
72
+ end
@@ -33,7 +33,7 @@ end
33
33
  module RedShift
34
34
  include Math
35
35
 
36
- VERSION = '1.3.17'
36
+ VERSION = '1.3.18'
37
37
 
38
38
  Infinity = Math::Infinity
39
39
 
@@ -476,6 +476,7 @@ end
476
476
  #
477
477
  def Component.flow(*states, &block)
478
478
  raise "no flows specified. Put { on same line!" unless block
479
+ states = states.map {|s| must_be_state(s)}
479
480
  states = [Enter] if states == []
480
481
 
481
482
  attach states, FlowSyntax.parse(block)
@@ -507,18 +508,18 @@ def Component.transition(edges = {}, &block)
507
508
  end
508
509
 
509
510
  edges.each do |s, d|
510
- must_be_state(d)
511
+ d = must_be_state(d)
511
512
 
512
513
  case s
513
514
  when Array
514
515
  s.each do |t|
515
- must_be_state(t)
516
+ t = must_be_state(t)
516
517
  warn << t if e[t]
517
518
  e[t] = d
518
519
  end
519
520
 
520
521
  else
521
- must_be_state(s)
522
+ s = must_be_state(s)
522
523
  warn << s if e[s]
523
524
  e[s] = d
524
525
  end
@@ -554,9 +555,15 @@ def Component.transition(edges = {}, &block)
554
555
  end
555
556
 
556
557
  def Component.must_be_state s
557
- unless s.kind_of? State
558
- raise TypeError, "Not a state: #{s}"
558
+ return s if s.kind_of?(State)
559
+ state = const_get(s.to_s)
560
+ rescue NameError
561
+ raise TypeError, "Not a state: #{s.inspect}"
562
+ else
563
+ unless state.kind_of?(State)
564
+ raise TypeError, "Not a state: #{s.inspect}"
559
565
  end
566
+ state
560
567
  end
561
568
 
562
569
  end
@@ -594,19 +594,18 @@ module RedShift
594
594
 
595
595
  def add_var_to_offset_table var_name
596
596
  ssn = shadow_struct.name
597
+ lit = shadow_library.literal_symbol(var_name,
598
+ shadow_library_source_file)
597
599
  offset_table_method.body %{\
598
- rb_hash_aset(table, #{shadow_library.literal_symbol(var_name)},
600
+ rb_hash_aset(table, #{lit},
599
601
  INT2FIX((char *)&(((struct #{ssn} *)0)->#{var_name}) - (char *)0));
600
602
  } ## can we just use offsetof() ?
601
603
  end
602
604
 
603
605
  def define_links
604
- own_links = link_variables.own
605
- return if own_links.empty?
606
-
607
606
  ssn = shadow_struct.name
608
607
 
609
- own_links.keys.sort_by{|k|k.to_s}.each do |var_name|
608
+ link_variables.own.keys.sort_by{|k|k.to_s}.each do |var_name|
610
609
  var_type, strictness = link_variables[var_name]
611
610
 
612
611
  unless var_type.is_a? Class
@@ -632,12 +631,16 @@ module RedShift
632
631
  rs_raise(#{exc}, shadow->self, #{msg.inspect});
633
632
  }
634
633
  end
635
-
636
- shadow_library_include_file.include(
637
- var_type.shadow_library_include_file)
638
634
 
639
635
  add_var_to_offset_table(var_name)
640
636
  end
637
+
638
+ link_variables.keys.sort_by{|k|k.to_s}.each do |var_name|
639
+ var_type, strictness = link_variables[var_name]
640
+
641
+ shadow_library_source_file.include(
642
+ var_type.shadow_library_include_file)
643
+ end
641
644
  end
642
645
 
643
646
  def check_variables
@@ -1,140 +1,31 @@
1
+ require 'redshift/buffer/buffer.so'
2
+ require 'redshift/buffer/dir'
3
+
1
4
  class RedShift::Library
2
5
  def define_buffer
3
- return if @define_buffer
4
- @define_buffer = true
5
-
6
- include_file, source_file = add_file "buffer"
7
-
8
- include_file.declare :Buffer => %{
9
- typedef struct {
10
- long len;
11
- long offset;
12
- double *ptr;
13
- } Buffer;
14
- }.tabto(0)
15
-
16
- source_file.define_c_function(:buffer_init).instance_eval {
17
- arguments "Buffer *buf", "long len", "double fill"
18
- scope :extern
19
- body %{
20
- int i;
21
- buf->ptr = ALLOC_N(double, len);
22
- buf->len = len;
23
- buf->offset = 0;
24
- for (i=0; i<len; i++) {
25
- buf->ptr[i] = fill;
26
- }
27
- }
28
- }
29
-
30
- source_file.define_c_function(:buffer_resize).instance_eval {
31
- arguments "Buffer *buf", "long len"
32
- scope :extern
33
- body %{
34
- long i;
35
- long old_len = buf->len;
36
- long offset = buf->offset;
37
- double *ptr = buf->ptr;
38
- double *dst, *src;
39
- double fill;
40
-
41
- if (len < old_len) {
42
- if (offset < len) {
43
- dst = ptr + offset;
44
- src = ptr + offset + old_len - len;
45
- memmove(dst, src, (len - offset) * sizeof(double));
46
- }
47
- else {
48
- dst = ptr;
49
- src = ptr + offset - len;
50
- offset = 0;
51
- memmove(dst, src, len * sizeof(double));
52
- }
53
- REALLOC_N(ptr, double, len);
54
- // ## maybe better: don't release space, just use less of it
55
- }
56
- else if (len > old_len) {
57
- REALLOC_N(ptr, double, len);
58
-
59
- fill = ptr[offset];
60
- dst = ptr + offset + len - old_len;
61
- src = ptr + offset;
62
- memmove(dst, src, (old_len - offset) * sizeof(double));
63
-
64
- for (i = 0; i < len - old_len; i++) {
65
- ptr[offset + i] = fill;
66
- }
67
- }
68
- else
69
- return;
70
-
71
- buf->len = len;
72
- buf->offset = offset;
73
- buf->ptr = ptr;
74
- }
75
- }
76
-
77
- source_file.define_c_function(:buffer_inhale_array).instance_eval {
78
- arguments "Buffer *buf", "VALUE ary"
79
- scope :extern
80
- body %{
81
- int size, i;
82
-
83
- Check_Type(ary, T_ARRAY);
84
-
85
- size = RARRAY(ary)->len;
86
- if (buf->ptr) {
87
- REALLOC_N(buf->ptr, double, size);
88
- }
89
- else {
90
- buf->ptr = ALLOC_N(double, size);
91
- }
92
- buf->len = size;
93
- buf->offset = 0;
94
-
95
- for (i = 0; i < size; i++) {
96
- buf->ptr[i] = NUM2DBL(RARRAY(ary)->ptr[i]);
97
- }
98
- }
99
- }
100
-
101
- source_file.define_c_function(:buffer_exhale_array).instance_eval {
102
- arguments "Buffer *buf"
103
- return_type "VALUE"
104
- returns "ary"
105
- scope :extern
106
- declare :size => "int size",
107
- :i => "int i",
108
- :j => "int j",
109
- :ary => "VALUE ary"
110
- body %{
111
- size = buf->len;
112
- ary = rb_ary_new2(size);
113
- RARRAY(ary)->len = size;
114
- for (i = buf->offset, j=0; i < size; i++, j++) {
115
- RARRAY(ary)->ptr[j] = rb_float_new(buf->ptr[i]);
116
- }
117
- for (i = 0; i < buf->offset; i++, j++) {
118
- RARRAY(ary)->ptr[j] = rb_float_new(buf->ptr[i]);
119
- }
120
- }
121
- }
6
+ unless @buffer_defined
7
+ @buffer_defined = true
8
+ text = File.read(File.join(REDSHIFT_BUFFER_DIR, "buffer.h"))
9
+ buffer_h = CGenerator::CFile.new("buffer.h", self, nil, true)
10
+ buffer_h.declare :buffer_header_text => text
11
+ add [buffer_h]
12
+ end
122
13
  end
123
-
14
+
124
15
  # An embedded struct that holds a pointer +ptr+ to an externally stored
125
16
  # array of doubles of length +len+.
126
17
  class BufferAttribute < CShadow::CNativeAttribute
127
- @pattern = /\A(Buffer)\s+(\w+)\z/
18
+ @pattern = /\A(RSBuffer)\s+(\w+)\z/
128
19
 
129
20
  def initialize(*args)
130
21
  super
131
- lib = owner_class.shadow_library
132
22
  owner_class.shadow_library_include_file.include "buffer.h"
133
23
 
134
- @reader = "result = buffer_exhale_array(&shadow->#{@cvar})"
135
- @writer = "buffer_inhale_array(&shadow->#{@cvar}, arg)"
136
- @dump = "rb_ary_push(result, buffer_exhale_array(&shadow->#{@cvar}))"
137
- @load = "buffer_inhale_array(&shadow->#{@cvar}, rb_ary_shift(from_array))"
24
+ @reader = "result = rs_buffer_exhale_array(&shadow->#{@cvar})"
25
+ @writer = "rs_buffer_inhale_array(&shadow->#{@cvar}, arg)"
26
+ @dump = "rb_ary_push(result, rs_buffer_exhale_array(&shadow->#{@cvar}))"
27
+ @load =
28
+ "rs_buffer_inhale_array(&shadow->#{@cvar}, rb_ary_shift(from_array))"
138
29
  @free = "free(shadow->#{@cvar}.ptr)"
139
30
  end
140
31
  end