flor 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG.md +7 -0
  2. data/Makefile +3 -0
  3. data/lib/flor.rb +1 -1
  4. data/lib/flor/colours.rb +7 -3
  5. data/lib/flor/conf.rb +21 -15
  6. data/lib/flor/core/executor.rb +71 -77
  7. data/lib/flor/core/node.rb +6 -1
  8. data/lib/flor/core/procedure.rb +112 -58
  9. data/lib/flor/core/texecutor.rb +6 -5
  10. data/lib/flor/log.rb +9 -7
  11. data/lib/flor/migrations/0003_timer_onid_bnid.rb +35 -0
  12. data/lib/flor/migrations/0004_trap_bnid.rb +16 -0
  13. data/lib/flor/pcore/_arr.rb +2 -2
  14. data/lib/flor/pcore/_atom.rb +1 -1
  15. data/lib/flor/pcore/_att.rb +59 -13
  16. data/lib/flor/pcore/_happly.rb +3 -3
  17. data/lib/flor/pcore/_obj.rb +22 -2
  18. data/lib/flor/pcore/_skip.rb +2 -2
  19. data/lib/flor/pcore/apply.rb +1 -1
  20. data/lib/flor/pcore/arith.rb +1 -1
  21. data/lib/flor/pcore/break.rb +2 -2
  22. data/lib/flor/pcore/case.rb +1 -1
  23. data/lib/flor/pcore/cmp.rb +1 -1
  24. data/lib/flor/pcore/cond.rb +1 -1
  25. data/lib/flor/pcore/cursor.rb +2 -2
  26. data/lib/flor/pcore/define.rb +1 -1
  27. data/lib/flor/pcore/fail.rb +1 -6
  28. data/lib/flor/pcore/if.rb +2 -2
  29. data/lib/flor/pcore/map.rb +1 -1
  30. data/lib/flor/pcore/matchr.rb +92 -0
  31. data/lib/flor/pcore/move.rb +2 -3
  32. data/lib/flor/pcore/noeval.rb +1 -1
  33. data/lib/flor/pcore/noret.rb +1 -1
  34. data/lib/flor/pcore/push.rb +1 -1
  35. data/lib/flor/pcore/rand.rb +1 -1
  36. data/lib/flor/pcore/set.rb +1 -1
  37. data/lib/flor/pcore/twig.rb +2 -2
  38. data/lib/flor/pcore/until.rb +4 -1
  39. data/lib/flor/pcore/val.rb +1 -1
  40. data/lib/flor/punit/cancel.rb +2 -3
  41. data/lib/flor/punit/cmap.rb +5 -6
  42. data/lib/flor/punit/concurrence.rb +3 -5
  43. data/lib/flor/punit/schedule.rb +20 -5
  44. data/lib/flor/punit/signal.rb +1 -1
  45. data/lib/flor/punit/sleep.rb +2 -2
  46. data/lib/flor/punit/task.rb +3 -3
  47. data/lib/flor/punit/trace.rb +1 -1
  48. data/lib/flor/punit/trap.rb +22 -6
  49. data/lib/flor/to_string.rb +2 -1
  50. data/lib/flor/unit/executor.rb +3 -5
  51. data/lib/flor/unit/hooker.rb +2 -3
  52. data/lib/flor/unit/models/timer.rb +9 -3
  53. data/lib/flor/unit/models/trap.rb +1 -0
  54. data/lib/flor/unit/scheduler.rb +40 -35
  55. data/lib/flor/unit/storage.rb +70 -59
  56. data/lib/flor/unit/waiter.rb +2 -3
  57. data/t.txt +4 -0
  58. metadata +6 -4
  59. data/fail.txt +0 -3
  60. data/lib/flor/pcore/match.rb +0 -46
@@ -31,9 +31,9 @@ module Flor
31
31
  []
32
32
  end
33
33
 
34
- def remove_node(exid, n)
34
+ def archive_node(exid, node)
35
35
 
36
- (@archive[exid] ||= {})[n['nid']] = Flor.dup(n) if @archive
36
+ (@archive[exid] ||= {})[node['nid']] = Flor.dup(node) if @archive
37
37
  end
