flor 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -0
- data/lib/flor.rb +1 -1
- data/lib/flor/core.rb +7 -0
- data/lib/flor/core/executor.rb +43 -8
- data/lib/flor/core/node.rb +84 -54
- data/lib/flor/core/procedure.rb +36 -19
- data/lib/flor/core/texecutor.rb +4 -1
- data/lib/flor/deep.rb +43 -51
- data/lib/flor/dollar.rb +2 -3
- data/lib/flor/flor.rb +38 -9
- data/lib/flor/parser.rb +123 -72
- data/lib/flor/pcore/_arr.rb +15 -0
- data/lib/flor/pcore/_atom.rb +6 -5
- data/lib/flor/pcore/_att.rb +9 -4
- data/lib/flor/pcore/_obj.rb +28 -34
- data/lib/flor/pcore/_pat_.rb +77 -0
- data/lib/flor/pcore/_pat_arr.rb +131 -0
- data/lib/flor/pcore/_pat_guard.rb +70 -0
- data/lib/flor/pcore/_pat_obj.rb +143 -0
- data/lib/flor/pcore/_pat_or.rb +46 -0
- data/lib/flor/pcore/_val.rb +20 -0
- data/lib/flor/pcore/arith.rb +7 -1
- data/lib/flor/pcore/case.rb +46 -69
- data/lib/flor/pcore/cursor.rb +24 -24
- data/lib/flor/pcore/define.rb +5 -1
- data/lib/flor/pcore/do_return.rb +32 -0
- data/lib/flor/pcore/length.rb +18 -0
- data/lib/flor/pcore/logo.rb +47 -0
- data/lib/flor/pcore/map.rb +12 -10
- data/lib/flor/pcore/match.rb +276 -0
- data/lib/flor/pcore/not.rb +13 -0
- data/lib/flor/pcore/push.rb +52 -13
- data/lib/flor/pcore/range.rb +69 -0
- data/lib/flor/pcore/set.rb +82 -24
- data/lib/flor/unit/hook.rb +28 -0
- data/lib/flor/unit/hooker.rb +5 -0
- data/lib/flor/unit/loader.rb +4 -1
- data/lib/flor/unit/storage.rb +5 -3
- data/lib/flor/unit/waiter.rb +12 -2
- data/lib/flor/unit/wlist.rb +4 -3
- data/match.md +22 -0
- metadata +15 -5
- data/lib/flor/pcore/_happly.rb +0 -49
- data/lib/flor/pcore/val.rb +0 -16
- data/t.txt +0 -4
data/lib/flor/pcore/set.rb
CHANGED
@@ -1,28 +1,105 @@
|
|
1
1
|
|
2
2
|
class Flor::Pro::Set < Flor::Procedure
|
3
|
+
#
|
4
|
+
# sets a field or a variable.
|
5
|
+
#
|
6
|
+
# ```
|
7
|
+
# sequence
|
8
|
+
# set f.a 1 # sets the value `1` in the field 'a'
|
9
|
+
# set a false # sets the `false` in the variable 'a'
|
10
|
+
# set v.b [ 1 2 ] # sets `[ 1, 2 ]` in the variable 'b'
|
11
|
+
# set v.c.0 -1 # sets `-1` in first slot of the array in var 'c'
|
12
|
+
# ```
|
13
|
+
#
|
14
|
+
# When set has a single child, it uses as value to copy the content of
|
15
|
+
# payload.ret.
|
16
|
+
#
|
17
|
+
# ```
|
18
|
+
# sequence
|
19
|
+
# "hello world"
|
20
|
+
# set a
|
21
|
+
# #
|
22
|
+
# # is equivalent to
|
23
|
+
# #
|
24
|
+
# sequence
|
25
|
+
# set a "hello world"
|
26
|
+
# ```
|
27
|
+
#
|
28
|
+
# ## splat
|
29
|
+
#
|
30
|
+
# ```
|
31
|
+
# sequence
|
32
|
+
# set a b___ c
|
33
|
+
# [ 0 1 2 3 ]
|
34
|
+
# # ==> a: 0, b: [ 1, 2 ], c: 3
|
35
|
+
# set d e__2 f
|
36
|
+
# [ 4 5 6 7 8 ]
|
37
|
+
# # ==> d: 4, e: [ 5, 6 ], f: 7
|
38
|
+
# set __2 g h
|
39
|
+
# [ 9 10 11 12 13 ]
|
40
|
+
# # ==> g: 11, h: 12
|
41
|
+
# # `__` is not prefixed by a var name, so it justs discard
|
42
|
+
# # what it captures
|
43
|
+
# set i j___
|
44
|
+
# [ 14 15 16 17 18 19 ]
|
45
|
+
# # ==> i: 14, j: (15..19).to_a
|
46
|
+
# set "k__$(c)" l
|
47
|
+
# [ 20 21 22 23 24 ]
|
48
|
+
# # ==> k: [ 20, 21, 22 ], l: 23
|
49
|
+
# ```
|
50
|
+
#
|
51
|
+
# ## "setr"
|
52
|
+
#
|
53
|
+
# "set", before terminating its execution carefully resets the payload.ret
|
54
|
+
# value to what it was right before it started executing.
|
55
|
+
# "setr" is a version of "set" that doesn't care and leave payload.ret to
|
56
|
+
# value set by its last child (usually the value set).
|
57
|
+
#
|
58
|
+
# ```
|
59
|
+
# sequence
|
60
|
+
# 123 # payload.ret is set to `123`
|
61
|
+
# set a 456 # var 'a' is set to 456, payload.ret is reset to `123`
|
62
|
+
# setr b 789 # var 'b' is set to `789`, payload.ret as well
|
63
|
+
# ```
|
3
64
|
|
4
65
|
names %w[ set setr ]
|
5
66
|
|
6
67
|
def pre_execute
|
7
68
|
|
8
69
|
unatt_unkeyed_children
|
9
|
-
|
70
|
+
|
71
|
+
nacn = non_att_children.dup
|
72
|
+
sc = @node['single_child'] = nacn.size == 1
|
73
|
+
nacn = non_att_children[0..-2] unless sc
|
74
|
+
|
75
|
+
nacn.each_with_index { |_, i| stringify_child(i) }
|
76
|
+
|
77
|
+
@node['refs'] = []
|
10
78
|
end
|
11
79
|
|
12
80
|
def receive_non_att
|
13
81
|
|
14
|
-
|
82
|
+
ret = payload['ret']
|
83
|
+
last = ! @node['single_child'] && (@fcid + 1) == children.size
|
84
|
+
|
85
|
+
@node['refs'] << ret if ! last && ret.is_a?(String)
|
15
86
|
|
16
87
|
super
|
17
88
|
end
|
18
89
|
|
19
90
|
def receive_last
|
20
91
|
|
21
|
-
|
92
|
+
ret = @node['single_child'] ? node_payload_ret : payload['ret']
|
93
|
+
|
94
|
+
if @node['refs'].size == 1
|
95
|
+
set_value(@node['refs'].first, ret)
|
96
|
+
else
|
97
|
+
Flor.splat(@node['refs'], ret).each { |k, v| set_value(k, v) }
|
98
|
+
end
|
22
99
|
|
23
100
|
payload['ret'] =
|
24
|
-
if tree[0] == 'setr' || @node['
|
25
|
-
|
101
|
+
if tree[0] == 'setr' || @node['refs'].last == 'f.ret'
|
102
|
+
ret
|
26
103
|
else
|
27
104
|
node_payload_ret
|
28
105
|
end
|
@@ -31,22 +108,3 @@ class Flor::Pro::Set < Flor::Procedure
|
|
31
108
|
end
|
32
109
|
end
|
33
110
|
|
34
|
-
# protected
|
35
|
-
#
|
36
|
-
# def splat(ks, vs)
|
37
|
-
#
|
38
|
-
# ks.inject(0) { |off, k|
|
39
|
-
# if k[0, 1] == '*'
|
40
|
-
# #p({ off: off, k: k, ks: ks[off + 1..-1], vs: vs[off..-1] })
|
41
|
-
# l = vs.length - ks.length + 1
|
42
|
-
# set_value(k[1..-1], vs[off, l])
|
43
|
-
# off + l
|
44
|
-
# else
|
45
|
-
# set_value(k, vs[off])
|
46
|
-
# off + 1
|
47
|
-
# end
|
48
|
-
# }
|
49
|
-
# end
|
50
|
-
#
|
51
|
-
# TODO need a splat a some point
|
52
|
-
|
data/lib/flor/unit/hook.rb
CHANGED
@@ -15,10 +15,17 @@ module Flor
|
|
15
15
|
opts = {}
|
16
16
|
opts[:consumed] = @h['consumed']
|
17
17
|
opts[:point] = Flor.h_fetch_a(@h, 'points', 'point', nil)
|
18
|
+
opts[:nid] = Flor.h_fetch_a(@h, 'nids', 'nid', nil)
|
18
19
|
opts[:heap] = Flor.h_fetch_a(@h, 'heaps', 'heap', nil)
|
19
20
|
opts[:heat] = Flor.h_fetch_a(@h, 'heats', 'heat', nil)
|
20
21
|
#opts[:name] = data['names']
|
21
22
|
|
23
|
+
#correct_points(opts)
|
24
|
+
#
|
25
|
+
# Necessary since "cancel" gets interpreted as
|
26
|
+
# [ '_proc', { 'proc' => 'cancel' }, @line ]
|
27
|
+
# ...
|
28
|
+
|
22
29
|
[ "hook#{object_id}", opts, self, nil ]
|
23
30
|
end
|
24
31
|
|
@@ -27,6 +34,27 @@ module Flor
|
|
27
34
|
|
28
35
|
@unit.runner.run(executor, @h, message)
|
29
36
|
end
|
37
|
+
|
38
|
+
# Avoid the proc/cancel problem upstreams in ConfExecutor, by ignoring
|
39
|
+
# non-core procedures, keeping this around for now
|
40
|
+
#
|
41
|
+
# protected
|
42
|
+
#
|
43
|
+
# def correct_points(opts)
|
44
|
+
#
|
45
|
+
# pts = opts[:point]; return unless pts
|
46
|
+
#
|
47
|
+
# opts[:point] =
|
48
|
+
# Flor.is_tree?(pts) ?
|
49
|
+
# correct_point(pts) :
|
50
|
+
# pts.collect { |pt| correct_point(pt) }
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# def correct_point(point)
|
54
|
+
#
|
55
|
+
# return point[1]['proc'] if point.is_a?(Array) && point[0] == '_proc'
|
56
|
+
# point
|
57
|
+
# end
|
30
58
|
end
|
31
59
|
end
|
32
60
|
|
data/lib/flor/unit/hooker.rb
CHANGED
@@ -102,6 +102,11 @@ module Flor
|
|
102
102
|
ps = o(opts, :point, :p, [])
|
103
103
|
return false if ps && ! ps.include?(message['point'])
|
104
104
|
|
105
|
+
if nid = o(opts, :nid)
|
106
|
+
return false \
|
107
|
+
unless nid.include?(message['nid'])
|
108
|
+
end
|
109
|
+
|
105
110
|
if exi = o(opts, :exid)
|
106
111
|
return false \
|
107
112
|
unless message['exid'] == exi
|
data/lib/flor/unit/loader.rb
CHANGED
@@ -94,6 +94,9 @@ module Flor
|
|
94
94
|
|
95
95
|
def hooks(domain, name=nil)
|
96
96
|
|
97
|
+
# NB: do not relativize path, because Ruby load path != cwd,
|
98
|
+
# stay absolute for `require` and `load`
|
99
|
+
|
97
100
|
Dir[File.join(@root, '**/*.json')]
|
98
101
|
.select { |f| f.index('/lib/hooks/') }
|
99
102
|
.collect { |pa| [ pa, expose_d(pa, {}) ] }
|
@@ -101,7 +104,7 @@ module Flor
|
|
101
104
|
.sort_by { |pa, d| d.count('.') }
|
102
105
|
.collect { |pa, d|
|
103
106
|
interpret(pa).each_with_index { |h, i|
|
104
|
-
h['_path'] =
|
107
|
+
h['_path'] = pa + ":#{i}" } }
|
105
108
|
.flatten(1)
|
106
109
|
end
|
107
110
|
|
data/lib/flor/unit/storage.rb
CHANGED
@@ -625,9 +625,11 @@ module Flor
|
|
625
625
|
}.compact
|
626
626
|
|
627
627
|
pointers +=
|
628
|
-
exe['tasks']
|
629
|
-
|
630
|
-
|
628
|
+
exe['tasks']
|
629
|
+
.reject { |_, v|
|
630
|
+
v['tasker'] == nil }
|
631
|
+
.collect { |nid, v|
|
632
|
+
[ dom, exid, nid, 'tasker', v['tasker'], v['name'], now, u ] }
|
631
633
|
|
632
634
|
cps = @db[:flor_pointers] # current pointers
|
633
635
|
.where(exid: exid)
|
data/lib/flor/unit/waiter.rb
CHANGED
@@ -5,12 +5,14 @@ module Flor
|
|
5
5
|
|
6
6
|
def initialize(exid, opts)
|
7
7
|
|
8
|
-
serie, timeout, repeat =
|
8
|
+
serie, timeout, on_timeout, repeat =
|
9
|
+
expand_args(opts)
|
9
10
|
|
10
11
|
@exid = exid
|
11
12
|
@original_serie = repeat ? Flor.dup(serie) : nil
|
12
13
|
@serie = serie
|
13
14
|
@timeout = timeout
|
15
|
+
@on_timeout = on_timeout
|
14
16
|
|
15
17
|
@queue = []
|
16
18
|
@mutex = Mutex.new
|
@@ -59,7 +61,11 @@ module Flor
|
|
59
61
|
@var.wait(@mutex, @timeout)
|
60
62
|
# will wait "in aeternum" if @timeout is nil
|
61
63
|
|
62
|
-
|
64
|
+
if @queue.empty?
|
65
|
+
fail RuntimeError.new(
|
66
|
+
"timeout for #{self.to_s}") if @on_timeout == 'fail'
|
67
|
+
return { 'exid' => @exid, 'timed_out' => @on_timeout }
|
68
|
+
end
|
63
69
|
end
|
64
70
|
|
65
71
|
#executor, message = @queue.shift
|
@@ -89,19 +95,23 @@ module Flor
|
|
89
95
|
owait = opts[:wait]
|
90
96
|
orepeat = opts[:repeat] || false
|
91
97
|
otimeout = opts[:timeout]
|
98
|
+
oontimeout = opts[:on_timeout] || opts[:ontimeout] || 'fail'
|
92
99
|
|
93
100
|
case owait
|
94
101
|
when true
|
95
102
|
[ [ [ nil, %w[ failed terminated ] ] ], # serie
|
96
103
|
otimeout,
|
104
|
+
oontimeout,
|
97
105
|
orepeat ]
|
98
106
|
when Numeric
|
99
107
|
[ [ [ nil, %w[ failed terminated ] ] ], # serie
|
100
108
|
owait, # timeout
|
109
|
+
oontimeout,
|
101
110
|
orepeat ]
|
102
111
|
when String, Array
|
103
112
|
[ parse_serie(owait), # serie
|
104
113
|
otimeout,
|
114
|
+
oontimeout,
|
105
115
|
orepeat ]
|
106
116
|
else
|
107
117
|
fail ArgumentError.new(
|
data/lib/flor/unit/wlist.rb
CHANGED
@@ -19,8 +19,8 @@ module Flor
|
|
19
19
|
@waiters = []
|
20
20
|
|
21
21
|
@unit.instance_eval do
|
22
|
-
def wait(exid, opts=true)
|
23
|
-
@hooker['wlist'].wait(exid, opts)
|
22
|
+
def wait(exid, opts=true, more=nil)
|
23
|
+
@hooker['wlist'].wait(exid, opts, more)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -46,7 +46,7 @@ module Flor
|
|
46
46
|
[] # no new messages
|
47
47
|
end
|
48
48
|
|
49
|
-
def wait(exid, opts)
|
49
|
+
def wait(exid, opts, more)
|
50
50
|
|
51
51
|
exid, opts =
|
52
52
|
if opts == true && exid == 'idle'
|
@@ -56,6 +56,7 @@ module Flor
|
|
56
56
|
else
|
57
57
|
[ exid, opts ]
|
58
58
|
end
|
59
|
+
opts.merge!(more) if more.is_a?(Hash)
|
59
60
|
|
60
61
|
opts[:timeout] =
|
61
62
|
nil if opts[:timeout] == true
|
data/match.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
```
|
3
|
+
match f.data
|
4
|
+
{ temperature: t }; register_temperature t
|
5
|
+
{ humidity: h }; register_humidity h
|
6
|
+
{ luminosity: l, period: 'am' }; register_morning_luminosity l
|
7
|
+
{ luminosity: l }; register_pm_luminosity l
|
8
|
+
```
|
9
|
+
|
10
|
+
or
|
11
|
+
|
12
|
+
```
|
13
|
+
cond
|
14
|
+
f.data.temperature; register_temperature f.data.temperature
|
15
|
+
f.data.humidity; register_humidity f.data.humidity
|
16
|
+
and \
|
17
|
+
luminosity
|
18
|
+
== period 'am'
|
19
|
+
register_morning_luminosity f.data.luminosity
|
20
|
+
f.data.luminosity; register_pm_luminosity f.data.luminosity
|
21
|
+
```
|
22
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: munemo
|
@@ -140,9 +140,14 @@ files:
|
|
140
140
|
- lib/flor/pcore/_att.rb
|
141
141
|
- lib/flor/pcore/_dump.rb
|
142
142
|
- lib/flor/pcore/_err.rb
|
143
|
-
- lib/flor/pcore/_happly.rb
|
144
143
|
- lib/flor/pcore/_obj.rb
|
144
|
+
- lib/flor/pcore/_pat_.rb
|
145
|
+
- lib/flor/pcore/_pat_arr.rb
|
146
|
+
- lib/flor/pcore/_pat_guard.rb
|
147
|
+
- lib/flor/pcore/_pat_obj.rb
|
148
|
+
- lib/flor/pcore/_pat_or.rb
|
145
149
|
- lib/flor/pcore/_skip.rb
|
150
|
+
- lib/flor/pcore/_val.rb
|
146
151
|
- lib/flor/pcore/apply.rb
|
147
152
|
- lib/flor/pcore/arith.rb
|
148
153
|
- lib/flor/pcore/break.rb
|
@@ -151,23 +156,28 @@ files:
|
|
151
156
|
- lib/flor/pcore/cond.rb
|
152
157
|
- lib/flor/pcore/cursor.rb
|
153
158
|
- lib/flor/pcore/define.rb
|
159
|
+
- lib/flor/pcore/do_return.rb
|
154
160
|
- lib/flor/pcore/echo.rb
|
155
161
|
- lib/flor/pcore/fail.rb
|
156
162
|
- lib/flor/pcore/if.rb
|
163
|
+
- lib/flor/pcore/length.rb
|
164
|
+
- lib/flor/pcore/logo.rb
|
157
165
|
- lib/flor/pcore/loop.rb
|
158
166
|
- lib/flor/pcore/map.rb
|
167
|
+
- lib/flor/pcore/match.rb
|
159
168
|
- lib/flor/pcore/matchr.rb
|
160
169
|
- lib/flor/pcore/move.rb
|
161
170
|
- lib/flor/pcore/noeval.rb
|
162
171
|
- lib/flor/pcore/noret.rb
|
172
|
+
- lib/flor/pcore/not.rb
|
163
173
|
- lib/flor/pcore/push.rb
|
164
174
|
- lib/flor/pcore/rand.rb
|
175
|
+
- lib/flor/pcore/range.rb
|
165
176
|
- lib/flor/pcore/sequence.rb
|
166
177
|
- lib/flor/pcore/set.rb
|
167
178
|
- lib/flor/pcore/stall.rb
|
168
179
|
- lib/flor/pcore/twig.rb
|
169
180
|
- lib/flor/pcore/until.rb
|
170
|
-
- lib/flor/pcore/val.rb
|
171
181
|
- lib/flor/punit/cancel.rb
|
172
182
|
- lib/flor/punit/cmap.rb
|
173
183
|
- lib/flor/punit/concurrence.rb
|
@@ -208,8 +218,8 @@ files:
|
|
208
218
|
- lib/flor.rb
|
209
219
|
- flor.gemspec
|
210
220
|
- LICENSE.txt
|
211
|
-
- t.txt
|
212
221
|
- CHANGELOG.md
|
222
|
+
- match.md
|
213
223
|
- README.md
|
214
224
|
homepage: http://github.com/floraison
|
215
225
|
licenses:
|
data/lib/flor/pcore/_happly.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
|
2
|
-
class Flor::Pro::Happly < Flor::Procedure
|
3
|
-
|
4
|
-
name '_happly'
|
5
|
-
|
6
|
-
def pre_execute
|
7
|
-
|
8
|
-
@node['atts'] = []
|
9
|
-
end
|
10
|
-
|
11
|
-
def execute
|
12
|
-
|
13
|
-
wrap(
|
14
|
-
'point' => 'execute',
|
15
|
-
'nid' => Flor.child_nid(nid, tree[1].size),
|
16
|
-
'tree' => tree[0])
|
17
|
-
end
|
18
|
-
|
19
|
-
def receive
|
20
|
-
|
21
|
-
fcid = Flor.child_id(message['from'])
|
22
|
-
|
23
|
-
return wrap_reply if @node['applied']
|
24
|
-
return super unless fcid == tree[1].size
|
25
|
-
|
26
|
-
ret = payload['ret']
|
27
|
-
|
28
|
-
@node['hret'] = payload['ret']
|
29
|
-
execute_child(0)
|
30
|
-
end
|
31
|
-
|
32
|
-
def receive_last
|
33
|
-
|
34
|
-
hret = @node['hret']
|
35
|
-
|
36
|
-
return wrap_reply('ret' => hret) unless Flor.is_func_tree?(hret)
|
37
|
-
|
38
|
-
args = @node['atts'].collect(&:last)
|
39
|
-
|
40
|
-
hret[1].merge!('head' => true, 'nid' => nid)
|
41
|
-
|
42
|
-
msgs = apply(hret, args, tree[2])
|
43
|
-
|
44
|
-
@node['applied'] = msgs.first['nid']
|
45
|
-
|
46
|
-
msgs
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|