flor 0.0.1 → 0.9.0

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 (84) hide show
  1. data/CHANGELOG.md +13 -0
  2. data/LICENSE.txt +1 -1
  3. data/Makefile +66 -0
  4. data/README.md +57 -0
  5. data/fail.txt +7 -0
  6. data/flor.gemspec +12 -9
  7. data/intercepted.txt +123 -0
  8. data/lib/flor/colours.rb +140 -0
  9. data/lib/flor/conf.rb +88 -0
  10. data/lib/flor/core/executor.rb +473 -0
  11. data/lib/flor/core/node.rb +397 -0
  12. data/lib/flor/core/procedure.rb +600 -0
  13. data/lib/flor/core/texecutor.rb +209 -0
  14. data/lib/flor/core.rb +93 -0
  15. data/lib/flor/dollar.rb +248 -0
  16. data/lib/flor/errors.rb +36 -0
  17. data/lib/flor/flor.rb +556 -0
  18. data/lib/flor/log.rb +336 -0
  19. data/lib/flor/migrations/0001_tables.rb +122 -0
  20. data/lib/flor/parser.rb +414 -0
  21. data/lib/flor/pcore/_arr.rb +49 -0
  22. data/lib/flor/pcore/_atom.rb +43 -0
  23. data/lib/flor/pcore/_att.rb +160 -0
  24. data/lib/flor/pcore/_dump.rb +60 -0
  25. data/lib/flor/pcore/_err.rb +30 -0
  26. data/lib/flor/pcore/_happly.rb +73 -0
  27. data/lib/flor/pcore/_obj.rb +65 -0
  28. data/lib/flor/pcore/_skip.rb +63 -0
  29. data/lib/flor/pcore/apply.rb +60 -0
  30. data/lib/flor/pcore/arith.rb +46 -0
  31. data/lib/flor/pcore/break.rb +71 -0
  32. data/lib/flor/pcore/cmp.rb +72 -0
  33. data/lib/flor/pcore/cond.rb +57 -0
  34. data/lib/flor/pcore/cursor.rb +223 -0
  35. data/lib/flor/pcore/define.rb +96 -0
  36. data/lib/flor/pcore/fail.rb +45 -0
  37. data/lib/flor/pcore/ife.rb +56 -0
  38. data/lib/flor/pcore/loop.rb +53 -0
  39. data/lib/flor/pcore/map.rb +75 -0
  40. data/lib/flor/pcore/match.rb +70 -0
  41. data/lib/flor/pcore/move.rb +65 -0
  42. data/lib/flor/pcore/noeval.rb +46 -0
  43. data/lib/flor/pcore/noret.rb +47 -0
  44. data/lib/flor/pcore/push.rb +69 -0
  45. data/lib/flor/pcore/sequence.rb +39 -0
  46. data/lib/flor/pcore/set.rb +76 -0
  47. data/lib/flor/pcore/stall.rb +35 -0
  48. data/lib/flor/pcore/until.rb +122 -0
  49. data/lib/flor/pcore/val.rb +40 -0
  50. data/lib/flor/punit/cancel.rb +69 -0
  51. data/lib/flor/punit/cmap.rb +76 -0
  52. data/lib/flor/punit/concurrence.rb +149 -0
  53. data/lib/flor/punit/every.rb +46 -0
  54. data/lib/flor/punit/on.rb +81 -0
  55. data/lib/flor/punit/schedule.rb +68 -0
  56. data/lib/flor/punit/signal.rb +47 -0
  57. data/lib/flor/punit/sleep.rb +53 -0
  58. data/lib/flor/punit/task.rb +109 -0
  59. data/lib/flor/punit/trace.rb +51 -0
  60. data/lib/flor/punit/trap.rb +100 -0
  61. data/lib/flor/to_string.rb +81 -0
  62. data/lib/flor/tools/env.rb +103 -0
  63. data/lib/flor/tools/repl.rb +231 -0
  64. data/lib/flor/unit/executor.rb +260 -0
  65. data/lib/flor/unit/hooker.rb +186 -0
  66. data/lib/flor/unit/journal.rb +52 -0
  67. data/lib/flor/unit/loader.rb +181 -0
  68. data/lib/flor/unit/logger.rb +181 -0
  69. data/lib/flor/unit/models/execution.rb +105 -0
  70. data/lib/flor/unit/models/pointer.rb +31 -0
  71. data/lib/flor/unit/models/timer.rb +52 -0
  72. data/lib/flor/unit/models/trace.rb +31 -0
  73. data/lib/flor/unit/models/trap.rb +130 -0
  74. data/lib/flor/unit/models.rb +106 -0
  75. data/lib/flor/unit/scheduler.rb +419 -0
  76. data/lib/flor/unit/storage.rb +633 -0
  77. data/lib/flor/unit/tasker.rb +191 -0
  78. data/lib/flor/unit/waiter.rb +146 -0
  79. data/lib/flor/unit/wlist.rb +77 -0
  80. data/lib/flor/unit.rb +50 -0
  81. data/lib/flor.rb +40 -3
  82. metadata +152 -22
  83. checksums.yaml +0 -7
  84. data/Rakefile +0 -52