38
38
 
39
39
  def has_tasker?(exid, tname)
@@ -59,8 +59,7 @@ module Flor
59
59
 
60
60
  def initialize(conf={})
61
61
 
62
- conf.merge!(Flor::Conf.read_env) unless conf['conf'] == true
63
- # don't read FLOR_DEBUG if this executor is only meant to read the conf
62
+ conf = Flor::Conf.prepare(conf, {})
64
63
 
65
64
  super(
66
65
  TransientUnit.new(conf),
@@ -72,6 +71,8 @@ module Flor
72
71
  #'ashes' => {},
73
72
  'start' => Flor.tstamp
74
73
  })
74
+
75
+ @unit.archive = {} if conf['archive']
75
76
  end
76
77
 
77
78
  def journal; @unit.journal; end
@@ -80,7 +81,7 @@ module Flor
80
81
  def launch(tree, opts={})
81
82
 
82
83
  @unit.opts = opts
83
- @unit.archive = {} if opts[:archive]
84
+ @unit.archive ||= {} if opts[:archive]
84
85
 
85
86
  Flor.print_src(tree, opts) if conf['log_src']
86
87
 
data/lib/flor/log.rb CHANGED
@@ -142,6 +142,8 @@ module Flor
142
142
 
143
143
  def self.print_tree(tree, nid='0', opts={})
144
144
 
145
+ t0, t1, t2 = (tree || [])
146
+
145
147
  o = (opts[:out] ||= $stdout)
146
148
  _c = colours(opts)
147
149
 
@@ -150,14 +152,14 @@ module Flor
150
152
  headers = opts[:headers]; headers = true if headers.nil?
151
153
  headers = true if opts[:title]
152
154
 
153
- h = "#{_c.yl}#{Flor.to_d(tree[0], compact: true)}"
154
- c = tree[1].is_a?(Array) ? '' : " #{_c.yl}#{tree[1]}"
155
- l = " #{_c.dg}L#{tree[2]}"
155
+ h = "#{_c.yl}#{Flor.to_d(t0, compact: true)}"
156
+ c = t1.is_a?(Array) ? '' : " #{_c.yl}#{t1}"
157
+ l = " #{_c.dg}L#{t2}"
156
158
 
157
159
  o.puts "#{ind}#{_c.dg}+--- #{opts[:title]}#{_c.rs}" if headers && nid == '0'
158
160
  o.puts "#{ind}#{_c.dg}| #{nid} #{h}#{c}#{l}#{_c.rs}"
159
- if tree[1].is_a?(Array)
160
- tree[1].each_with_index { |ct, i| print_tree(ct, "#{nid}_#{i}", opts) }
161
+ if t1.is_a?(Array)
162
+ t1.each_with_index { |ct, i| print_tree(ct, Flor.child_nid(nid, i), opts) }
161
163
  end
162
164
  o.puts "#{ind}#{_c.dg}.#{_c.rs}" if headers && nid == '0'
163
165
 
@@ -235,7 +237,7 @@ module Flor
235
237
  t = Flor.truncate_string(t, 42);
236
238
 
237
239
  h = {}
238
- %w[ parent cnid noreply dbg removed ].each do |k|
240
+ %w[ parent cnid noreply dbg ].each do |k|
239
241
  h[k] = n[k] if n.has_key?(k)
240
242
  end
241
243
 
@@ -306,7 +308,7 @@ module Flor
306
308
  o.puts "#{_c.dg}payload:#{_c.yl}"
307
309
  o.puts(Flor.to_pretty_s(m['payload'], 0))
308
310
  o.puts "#{_c.dg}tree:"
309
- print_tree(node.lookup_tree(nid), nid, out: o) if node # FIXME
311
+ print_tree(node.lookup_tree(nid), nid, out: o) if node
310
312
  o.puts "#{_c.dg}node:#{_c.yl}"
311
313
  o.puts(Flor.to_pretty_s(n)) if n
312
314
  o.puts "#{_c.dg}nodes:"
