redshift 1.3.17 → 1.3.18

Sign up to get free protection for your applications and to get access to all the features.
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