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/CHANGELOG.md
CHANGED
data/lib/flor.rb
CHANGED
data/lib/flor/core.rb
CHANGED
@@ -44,6 +44,13 @@ module Flor
|
|
44
44
|
pl = opts[:payload] || opts[:fields] || {}
|
45
45
|
vs = opts[:variables] || opts[:vars] || {}
|
46
46
|
|
47
|
+
fail ArgumentError.new(
|
48
|
+
"given launch payload should be a Hash, but it's a #{pl.class}"
|
49
|
+
) unless pl.is_a?(Hash)
|
50
|
+
fail ArgumentError.new(
|
51
|
+
"given launch variables should come in a Hash, but it's a #{vs.class}"
|
52
|
+
) unless vs.is_a?(Hash)
|
53
|
+
|
47
54
|
msg =
|
48
55
|
{ 'point' => 'execute',
|
49
56
|
'exid' => exid,
|
data/lib/flor/core/executor.rb
CHANGED
@@ -182,18 +182,23 @@ module Flor
|
|
182
182
|
|
183
183
|
# "exceptions"
|
184
184
|
|
185
|
-
|
186
|
-
#
|
187
|
-
#
|
188
|
-
|
185
|
+
if heat == nil && tree[0].index('.') && tree[1].empty?
|
186
|
+
#
|
187
|
+
# a field reference that points to nothing returns null
|
188
|
+
|
189
|
+
node['heat0'] = '_nul'
|
190
|
+
node['heat'] = '_nul'
|
191
|
+
node['heap'] = '_nul'
|
192
|
+
|
193
|
+
elsif message['accept_symbol'] && heat == nil
|
189
194
|
#
|
190
195
|
# tag: et al
|
191
196
|
|
192
|
-
|
197
|
+
node['tree'] = message['tree'] = t = [ '_dqs', tree[0], tree[2] ]
|
193
198
|
|
194
|
-
node['heat0'] =
|
195
|
-
node['heat'] =
|
196
|
-
node['heap'] =
|
199
|
+
node['heat0'] = t[0]
|
200
|
+
node['heat'] = h = n.deref(t[0])
|
201
|
+
node['heap'] = n.reheap(t, h)
|
197
202
|
|
198
203
|
elsif heap == 'task' && heat[0] == '_task'
|
199
204
|
#
|
@@ -296,11 +301,41 @@ module Flor
|
|
296
301
|
@unit.archive_node(message['exid'], node)
|
297
302
|
# archiving is only active during testing
|
298
303
|
|
304
|
+
#update_parent_node_tree(node)
|
305
|
+
|
299
306
|
@execution['nodes'].delete(nid)
|
300
307
|
|
301
308
|
cancels
|
302
309
|
end
|
303
310
|
|
311
|
+
# This saves the modified trees in the parent when the node is removed
|
312
|
+
# it works ok except for 3 (2017-05-9) failing specs.
|
313
|
+
#
|
314
|
+
# Introducing 3 exceptions for this is not interesting.
|
315
|
+
#
|
316
|
+
# def update_parent_node_tree(node)
|
317
|
+
#
|
318
|
+
# t = node['tree']; return unless t
|
319
|
+
##return if t[0] == '_apply'
|
320
|
+
# pnode = @execution['nodes'][node['parent']]; return unless pnode
|
321
|
+
#
|
322
|
+
# pt =
|
323
|
+
# pnode['tree'] ||
|
324
|
+
# Flor::Node.new(self, pnode, nil).lookup_tree(pnode['nid'])
|
325
|
+
# cid =
|
326
|
+
# Flor.child_id(node['nid'])
|
327
|
+
#
|
328
|
+
# if cid == pt[1].size # head "exception"
|
329
|
+
# return if pt[0] == t
|
330
|
+
# pt[0] = t
|
331
|
+
# pnode['tree'] = pt
|
332
|
+
# return
|
333
|
+
# end
|
334
|
+
#
|
335
|
+
# pt[1][cid] = t
|
336
|
+
# pnode['tree'] = pt
|
337
|
+
# end
|
338
|
+
|
304
339
|
def leave_tags(message, node)
|
305
340
|
|
306
341
|
ts = node['tags']; return [] unless ts && ts.any?
|
data/lib/flor/core/node.rb
CHANGED
@@ -145,27 +145,25 @@ class Flor::Node
|
|
145
145
|
#
|
146
146
|
# that might be the way...
|
147
147
|
|
148
|
-
def lookup(name)
|
149
|
-
|
150
|
-
cat, mod,
|
151
|
-
key, pth =
|
152
|
-
|
153
|
-
val =
|
154
|
-
if [ cat, mod, key ] == [ 'v', '', 'node' ]
|
155
|
-
@node
|
156
|
-
elsif cat == 'v'
|
157
|
-
lookup_var(@node, mod, key)
|
158
|
-
elsif cat == 't'
|
159
|
-
lookup_tag(mod, key)
|
160
|
-
else
|
161
|
-
lookup_field(mod, key)
|
162
|
-
end
|
148
|
+
def lookup(name, silence_index_error=false)
|
149
|
+
|
150
|
+
cat, mod, key_and_path = key_split(name)
|
151
|
+
key, pth = key_and_path.split('.', 2)
|
163
152
|
|
164
|
-
if
|
165
|
-
|
153
|
+
if [ cat, mod, key ] == [ 'v', '', 'node' ]
|
154
|
+
lookup_in_node(pth)
|
155
|
+
elsif cat == 'v'
|
156
|
+
lookup_var(@node, mod, key, pth)
|
157
|
+
elsif cat == 't'
|
158
|
+
lookup_tag(mod, key)
|
166
159
|
else
|
167
|
-
|
160
|
+
lookup_field(mod, key_and_path)
|
168
161
|
end
|
162
|
+
|
163
|
+
rescue IndexError
|
164
|
+
|
165
|
+
raise unless silence_index_error
|
166
|
+
nil
|
169
167
|
end
|
170
168
|
|
171
169
|
class Expander < Flor::Dollar
|
@@ -178,7 +176,8 @@ class Flor::Node
|
|
178
176
|
return @node.exid if k == 'exid'
|
179
177
|
return Flor.tstamp if k == 'tstamp'
|
180
178
|
|
181
|
-
@node.lookup(k)
|
179
|
+
r = @node.lookup(k, true)
|
180
|
+
r.is_a?(Symbol) ? nil : r
|
182
181
|
end
|
183
182
|
end
|
184
183
|
|
@@ -202,10 +201,10 @@ class Flor::Node
|
|
202
201
|
|
203
202
|
ref =
|
204
203
|
case v[0]
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
204
|
+
when '_func' then true
|
205
|
+
when '_proc' then v[1]['proc'] != o
|
206
|
+
when '_task' then v[1]['task'] != o
|
207
|
+
else false
|
209
208
|
end
|
210
209
|
|
211
210
|
v[1]['oref'] ||= v[1]['ref'] if ref && v[1]['ref']
|
@@ -226,8 +225,6 @@ class Flor::Node
|
|
226
225
|
'apply'
|
227
226
|
elsif heat[0] == '_task'
|
228
227
|
'task'
|
229
|
-
elsif Flor.is_tree_head_tree?(tree)
|
230
|
-
'_happly'
|
231
228
|
else
|
232
229
|
'_val'
|
233
230
|
end
|
@@ -317,54 +314,86 @@ class Flor::Node
|
|
317
314
|
# @execution['nodes'][node['cnid']]
|
318
315
|
#end
|
319
316
|
|
320
|
-
def
|
317
|
+
def lookup_in_node(pth)
|
321
318
|
|
322
|
-
|
323
|
-
|
324
|
-
end
|
319
|
+
Flor.deep_get(@node, pth)
|
320
|
+
end
|
325
321
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
end
|
322
|
+
class PseudoVarContainer < Hash
|
323
|
+
#
|
324
|
+
# inherit from Hash so that deep.rb is quietly mislead
|
325
|
+
#
|
326
|
+
def initialize(type); @type = type; end
|
327
|
+
#def has_key?(key); true; end
|
328
|
+
def [](key); [ "_#{@type}", { @type => key }, -1 ]; end
|
329
|
+
end
|
330
|
+
#
|
331
|
+
PROC_VAR_CONTAINER = PseudoVarContainer.new('proc')
|
332
|
+
TASKER_VAR_CONTAINER = PseudoVarContainer.new('task')
|
333
333
|
|
334
|
-
|
335
|
-
return [ '_task', { 'task' => key }, -1 ]
|
336
|
-
end
|
334
|
+
def lookup_var(node, mod, key, pth)
|
337
335
|
|
338
|
-
|
336
|
+
c = lookup_var_container(node, mod, key)
|
337
|
+
|
338
|
+
kp = [ key, pth ].reject { |x| x == nil || x.size < 1 }.join('.')
|
339
|
+
|
340
|
+
v = Flor.deep_get(c, kp)
|
341
|
+
#p [ mod, key, pth, '->', v ]
|
342
|
+
|
343
|
+
return v unless v.is_a?(Symbol)
|
344
|
+
|
345
|
+
vs = v.to_s.split('.')
|
346
|
+
tail = vs.pop
|
347
|
+
vs = vs.join('.')
|
348
|
+
|
349
|
+
fail IndexError.new("variable #{tail.inspect} not found") if vs.empty?
|
350
|
+
fail IndexError.new("no key #{tail.inspect} in variable #{vs.inspect}")
|
339
351
|
end
|
340
352
|
|
341
|
-
def
|
353
|
+
def lookup_var_container(node, mod, key)
|
342
354
|
|
343
|
-
return
|
355
|
+
return lookup_dvar_container(mod, key) if node == nil || mod == 'd'
|
344
356
|
|
345
357
|
pnode = parent_node(node)
|
346
|
-
|
358
|
+
vars = node['vars']
|
347
359
|
|
348
360
|
if mod == 'g'
|
349
|
-
|
350
|
-
return
|
351
|
-
return vars[key] if vars
|
352
|
-
#return lookup_var(cnode, mod, key) if cnode
|
361
|
+
return lookup_var_container(pnode, mod, key) if pnode
|
362
|
+
return vars if vars
|
353
363
|
fail "node #{node['nid']} has no vars and no parent"
|
354
364
|
end
|
355
365
|
|
356
|
-
vars
|
357
|
-
|
358
|
-
return vars[key] if vars && vars.has_key?(key)
|
366
|
+
return vars if vars && vars.has_key?(key)
|
359
367
|
|
360
368
|
if cnid = node['cnid']
|
361
369
|
cvars = (@execution['nodes'][cnid] || {})['vars']
|
362
|
-
return cvars
|
370
|
+
return cvars if cvars && cvars.has_key?(key)
|
363
371
|
end
|
364
372
|
#
|
365
373
|
# look into closure, just one level deep...
|
366
374
|
|
367
|
-
|
375
|
+
lookup_var_container(pnode, mod, key)
|
376
|
+
end
|
377
|
+
|
378
|
+
def lookup_dvar_container(mod, key)
|
379
|
+
|
380
|
+
if mod != 'd' && Flor::Procedure[key]
|
381
|
+
return PROC_VAR_CONTAINER
|
382
|
+
end
|
383
|
+
|
384
|
+
l = @executor.unit.loader
|
385
|
+
vdomain = @node['vdomain']
|
386
|
+
#
|
387
|
+
if l && vdomain != false
|
388
|
+
vars = l.variables(vdomain || domain)
|
389
|
+
return vars if vars.has_key?(key)
|
390
|
+
end
|
391
|
+
|
392
|
+
if mod != 'd' && @executor.unit.has_tasker?(@executor.exid, key)
|
393
|
+
return TASKER_VAR_CONTAINER
|
394
|
+
end
|
395
|
+
|
396
|
+
{}
|
368
397
|
end
|
369
398
|
|
370
399
|
def lookup_var_name(node, val)
|
@@ -389,9 +418,10 @@ class Flor::Node
|
|
389
418
|
nids.empty? ? [ '_nul', nil, -1 ] : nids
|
390
419
|
end
|
391
420
|
|
392
|
-
def lookup_field(mod,
|
421
|
+
def lookup_field(mod, key_and_path)
|
393
422
|
|
394
|
-
Flor.deep_get(payload.current,
|
423
|
+
r = Flor.deep_get(payload.current, key_and_path)
|
424
|
+
r.is_a?(Symbol) ? nil : r
|
395
425
|
end
|
396
426
|
|
397
427
|
def key_split(key) # => category, mode, key
|
data/lib/flor/core/procedure.rb
CHANGED
@@ -17,12 +17,15 @@ class Flor::Procedure < Flor::Node
|
|
17
17
|
|
18
18
|
names = names.flatten
|
19
19
|
@names = names if names.any?
|
20
|
+
@core = !! caller.find { |l| l.match(/flor\/pcore/) } if names.any?
|
20
21
|
|
21
22
|
@names
|
22
23
|
end
|
23
24
|
|
24
25
|
alias :name :names
|
25
26
|
|
27
|
+
def core?; @core; end
|
28
|
+
|
26
29
|
def make(executor, node, message)
|
27
30
|
|
28
31
|
heap = node['heat'] ? node['heap'] : nil
|
@@ -234,9 +237,9 @@ class Flor::Procedure < Flor::Node
|
|
234
237
|
unatt_unkeyed_children(true)
|
235
238
|
end
|
236
239
|
|
237
|
-
def
|
240
|
+
def stringify_child(non_att_index)
|
238
241
|
|
239
|
-
c = non_att_children
|
242
|
+
c = non_att_children[non_att_index]
|
240
243
|
return unless c
|
241
244
|
return unless c[1] == [] && c[0].is_a?(String)
|
242
245
|
|
@@ -247,6 +250,11 @@ class Flor::Procedure < Flor::Node
|
|
247
250
|
@node['tree'] = [ tree[0], cn, tree[2] ]
|
248
251
|
end
|
249
252
|
|
253
|
+
def stringify_first_child
|
254
|
+
|
255
|
+
stringify_child(0)
|
256
|
+
end
|
257
|
+
|
250
258
|
def do_execute
|
251
259
|
|
252
260
|
pre_execute
|
@@ -321,31 +329,37 @@ class Flor::Procedure < Flor::Node
|
|
321
329
|
[]
|
322
330
|
end
|
323
331
|
|
324
|
-
def
|
332
|
+
def determine_fcid_and_ncid
|
325
333
|
|
326
334
|
@fcid = point == 'receive' ? Flor.child_id(from) : nil
|
327
335
|
@ncid = (@fcid || -1) + 1
|
336
|
+
end
|
328
337
|
|
329
|
-
|
338
|
+
def from_att?
|
339
|
+
|
340
|
+
@fcid && (c = children[@fcid]) && c[0] == '_att'
|
341
|
+
end
|
330
342
|
|
331
|
-
|
343
|
+
def receive
|
332
344
|
|
333
|
-
|
345
|
+
determine_fcid_and_ncid
|
334
346
|
|
347
|
+
return receive_first if @fcid == nil
|
348
|
+
return receive_att if from_att?
|
335
349
|
receive_non_att
|
336
350
|
end
|
337
351
|
|
338
352
|
def receive_first
|
339
353
|
|
340
|
-
return receive_last_att if children[0] &&
|
354
|
+
return receive_last_att if (c = children[0]) && c[0] != '_att'
|
341
355
|
execute_child(@ncid)
|
342
356
|
end
|
343
357
|
|
344
358
|
def receive_att
|
345
359
|
|
346
|
-
|
360
|
+
nt = children[@ncid]
|
347
361
|
|
348
|
-
return receive_last_att if
|
362
|
+
return receive_last_att if nt == nil || nt[0] != '_att'
|
349
363
|
execute_child(@ncid)
|
350
364
|
end
|
351
365
|
|
@@ -477,9 +491,9 @@ class Flor::Procedure < Flor::Node
|
|
477
491
|
|
478
492
|
if node
|
479
493
|
|
480
|
-
|
494
|
+
v = Flor.deep_set(node['vars'], k, v)
|
481
495
|
|
482
|
-
return v
|
496
|
+
return v unless v.is_a?(Symbol)
|
483
497
|
end
|
484
498
|
|
485
499
|
fail IndexError.new("couldn't set var #{mode}v.#{k}")
|
@@ -487,9 +501,9 @@ class Flor::Procedure < Flor::Node
|
|
487
501
|
|
488
502
|
def set_field(k, v)
|
489
503
|
|
490
|
-
|
504
|
+
value = Flor.deep_set(payload.copy, k, v)
|
491
505
|
|
492
|
-
fail IndexError.new("couldn't set field #{k}")
|
506
|
+
fail IndexError.new("couldn't set field #{k}") if value.is_a?(Symbol)
|
493
507
|
|
494
508
|
value
|
495
509
|
end
|
@@ -501,10 +515,10 @@ class Flor::Procedure < Flor::Node
|
|
501
515
|
cat, mod, key = key_split(k)
|
502
516
|
|
503
517
|
case cat[0, 1]
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
518
|
+
when 'f' then set_field(key, v)
|
519
|
+
when 'v' then set_var(mod, key, v)
|
520
|
+
#when 'w' then set_war(key, v)
|
521
|
+
else fail IndexError.new("don't know how to set #{k.inspect}")
|
508
522
|
end
|
509
523
|
end
|
510
524
|
|
@@ -516,10 +530,12 @@ class Flor::Procedure < Flor::Node
|
|
516
530
|
|
517
531
|
cni = fun[1]['cnid'] # closure nid
|
518
532
|
|
519
|
-
t =
|
533
|
+
t = fun[1]['tree']
|
534
|
+
t = t || lookup_tree(fni) # TODO when fun[1]['tree'] is settled, drop me
|
520
535
|
fail ArgumentError.new("couldn't find function at #{fni}") unless t
|
521
536
|
|
522
|
-
t = t[0] if
|
537
|
+
t = t[0] if t[0].is_a?(Array)
|
538
|
+
t = t[1][0] if t[0] == '_att'
|
523
539
|
|
524
540
|
sig = t[1].select { |c| c[0] == '_att' }
|
525
541
|
sig = sig.drop(1) if t[0] == 'define'
|
@@ -629,6 +645,7 @@ class Flor::Macro < Flor::Procedure
|
|
629
645
|
def rewrite
|
630
646
|
|
631
647
|
t = rewrite_tree
|
648
|
+
#Flor.print_tree(t, nid)
|
632
649
|
|
633
650
|
m = @message.dup
|
634
651
|
m['tree'] = t
|