@@ -0,0 +1,35 @@
1
+
2
+ Sequel.migration do
3
+
4
+ up do
5
+
6
+ alter_table :flor_timers do
7
+
8
+ add_column :onid, String
9
+ add_column :bnid, String
10
+ end
11
+
12
+ self[:flor_timers].update(onid: :nid)
13
+ self[:flor_timers].update(bnid: :nid)
14
+
15
+ alter_table :flor_timers do
16
+
17
+ set_column_not_null :onid
18
+ set_column_not_null :bnid
19
+ end
20
+ #
21
+ # Sqlite3, for example, does that by renaming "flor_timers",
22
+ # creating a new table with the "not null" set, then copying the
23
+ # values of the renamed, original, table into the new table...
24
+ end
25
+
26
+ down do
27
+
28
+ alter_table :flor_timers do
29
+
30
+ drop_column :onid
31
+ drop_column :bnid
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,16 @@
1
+
2
+ Sequel.migration do
3
+
4
+ up do
5
+
6
+ alter_table(:flor_traps) { add_column :bnid, String }
7
+ self[:flor_traps].update(bnid: :nid)
8
+ alter_table(:flor_traps) { set_column_not_null :bnid }
9
+ end
10
+
11
+ down do
12
+
13
+ alter_table(:flor_traps) { drop_column :bnid }
14
+ end
15
+ end
16
+
@@ -10,7 +10,7 @@ class Flor::Pro::Arr < Flor::Procedure
10
10
 
11
11
  def receive
12
12
 
13
- return reply('ret' => []) if children == 0
13
+ return wrap_reply('ret' => []) if children == 0
14
14
 
15
15
  super
16
16
  end
@@ -19,7 +19,7 @@ class Flor::Pro::Arr < Flor::Procedure
19
19
 
20
20
  payload['ret'] = @node['rets']
21
21
 
22
- reply
22
+ wrap_reply
23
23
  end
24
24
  end
25
25
 
@@ -13,7 +13,7 @@ class Flor::Pro::Atom < Flor::Procedure
13
13
  else tree[1]
14
14
  end
15
15
 
16
- reply
16
+ wrap_reply
17
17
  end
18
18
  end
19
19
 
@@ -5,11 +5,14 @@ class Flor::Pro::Att < Flor::Procedure
5
5
 
6
6
  def execute
7
7
 
8
- return reply if children == [ [ '_', [], tree[2] ] ]
8
+ return wrap_reply if children == [ [ '_', [], tree[2] ] ]
9
9
  # spares 1 message
10
10
 
11
11
  pt = parent_node['tree']
12
- return reply if pt && pt[0] == '_apply'
12
+ return wrap_reply if pt && pt[0] == '_apply'
13
+
14
+ m = "pre_execute_#{children[0][0]}"
15
+ send(m) if respond_to?(m, true)
13
16
 
14
17
  execute_child(0, nil, 'accept_symbol' => children.size > 1)
15
18
  end
@@ -25,6 +28,36 @@ class Flor::Pro::Att < Flor::Procedure
25
28
 
26
29
  protected
27
30
 
31
+ #
32
+ # execute phase
33
+
34
+ def pre_execute_boolean_attribute
35
+
36
+ return unless children.size == 1
37
+
38
+ t = @node['tree'] = Flor.dup(tree)
39
+ t[1] << [ '_boo', true, @node['tree'][2] ]
40
+ end
41
+
42
+ alias pre_execute_flank pre_execute_boolean_attribute
43
+
44
+ def pre_execute_vars
45
+
46
+ return unless children.size == 2 && children[1][0] == '_obj'
47
+
48
+ t = tree
49
+
50
+ return if t[1][1][1] == 0 # [ '_obj', 0, 123 ]
51
+
52
+ t = @node['tree'] = Flor.dup(t)
53
+
54
+ t[1][1][1].unshift([
55
+ '_att', [ [ 'quote', [], -1 ], [ '_sqs', 'keys', -1 ] ], -1 ])
56
+ end
57
+
58
+ #
59
+ # receive phase
60
+
28
61
  def receive_unkeyed
29
62
 
30
63
  receive_att(nil)
@@ -71,17 +104,21 @@ class Flor::Pro::Att < Flor::Procedure
71
104
 
72
105
  payload['ret'] = @node['ret'] if key