@@ -0,0 +1,414 @@
1
+ #--
2
+ # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Flor
27
+
28
+ module Lang include Raabro
29
+
30
+ # parsing
31
+
32
+ def null(i); str(:null, i, 'null'); end
33
+ def number(i); rex(:number, i, /-?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?/); end
34
+
35
+ def tru(i); str(nil, i, 'true'); end
36
+ def fls(i); str(nil, i, 'false'); end
37
+ def boolean(i); alt(:boolean, i, :tru, :fls); end
38
+
39
+ def dqstring(i)
40
+
41
+ rex(:dqstring, i, %r{
42
+ "(
43
+ \\["bfnrt] |
44
+ \\u[0-9a-fA-F]{4} |
45
+ [^"\\\b\f\n\r\t]
46
+ )*"
47
+ }x)
48
+ end
49
+
50
+ def sqstring(i)
51
+
52
+ rex(:sqstring, i, %r{
53
+ '(
54
+ \\['bfnrt] |
55
+ \\u[0-9a-fA-F]{4} |
56
+ [^'\\\b\f\n\r\t]
57
+ )*'
58
+ }x)
59
+ end
60
+
61
+ def rxstring(i)
62
+
63
+ rex(:rxstring, i, %r{
64
+ /(
65
+ \\[\/bfnrt] |
66
+ \\u[0-9a-fA-F]{4} |
67
+ [^/\b\f\n\r\t]
68
+ )*/[a-z]*
69
+ }x)
70
+ end
71
+
72
+ def symbol(i); rex(:symbol, i, /[^:;| \b\f\n\r\t"',()\[\]{}#\\]+/); end
73
+
74
+ def comment(i); rex(nil, i, /#[^\r\n]*/); end
75
+
76
+ def ws_star(i); rex(nil, i, /[ \t]*/); end
77
+ def retnew(i); rex(nil, i, /[\r\n]*/); end
78
+ def colon(i); str(nil, i, ':'); end
79
+ def comma(i); str(nil, i, ','); end
80
+ def bslash(i); str(nil, i, '\\'); end
81
+
82
+ def pstart(i); str(nil, i, '('); end
83
+ def pend(i); str(nil, i, ')'); end
84
+ def sbstart(i); str(nil, i, '['); end
85
+ def sbend(i); str(nil, i, ']'); end
86
+ def pbstart(i); str(nil, i, '{'); end
87
+ def pbend(i); str(nil, i, '}'); end
88
+
89
+ def eol(i); seq(nil, i, :ws_star, :comment, '?', :retnew); end
90
+ def postval(i); rep(nil, i, :eol, 0); end
91
+
92
+ def comma_eol(i); seq(nil, i, :comma, :eol, :ws_star); end
93
+ def bslash_eol(i); seq(nil, i, :bslash, :eol, :ws_star); end
94
+ def sep(i); alt(nil, i, :comma_eol, :bslash_eol, :ws_star); end
95
+
96
+ def comma_qmark_eol(i); seq(nil, i, :comma, '?', :eol); end
97
+ def coll_sep(i); alt(nil, i, :bslash_eol, :comma_qmark_eol, :ws_star); end
98
+
99
+ def ent(i); seq(:ent, i, :key, :postval, :colon, :postval, :exp, :postval); end
100
+ def ent_qmark(i); rep(nil, i, :ent, 0, 1); end
101
+
102
+ def exp_qmark(i); rep(nil, i, :exp, 0, 1); end
103
+
104
+ def obj(i); eseq(:obj, i, :pbstart, :ent_qmark, :coll_sep, :pbend); end
105
+ def arr(i); eseq(:arr, i, :sbstart, :exp_qmark, :coll_sep, :sbend); end
106
+
107
+ def par(i); seq(:par, i, :pstart, :eol, :ws_star, :node, :eol, :pend); end
108
+
109
+ def val(i)
110
+ altg(:val, i,
111
+ :panode, :par,
112
+ :symbol, :sqstring, :dqstring, :rxstring,
113
+ :arr, :obj,
114
+ :number, :boolean, :null)
115
+ end
116
+ def val_ws(i); seq(nil, i, :val, :ws_star); end
117
+
118
+ # precedence
119
+ # %w[ or or ], %w[ and and ],
120
+ # %w[ equ == != <> ], %w[ lgt < > <= >= ], %w[ sum + - ], %w[ prd * / % ],
121
+
122
+ def ssprd(i); rex(:sop, i, /[\*\/%]/); end
123
+ def sssum(i); rex(:sop, i, /[+-]/); end
124
+ def sslgt(i); rex(:sop, i, /(<=?|>=?)/); end
125
+ def ssequ(i); rex(:sop, i, /(==?|!=|<>)/); end
126
+ def ssand(i); str(:sop, i, 'and'); end
127
+ def ssor(i); str(:sop, i, 'or'); end
128
+
129
+ def sprd(i); seq(nil, i, :ssprd, :eol, '?'); end
130
+ def ssum(i); seq(nil, i, :sssum, :eol, '?'); end
131
+ def slgt(i); seq(nil, i, :sslgt, :eol, '?'); end
132
+ def sequ(i); seq(nil, i, :ssequ, :eol, '?'); end
133
+ def sand(i); seq(nil, i, :ssand, :eol, '?'); end
134
+ def sor(i); seq(nil, i, :ssor, :eol, '?'); end
135
+
136
+ def eprd(i); jseq(:exp, i, :val_ws, :sprd); end
137
+ def esum(i); jseq(:exp, i, :eprd, :ssum); end
138
+ def elgt(i); jseq(:exp, i, :esum, :slgt); end
139
+ def eequ(i); jseq(:exp, i, :elgt, :sequ); end
140
+ def eand(i); jseq(:exp, i, :eequ, :sand); end
141
+ def eor(i); jseq(:exp, i, :eand, :sor); end
142
+
143
+ alias exp eor
144
+
145
+ def key(i); seq(:key, i, :exp); end
146
+ def keycol(i); seq(nil, i, :key, :ws_star, :colon, :eol); end
147
+
148
+ def att(i); seq(:att, i, :sep, :keycol, '?', :exp); end
149
+ def head(i); seq(:head, i, :exp); end
150
+ def indent(i); rex(:indent, i, /[|; \t]*/); end
151
+ def node(i); seq(:node, i, :indent, :head, :att, '*'); end
152
+
153
+ def line(i)
154
+ seq(:line, i, :node, '?', :eol)
155
+ end
156
+ def panode(i)
157
+ seq(:panode, i, :pstart, :eol, :ws_star, :line, '*', :eol, :pend)
158
+ end
159
+
160
+ def flor(i); rep(:flor, i, :line, 0); end
161
+
162
+ # rewriting
163
+
164
+ def line_number(t)
165
+
166
+ t.input.string[0..t.offset].scan("\n").count + 1
167
+ end
168
+ alias ln line_number
169
+
170
+ def rewrite_par(t)
171
+
172
+ Nod.new(t.lookup(:node)).to_a
173
+ end
174
+
175
+ def rewrite_symbol(t); [ t.string, [], ln(t) ]; end
176
+
177
+ def rewrite_sqstring(t); [ '_sqs', t.string[1..-2], ln(t) ]; end
178
+ def rewrite_dqstring(t); [ '_dqs', t.string[1..-2], ln(t) ]; end
179
+ def rewrite_rxstring(t); [ '_rxs', t.string, ln(t) ]; end
180
+
181
+ def rewrite_boolean(t); [ '_boo', t.string == 'true', line_number(t) ]; end
182
+ def rewrite_null(t); [ '_nul', nil, line_number(t) ]; end
183
+
184
+ def rewrite_number(t)
185
+
186
+ s = t.string; [ '_num', s.index('.') ? s.to_f : s.to_i, ln(t) ]
187
+ end
188
+
189
+ def rewrite_obj(t)
190
+
191
+ cn =
192
+ t.subgather(nil).inject([]) do |a, tt|
193
+ a << rewrite(tt.c0.c0)
194
+ a << rewrite(tt.c4)
195
+ end
196
+ cn = 0 if cn.empty?
197
+
198
+ [ '_obj', cn, ln(t) ]
199
+ end
200
+
201
+ def rewrite_arr(t)
202
+
203
+ cn = t.subgather(nil).collect { |n| rewrite(n) }
204
+ cn = 0 if cn.empty?
205
+
206
+ [ '_arr', cn, ln(t) ]
207
+ end
208
+
209
+ def rewrite_val(t)
210
+
211
+ rewrite(t.c0)
212
+ end
213
+
214
+ def rewrite_exp(t)
215
+
216
+ return rewrite(t.c0) if t.children.size == 1
217
+
218
+ cn = [ rewrite(t.c0) ]
219
+ op = t.lookup(:sop).string
220
+
221
+ tcn = t.children[2..-1].dup
222
+
223
+ loop do
224
+ c = tcn.shift; break unless c
225
+ cn << rewrite(c)
226
+ o = tcn.shift; break unless o
227
+ o = o.lookup(:sop).string
228
+ next if o == op
229
+ cn = [ [ op, cn, cn.first[2] ] ]
230
+ op = o
231
+ end
232
+
233
+ if op == '-' && cn.all? { |c| c[0] == '_num' }
234
+ op = '+'
235
+ cn[1..-1].each { |c| c[1] = -c[1] }
236
+ end
237
+
238
+ [ op, cn, cn.first[2] ]
239
+ end
240
+
241
+ class Nod
242
+
243
+ attr_accessor :parent, :indent
244
+ attr_reader :children
245
+
246
+ def initialize(tree)
247
+
248
+ @parent = nil
249
+ @indent = -1
250
+ @head = 'sequence'
251
+ @children = []
252
+ @line = 0
253
+
254
+ read(tree) if tree
255
+ end
256
+
257
+ def append(node)
258
+
259
+ if node.indent == :east
260
+ node.indent = self.indent + 2
261
+ elsif node.indent == :south
262
+ node.indent = self.indent
263
+ end
264
+
265
+ if node.indent > self.indent
266
+ @children << node
267
+ node.parent = self
268
+ else
269
+ @parent.append(node)
270
+ end
271
+ end
272
+
273
+ def to_a
274
+
275
+ return @head if @head.is_a?(Array) && @children.empty?
276
+
277
+ cn = @children.collect(&:to_a)
278
+
279
+ # detect if/unless suffix
280
+
281
+ atts =
282
+ cn.inject([]) { |a, c| a << c[1] if c[0] == '_att'; a }
283
+ i =
284
+ atts.index { |c|
285
+ c.size == 1 && %w[ if unless ].include?(c[0][0]) && c[0][1] == []
286
+ }
287
+
288
+ #return cn.first if @head == 'sequence' && @line == 0 && cn.size == 1
289
+ return [ @head, cn, @line ] unless i
290
+
291
+ # rewrite if/unless suffix
292
+
293
+ t = [ atts[i][0][0] == 'if' ? 'ife' : 'unlesse', [], @line ]
294
+ t[1].concat(atts[i + 1..-1].collect(&:first))
295
+ t[1].push([ @head, cn[0, i], @line ])
296
+
297
+ t
298
+ end
299
+
300
+ protected
301
+
302
+ def read(tree)
303
+
304
+ if it = tree.lookup(:indent)
305
+
306
+ s = it.string
307
+ semicount = s.count(';')
308
+ pipe = s.index('|')
309
+
310
+ @indent =
311
+ if semicount == 1 then :east
312
+ elsif semicount > 1 || pipe then :south
313
+ else s.length; end
314
+ end
315
+
316
+ ht = tree.lookup(:head)
317
+ @line = Lang.line_number(ht)
318
+
319
+ @head = Flor::Lang.rewrite(ht.c0)
320
+ @head = @head[0] if @head[0].is_a?(String) && @head[1] == []
321
+
322
+ atts =
323
+ tree.children[2..-1].inject([]) do |as, ct|
324
+
325
+ kt = ct.children.size == 3 ? ct.children[1].lookup(:key) : nil
326
+ v = Flor::Lang.rewrite(ct.clast)
327
+
328
+ if kt
329
+ k = Flor::Lang.rewrite(kt.c0)
330
+ as << [ '_att', [ k, v ], k[2] ]
331
+ elsif %w[ - + ].include?(@head) && v[0, 2] != [ '_', [] ]
332
+ if v[0] == '+'
333
+ as.concat(v[1])
334
+ else
335
+ as << v
336
+ end
337
+ else
338
+ as << [ '_att', [ v ], v[2] ]
339
+ end
340
+
341
+ as
342
+ end
343
+
344
+ @children.concat(atts)
345
+ end
346
+ end
347
+
348
+ def rewrite_flor(t)
349
+
350
+ prev = root = Nod.new(nil)
351
+
352
+ t.gather(:node).each do |nt|
353
+ n = Nod.new(nt)
354
+ prev.append(n)
355
+ prev = n
356
+ end
357
+
358
+ root.children.count == 1 ? root.children.first.to_a : root.to_a
359
+ end
360
+ alias rewrite_panode rewrite_flor
361
+
362
+ def parse(input, fname=nil, opts={})
363
+
364
+ opts = fname if fname.is_a?(Hash) && opts.empty?
365
+
366
+ #Raabro.pp(super(input, debug: 2))
367
+ #Raabro.pp(super(input, debug: 3))
368
+
369
+ r = super(input, opts)
370
+ r << fname if fname
371
+
372
+ r
373
+ end
374
+ end # module Lang
375
+
376
+ def self.unescape_u(cs)
377
+
378
+ s = ''; 4.times { s << cs.next }
379
+
380
+ [ s.to_i(16) ].pack('U*')
381
+ end
382
+
383
+ def self.unescape(s)
384
+
385
+ sio = StringIO.new
386
+
387
+ cs = s.each_char
388
+
389
+ loop do
390
+
391
+ c = cs.next
392
+
393
+ break unless c
394
+
395
+ if c == '\\'
396
+ case cn = cs.next
397
+ when 'u' then sio.print(unescape_u(cs))
398
+ when '\\', '"', '\'' then sio.print(cn)
399
+ when 'b' then sio.print("\b")
400
+ when 'f' then sio.print("\f")
401
+ when 'n' then sio.print("\n")
402
+ when 'r' then sio.print("\r")
403
+ when 't' then sio.print("\t")
404
+ else sio.print("\\#{cn}")
405
+ end
406
+ else
407
+ sio.print(c)
408
+ end
409
+ end
410
+
411
+ sio.string
412
+ end
413
+ end
414
+
@@ -0,0 +1,49 @@
1
+ #--
2
+ # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ class Flor::Pro::Arr < Flor::Procedure
27
+
28
+ name '_arr'
29
+
30
+ def pre_execute
31
+
32
+ @node['rets'] = []
33
+ end
34
+
35
+ def receive
36
+
37
+ return reply('ret' => []) if children == 0
38
+
39
+ super
40
+ end
41
+
42
+ def receive_last
43
+
44
+ payload['ret'] = @node['rets']
45
+
46
+ reply
47
+ end
48
+ end
49
+
@@ -0,0 +1,43 @@
1
+ #--
2
+ # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ class Flor::Pro::Atom < Flor::Procedure
27
+
28
+ names %w[ _num _boo _sqs _dqs _rxs _nul _func ]
29
+
30
+ def execute
31
+
32
+ payload['ret'] =
33
+ case tree[0]
34
+ when '_dqs' then expand(tree[1])
35
+ when '_rxs' then [ tree[0], expand(tree[1]), *tree[2..-1] ]
36
+ when '_func' then tree
37
+ else tree[1]
38
+ end
39
+
40
+ reply
41
+ end
42
+ end
43
+
@@ -0,0 +1,160 @@
1
+ #--
2
+ # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ class Flor::Pro::Att < Flor::Procedure
27
+
28
+ name '_att'
29
+
30
+ def execute
31
+
32
+ return reply if children == [ [ '_', [], tree[2] ] ]
33
+ # spares 1 message
34
+
35
+ pt = parent_node['tree']
36
+ return reply if pt && pt[0] == '_apply'
37
+
38
+ execute_child(0, nil, 'accept_symbol' => children.size > 1)
39
+ end
40
+
41
+ def receive
42
+
43
+ if children.size < 2
44
+ receive_unkeyed
45
+ else
46
+ receive_keyed
47
+ end
48
+ end
49
+
50
+ protected
51
+
52
+ def receive_unkeyed
53
+
54
+ receive_att(nil)
55
+ end
56
+
57
+ def receive_keyed
58
+
59
+ if Flor.child_id(@message['from']) == 0
60
+ @node['key'] = k = payload['ret']
61
+ as = (parent_node || {})['atts_accepting_symbols'] || []
62
+ execute_child(1, nil, 'accept_symbol' => as.include?(k))
63
+ else
64
+ k = @node['key']
65
+ m = "receive_#{k}"
66
+ respond_to?(m, true) ? send(m) : receive_att(k)
67
+ end
68
+ end
69
+
70
+ def unref(k, flavour=:key)
71
+
72
+ #return lookup_var_name(@node, k) if Flor.is_func_tree?(k)
73
+ # old style
74
+
75
+ return k unless Flor.is_tree?(k)
76
+ return k unless k[1].is_a?(Hash)
77
+ return k unless %w[ _proc _task _func ].include?(k[0])
78
+
79
+ (flavour == :key ? nil : k[1]['oref']) ||
80
+ k[1]['ref'] ||
81
+ k[1]['proc'] || k[1]['task']
82
+ end
83
+
84
+ def receive_att(key)
85
+
86
+ if parent_node['atts']
87
+ parent_node['atts'] << [ unref(key), payload['ret'] ]
88
+ parent_node['mtime'] = Flor.tstamp
89
+ elsif key == nil && parent_node['rets']
90
+ parent_node['rets'] << payload['ret']
91
+ parent_node['mtime'] = Flor.tstamp
92
+ end
93
+
94
+ payload['ret'] = @node['ret'] if key
95
+
96
+ reply
97
+ end
98
+
99
+ # vars: { ... }, inits a scope for the parent node
100
+ #
101
+ def receive_vars
102
+
103
+ parent_node['vars'] = payload['ret']
104
+ payload['ret'] = @node['ret']
105
+
106
+ reply
107
+ end
108
+
109
+ def receive_tag
110
+
111
+ pt = parent_node_tree
112
+
113
+ return receive_att('tags') \
114
+ if pt && pt[0].is_a?(String) && Flor::Procedure[pt[0]].names[0] == 'trap'
115
+
116
+ ret = payload['ret']
117
+ ret = unref(ret, :att)
118
+
119
+ tags = Array(ret)
120
+
121
+ return reply if tags.empty?
122
+
123
+ (parent_node['tags'] ||= []).concat(tags)
124
+ parent_node['tags'].uniq!
125
+
126
+ reply('point' => 'entered', 'tags' => tags) +
127
+ reply
128
+ end
129
+ alias receive_tags receive_tag
130
+
131
+ def receive_ret
132
+
133
+ if pn = parent_node
134
+ pn['aret'] = Flor.dup(payload['ret'])
135
+ end
136
+
137
+ reply
138
+ end
139
+
140
+ def receive_timeout
141
+
142
+ n = parent
143
+ m = reply('point' => 'cancel', 'nid' => n, 'flavour' => 'timeout').first
144
+ t = payload['ret']
145
+
146
+ schedule('type' => 'in', 'string' => t, 'nid' => n, 'message' => m) +
147
+ reply
148
+ end
149
+
150
+ def receive_on_error
151
+
152
+ oe = payload['ret']
153
+ oe[1]['on_error'] = true
154
+
155
+ (parent_node['on_error'] ||= []) << oe
156
+
157
+ reply
158
+ end
159
+ end
160
+