73
106
 
74
- reply
107
+ wrap_reply
75
108
  end
76
109
 
77
110
  # vars: { ... }, inits a scope for the parent node
78
111
  #
79
112
  def receive_vars
80
113
 
81
- parent_node['vars'] = payload['ret']
114
+ vars = payload['ret']
115
+ vars = @executor.vars(nid) if vars == 'copy' || vars == '*'
116
+
117
+ (parent_node['vars'] ||= {}).merge!(vars)
118
+
82
119
  payload['ret'] = @node['ret']
83
120
 
84
- reply
121
+ wrap_reply
85
122
  end
86
123
 
87
124
  def receive_tag
@@ -96,13 +133,13 @@ class Flor::Pro::Att < Flor::Procedure
96
133
 
97
134
  tags = Array(ret)
98
135
 
99
- return reply if tags.empty?
136
+ return wrap_reply if tags.empty?
100
137
 
101
138
  (parent_node['tags'] ||= []).concat(tags)
102
139
  parent_node['tags'].uniq!
103
140
 
104
- reply('point' => 'entered', 'tags' => tags) +
105
- reply
141
+ wrap('point' => 'entered', 'tags' => tags) +
142
+ wrap_reply
106
143
  end
107
144
  alias receive_tags receive_tag
108
145
 
@@ -112,17 +149,17 @@ class Flor::Pro::Att < Flor::Procedure
112
149
  pn['aret'] = Flor.dup(payload['ret'])
113
150
  end
114
151
 
115
- reply
152
+ wrap_reply
116
153
  end
117
154
 
118
155
  def receive_timeout
119
156
 
120
157
  n = parent
121
- m = reply('point' => 'cancel', 'nid' => n, 'flavour' => 'timeout').first
158
+ m = wrap_cancel('nid' => n, 'flavour' => 'timeout').first
122
159
  t = payload['ret']
123
160
 
124
- schedule('type' => 'in', 'string' => t, 'nid' => n, 'message' => m) +
125
- reply
161
+ wrap_schedule('type' => 'in', 'string' => t, 'nid' => n, 'message' => m) +
162
+ wrap_reply
126
163
  end
127
164
 
128
165
  def receive_on_error
@@ -132,7 +169,16 @@ class Flor::Pro::Att < Flor::Procedure
132
169
 
133
170
  (parent_node['on_error'] ||= []) << oe
134
171
 
135
- reply
172
+ wrap_reply
173
+ end
174
+
175
+ def receive_flank
176
+
177
+ return wrap_reply unless Flor.true?(payload['ret'])
178
+ return wrap_reply unless parent_node
179
+
180
+ Flor::Procedure.make(@executor, parent_node, @message).flank +
181
+ wrap_reply
136
182
  end
137
183
  end
138
184
 
@@ -10,7 +10,7 @@ class Flor::Pro::Happly < Flor::Procedure
10
10
 
11
11
  def execute
12
12
 
13
- queue(
13
+ wrap(
14
14
  'point' => 'execute',
15
15
  'nid' => Flor.child_nid(nid, tree[1].size),
16
16
  'tree' => tree[0])
@@ -20,7 +20,7 @@ class Flor::Pro::Happly < Flor::Procedure
20
20
 
21
21
  fcid = Flor.child_id(message['from'])
22
22
 
23
- return reply if @node['applied']
23
+ return wrap_reply if @node['applied']
24
24
  return super unless fcid == tree[1].size
25
25
 
26
26
  ret = payload['ret']
@@ -33,7 +33,7 @@ class Flor::Pro::Happly < Flor::Procedure
33
33
 
34
34
  hret = @node['hret']
35
35
 
36
- return reply('ret' => hret) unless Flor.is_func_tree?(hret)
36
+ return wrap_reply('ret' => hret) unless Flor.is_func_tree?(hret)
37
37
 
38
38
  args = @node['atts'].collect(&:last)
39
39
 
@@ -6,11 +6,31 @@ class Flor::Pro::Obj < Flor::Procedure
6
6
  def pre_execute
7
7
 
8
8
  @node['rets'] = []
9
+ @node['atts'] = []
10
+ end
11
+
12
+ def receive_last_att
13
+
14
+ return super unless att('quote') == 'keys'
15
+
16
+ t0 = tree
17
+ t1 = Flor.dup(t0)
18
+
19
+ (@ncid..t1[1].length - 1).step(2) do |i|
20
+
21
+ c = t1[1][i]
22
+
23
+ t1[1][i] = [ '_sqs', c[0], *c[2..-1] ] if c[0].is_a?(String) && c[1] == []
24
+ end
25
+
26
+ @node['tree'] = t1 if t1 != t0
27
+
28
+ super
9
29
  end
10
30
 
11
31
  def receive_first
12
32
 
13
- return reply('ret' => {}) if children == 0
33
+ return wrap_reply('ret' => {}) if children == 0
14
34
 
15
35
  cn = children
16
36
  .inject([]) { |a, e| a << (a.size.even? ? stringify(e) : e); a }
@@ -27,7 +47,7 @@ class Flor::Pro::Obj < Flor::Procedure
27
47
  .each_slice(2)
28
48
  .inject({}) { |h, (k, v)| h[k.to_s] = v; h }
29
49
 
30
- reply
50
+ wrap_reply
31
51
  end
32
52
 
33
53
  protected
@@ -23,9 +23,9 @@ class Flor::Pro::Skip < Flor::Procedure
23
23
 
24
24
  @node['count'] -= 1
25
25
 
26
- return reply if @node['count'] < 1
26
+ return wrap_reply if @node['count'] < 1
27
27
 
28
- reply('nid' => nid, 'from' => Flor.child_nid(nid, children.size))
28
+ wrap_reply('nid' => nid, 'from' => Flor.child_nid(nid, children.size))
29
29
  end
30
30
 
31
31
  def receive_last
@@ -33,7 +33,7 @@ class Flor::Pro::Apply < Flor::Procedure
33
33
 
34
34
  def receive
35
35
 
36
- return reply if from && from == @node['applied']
36
+ return wrap_reply if from && from == @node['applied']
37
37
 
38
38
  super
39
39
  end
@@ -16,7 +16,7 @@ class Flor::Pro::Arith < Flor::Procedure
16
16
 
17
17
  payload['ret'] = @node['rets'].reduce(&sign) || DEFAULTS[sign]
18
18
 
19
- reply
19
+ wrap_reply
20
20
  end
21
21
  end
22
22
 
@@ -30,7 +30,7 @@ class Flor::Pro::Break < Flor::Procedure
30
30
 
31
31
  if nid
32
32
 
33
- ms += reply('point' => 'cancel', 'nid' => nid, 'flavour' => @node['heap'])
33
+ ms += wrap_cancel('nid' => nid, 'flavour' => @node['heap'])
34
34
  end
35
35
 
36
36
  unless is_ancestor_node?(nid)
@@ -38,7 +38,7 @@ class Flor::Pro::Break < Flor::Procedure
38
38
  pl = ms.any? ? payload.copy_current : payload.current
39
39
  pl['ret'] = node_payload_ret
40
40
 
41
- ms += reply('payload' => pl)
41
+ ms += wrap_reply('payload' => pl)
42
42
  end
43
43
 
44
44
  ms
@@ -42,7 +42,7 @@ class Flor::Pro::Case < Flor::Procedure
42
42
 
43
43
  def receive_non_att
44
44
 
45
- return reply if @node['found']
45
+ return wrap_reply if @node['found']
46
46
 
47
47
  return receive_array if @node.has_key?('key')
48
48
 
@@ -21,7 +21,7 @@ class Flor::Pro::Cmp < Flor::Procedure
21
21
  true
22
22
  end
23
23
 
24
- reply
24
+ wrap_reply
25
25
  end
26
26
 
27
27
  protected
@@ -30,7 +30,7 @@ class Flor::Pro::Cond < Flor::Procedure
30
30
  def receive_non_att
31
31
 
32
32
  return execute_child(0) if @message['point'] == 'execute'
33
- return reply if @node['found']
33
+ return wrap_reply if @node['found']
34
34
 
35
35
  tf2 = tree[1][@fcid + 2]
36
36