pione 0.1.1 → 0.1.2

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 (53) hide show
  1. data/History.txt +9 -2
  2. data/Rakefile +1 -1
  3. data/example/Fib/Fib.pione +5 -5
  4. data/example/SequentialProcess/SequentialProcess.pione +69 -0
  5. data/lib/pione.rb +7 -11
  6. data/lib/pione/agent/input-generator.rb +3 -2
  7. data/lib/pione/agent/task-worker.rb +6 -3
  8. data/lib/pione/agent/trivial-routine-worker.rb +6 -5
  9. data/lib/pione/command/basic-command.rb +7 -1
  10. data/lib/pione/command/child-process.rb +5 -1
  11. data/lib/pione/command/front-owner-command.rb +15 -4
  12. data/lib/pione/command/pione-client.rb +16 -9
  13. data/lib/pione/command/pione-syntax-checker.rb +45 -30
  14. data/lib/pione/command/pione-task-worker.rb +22 -13
  15. data/lib/pione/command/pione-tuple-space-provider.rb +4 -2
  16. data/lib/pione/command/pione-tuple-space-receiver.rb +10 -5
  17. data/lib/pione/front/task-worker-owner.rb +1 -0
  18. data/lib/pione/model/basic-model.rb +3 -0
  19. data/lib/pione/model/block.rb +2 -1
  20. data/lib/pione/model/call-rule.rb +10 -0
  21. data/lib/pione/model/feature-expr.rb +143 -54
  22. data/lib/pione/model/float.rb +0 -1
  23. data/lib/pione/model/rule-expr.rb +132 -7
  24. data/lib/pione/model/rule.rb +53 -17
  25. data/lib/pione/model/ticket-expr.rb +124 -0
  26. data/lib/pione/parser/expr-parser.rb +75 -38
  27. data/lib/pione/parser/literal-parser.rb +14 -0
  28. data/lib/pione/parser/parslet-extension.rb +143 -0
  29. data/lib/pione/rule-handler/flow-handler.rb +33 -3
  30. data/lib/pione/system/global.rb +10 -3
  31. data/lib/pione/transformer.rb +24 -0
  32. data/lib/pione/transformer/block-transformer.rb +6 -5
  33. data/lib/pione/transformer/document-transformer.rb +5 -10
  34. data/lib/pione/transformer/expr-transformer.rb +56 -30
  35. data/lib/pione/transformer/feature-expr-transformer.rb +9 -5
  36. data/lib/pione/transformer/flow-element-transformer.rb +21 -23
  37. data/lib/pione/transformer/literal-transformer.rb +39 -35
  38. data/lib/pione/transformer/rule-definition-transformer.rb +8 -6
  39. data/lib/pione/transformer/transformer-module.rb +7 -5
  40. data/lib/pione/tuple/ticket-tuple.rb +8 -0
  41. data/lib/pione/util/{message.rb → console-message.rb} +54 -26
  42. data/lib/pione/version.rb +1 -1
  43. data/pione.gemspec +2 -1
  44. data/test/model/spec_feature-expr.rb +18 -3
  45. data/test/model/spec_feature-expr.yml +28 -16
  46. data/test/model/spec_ticket-expr.rb +67 -0
  47. data/test/parser/spec_expr-parser.yml +74 -25
  48. data/test/parser/spec_literal-parser.yml +11 -0
  49. data/test/test-util.rb +1 -1
  50. data/test/transformer/spec_expr-transformer.rb +27 -54
  51. data/test/transformer/spec_literal-transformer.rb +6 -0
  52. metadata +29 -7
  53. data/lib/pione/parser/syntax-error.rb +0 -61
@@ -12,6 +12,10 @@ module Pione
12
12
  # +expr+ matches all expressions in PIONE document.
13
13
  # @return [Parslet::Atoms::Entity] +expr+ atom
14
14
  # @example
15
+ # "abc"[0]
16
+ # @example
17
+ # 'abc'.as_string
18
+ # @example
15
19
  # 1 + 1
16
20
  # @example
17
21
  # (1 + 1).next
@@ -24,31 +28,52 @@ module Pione
24
28
  rule(:expr) {
25
29
  ( expr_operator_application |
26
30
  assignment |
27
- (expr_element.as(:receiver) >>
28
- (index | message).repeat(1).as(:messages)) |
31
+ expr_prepositional_messages.as(:reverse_messages) >> pad? >> expr.as(:receiver) |
29
32
  expr_element
30
33
  ).as(:expr)
31
34
  }
32
35
 
36
+
37
+ # @!attribute [r] expr_prepositional_messages
38
+ # +expr_messages+ matches prepositional messages.
39
+ # @return [Parslet::Atoms::Entity] +expr_prepositional_messages+ atom
40
+ rule(:expr_prepositional_messages) {
41
+ (pad? >> reverse_message).repeat(1)
42
+ }
43
+
44
+ # @!attribute [r] expr_postpositional_messages
45
+ # +expr_messages+ matches postpositional messages.
46
+ # @return [Parslet::Atoms::Entity] +expr_post_positional_messages+ atom
47
+ rule(:expr_postpositional_messages) {
48
+ (pad? >> (index | message | parameters.as(:postpositional_parameters))).repeat(1)
49
+ }
50
+
33
51
  # @!attribute [r] expr_element
34
52
  # +expr_element+ matches simple expressions.
35
53
  # @return [Parslet::Atoms::Entity] +expr_element+ atom
36
54
  # @example
37
55
  # true
38
56
  # @example
39
- # "abc"[0]
57
+ # (1 + 1)
40
58
  # @example
41
- # 'abc'.as_string
59
+ # ("abc".index(1, 1))
60
+ rule(:expr_element) {
61
+ expr_basic_element.as(:receiver) >> expr_postpositional_messages.as(:messages) |
62
+ expr_basic_element
63
+ }
64
+
65
+ # @!attribute [r] expr_element
66
+ # +expr_element+ matches simple expressions.
67
+ # @return [Parslet::Atoms::Entity] +expr_element+ atom
68
+ # @example
69
+ # true
42
70
  # @example
43
71
  # (1 + 1)
44
72
  # @example
45
73
  # ("abc".index(1, 1))
46
- rule(:expr_element) {
47
- ( (atomic_expr.as(:receiver) >> indexes) |
48
- (atomic_expr.as(:receiver) >> messages) |
49
- atomic_expr |
50
- lparen >> expr >> rparen
51
- )
74
+ rule(:expr_basic_element) {
75
+ atomic_expr |
76
+ lparen >> expr >> rparen
52
77
  }
53
78
 
54
79
  # @!attribute [r] atomic_expr
@@ -57,6 +82,8 @@ module Pione
57
82
  # @example
58
83
  # true
59
84
  # @example
85
+ # false
86
+ # @example
60
87
  # 0.1
61
88
  # @example
62
89
  # 1
@@ -67,6 +94,8 @@ module Pione
67
94
  # @example
68
95
  # '*.txt'
69
96
  # @example
97
+ # null
98
+ # @example
70
99
  # {var: 1}
71
100
  # @example
72
101
  # $abc:test
@@ -77,6 +106,7 @@ module Pione
77
106
  float |
78
107
  integer |
79
108
  string |
109
+ ticket |
80
110
  data_name |
81
111
  rule_expr |
82
112
  feature_expr |
@@ -106,10 +136,12 @@ module Pione
106
136
  # @example
107
137
  # :=, ==, !=, >=, >, <=, <, &&, ||, +, -, *, /, %, or, and
108
138
  rule(:expr_operator) {
139
+ equals >> equals >> greater_than |
109
140
  equals >> equals |
110
141
  exclamation >> equals |
111
142
  less_than >> equals |
112
143
  less_than |
144
+ greater_than >> greater_than >> greater_than |
113
145
  greater_than >> equals |
114
146
  greater_than |
115
147
  ampersand >> ampersand |
@@ -151,21 +183,12 @@ module Pione
151
183
  ).as(:assignment)
152
184
  }
153
185
 
154
- # @!attribute [r] messages
155
- # +messages+ matches message list.
156
- # @return [Parslet::Atoms::Entity] +messages+ atom
157
- # @example
158
- # .params("-w").sync
159
- rule(:messages) {
160
- message.repeat(1).as(:messages)
161
- }
162
-
163
186
  # @!attribute [r] message
164
187
  # +message+ matches message sending.
165
188
  # @return [Parslet::Atoms::Entity] +message+ atom
166
189
  # @example
167
190
  # # message with no arguments
168
- # .to_string
191
+ # .as_string
169
192
  # @example
170
193
  # # message with arguments
171
194
  # .params("-w")
@@ -176,6 +199,23 @@ module Pione
176
199
  ).as(:message)
177
200
  }
178
201
 
202
+ # @!attribute [r] reverse_message
203
+ # +message+ matches reverse message sending.
204
+ # @return [Parslet::Atoms::Entity] +reverse_message+ atom
205
+ # @example
206
+ # # message with no arguments
207
+ # as_string ::
208
+ # @example
209
+ # # message with arguments
210
+ # params("-w") ::
211
+ rule(:reverse_message) {
212
+ ( identifier.as(:message_name) >>
213
+ message_parameters.maybe >>
214
+ pad? >>
215
+ colon >> colon
216
+ ).as(:message)
217
+ }
218
+
179
219
  # @!attribute [r] message_parameters
180
220
  # +message_parameters+ matches message parameters.
181
221
  # @return [Parslet::Atoms::Entity] +message_parameters+ atom
@@ -211,14 +251,9 @@ module Pione
211
251
  pad? >> comma >> pad? >> expr
212
252
  }
213
253
 
214
- # @!attribute [r] indexes
215
- # +indexes+ matches object index list.
216
- # @return [Parslet::Atoms::Entity] +indexes+ atom
217
- # @example
218
- # [1][2][3]
219
- rule(:indexes) {
220
- index.repeat(1).as(:indexes)
221
- }
254
+ #
255
+ # INDEX
256
+ #
222
257
 
223
258
  # @!attribute [r] index
224
259
  # +index+ matches object index.
@@ -227,13 +262,17 @@ module Pione
227
262
  # [1]
228
263
  # [1,1]
229
264
  # [1,2,3]
265
+ # ["a"]
266
+ # ["a", "b", "c"]
267
+ # @example
268
+ # [Var: 1]
230
269
  rule(:index) {
231
270
  ( lsbracket >>
232
- space? >>
271
+ pad? >>
233
272
  ( index_arguments.as(:index) |
234
273
  syntax_error("it should be index arguments", :expr)) >>
235
- space? >>
236
- rsbracket
274
+ pad? >>
275
+ (rsbracket | syntax_error("it should be index end ']'"))
237
276
  )
238
277
  }
239
278
 
@@ -245,21 +284,19 @@ module Pione
245
284
  # 1,1
246
285
  # 1,2,3
247
286
  rule(:index_arguments) {
248
- expr.repeat(1,1) >> space? >> index_arguments_rest.repeat
287
+ expr.repeat(1,1) >> pad? >> index_arguments_rest.repeat
249
288
  }
250
289
 
251
290
  # @!attribute [r] index_arguments_rest
252
- # +index_arguments_rest+ matches argument tail of object index.
291
+ # +index_arguments_rest+ matches tail elements in index expression.
253
292
  # @return [Parslet::Atoms::Entity] +index_arguments_rest+ atom
254
293
  # @example
255
294
  # ,1
256
295
  rule(:index_arguments_rest) {
257
- space? >>
296
+ pad? >>
258
297
  comma >>
259
- space? >>
260
- ( expr |
261
- syntax_error("it should be expr", :expr)
262
- )
298
+ pad? >>
299
+ (expr | syntax_error("it should be expr", :expr))
263
300
  }
264
301
  end
265
302
  end
@@ -177,6 +177,20 @@ module Pione
177
177
  syntax_error("it should be parameter key", :identifier)
178
178
  )
179
179
  }
180
+
181
+ # @!attribute [r] ticket
182
+ # +ticket+ matches ticket object.
183
+ #
184
+ # @return [Parslet::Atoms::Entity] +ticket+ atom
185
+ # @example
186
+ # &Main
187
+ rule(:ticket) {
188
+ less_than >>
189
+ space? >>
190
+ identifier.as(:ticket) >>
191
+ space? >>
192
+ greater_than
193
+ }
180
194
  end
181
195
  end
182
196
  end
@@ -0,0 +1,143 @@
1
+ module Pione
2
+ module Parser
3
+ # ParserError is raised when the parser finds syntax error.
4
+ class ParserError < Parslet::ParseFailed
5
+ # Creates an error.
6
+ # @param [String] str
7
+ # target string
8
+ # @param [Array<String>] expected
9
+ # expected names
10
+ # @param [Parslet::Source] source
11
+ # parser source
12
+ def initialize(str, expected, source)
13
+ @str = str
14
+ @expected = expected
15
+ @source = source
16
+ super(str)
17
+ end
18
+
19
+ # @api private
20
+ def message
21
+ line, column = @source.line_and_column
22
+ expected = @expected.join(", ")
23
+ left = @source.consume(@source.chars_left)
24
+ "%s(expected: %s, line: %s, column: %s):\n%s" % [
25
+ @str, expected, line, column, left
26
+ ]
27
+ end
28
+ end
29
+
30
+ # @api private
31
+ class SyntaxErrorAtom < Parslet::Atoms::Base
32
+ def initialize(msg, expected_elements=[], ignore_error)
33
+ @msg = msg
34
+ @expected_elements = expected_elements
35
+ @ignore_error = ignore_error
36
+ end
37
+
38
+ def try(source, context, _)
39
+ raise ParserError.new(@msg, @expected_elements, source)
40
+ end
41
+
42
+ def to_s_inner(prec)
43
+ "SYNTAX_ERROR"
44
+ end
45
+ end
46
+
47
+ class IgnoreErrorAtom < Parslet::Atoms::Base
48
+ def initialize(atom)
49
+ @atom = atom
50
+ end
51
+
52
+ def try(source, context)
53
+ begin
54
+ @atom.apply(source, context)
55
+ rescue ParserError
56
+ context.err(self, source, "", [])
57
+ end
58
+ end
59
+
60
+ def to_s_inner(prec)
61
+ "IGNORE_ERROR"
62
+ end
63
+ end
64
+
65
+ # SyntaxError provides notification methods for syntax error.
66
+ module SyntaxError
67
+ # Raises syntax error. This method returns a dummy atom and the parser
68
+ # evaluates it as error.
69
+ # @param [String] msg
70
+ # error message
71
+ # @param [Array<String>] expected_elements
72
+ # expected name list
73
+ # @return [SyntaxErrorAtom]
74
+ # dummy atom for parser
75
+ def syntax_error(msg, *expected_elements)
76
+ SyntaxErrorAtom.new(msg, expected_elements, $ignore_error)
77
+ end
78
+
79
+ def ignore_error(&b)
80
+ res = yield
81
+ return IgnoreErrorAtom.new(res)
82
+ end
83
+ end
84
+
85
+ class IgnoreAtom < Parslet::Atoms::Base
86
+ def initialize(atom)
87
+ @atom = atom
88
+ end
89
+
90
+ def try(source, context, consume_all)
91
+ success, _ = result = @atom.try(source, context, consume_all)
92
+ return sucess ? succ(nil) : result
93
+ end
94
+
95
+ def to_s_inner(prec)
96
+ "IGNORE"
97
+ end
98
+ end
99
+
100
+ module Ignore
101
+ def ignore
102
+ IgnoreAtom.new(self)
103
+ end
104
+ end
105
+
106
+ class ExceptionAtom < Parslet::Atoms::Base
107
+ def initialize(atom, exception)
108
+ @atom = atom
109
+ @exception = exception
110
+ end
111
+
112
+ def try(source, context)
113
+ success, value = result = @atom.apply(source, context)
114
+ if success
115
+ esuccess, _ = @exception.apply(source, context)
116
+ p @exception
117
+ p source
118
+ p esuccess
119
+ if esuccess
120
+ return result
121
+ end
122
+ end
123
+ return result
124
+ end
125
+
126
+ def to_s_inner(prec)
127
+ "EXCEPTION"
128
+ end
129
+ end
130
+
131
+ module Exception
132
+ def except(exception)
133
+ #ExceptionAtom.new(self, exception)
134
+ ExceptionAtom.new(self, exception)
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ class Parslet::Atoms::Base
141
+ include Pione::Parser::Ignore
142
+ include Pione::Parser::Exception
143
+ end
@@ -69,10 +69,35 @@ module Pione
69
69
 
70
70
  # Finds applicable flow-element rules with inputs and variables.
71
71
  def find_applicable_rules(callees)
72
- callees.inject([]) do |combinations, callee|
73
- # eval callee expr by handling rule context
74
- callee = callee.eval(@variable_table)
72
+ callees = callees.inject([]) do |list, callee|
73
+ # evaluate callee expr by handling rule context
74
+ # and expand compositional rule expressions as simple rule expressions
75
+ list + callee.eval(@variable_table).expr.to_set.to_a.map{|expr| CallRule.new(expr)}
76
+ end
77
+
78
+ # ticket check
79
+ callees = callees.inject([]) do |list, callee|
80
+ target = nil
81
+ # check if tickets exist in the domain
82
+ names = callee.expr.input_ticket_expr.names
83
+ if not(names.empty?)
84
+ if names.all? do |name|
85
+ begin
86
+ read0(Tuple[:ticket].new(@domain, name))
87
+ true
88
+ rescue Rinda::RequestExpiredError
89
+ false # when the ticket doesn't exist
90
+ end
91
+ end
92
+ target = callee
93
+ end
94
+ else
95
+ target = callee
96
+ end
97
+ target ? list << callee : list
98
+ end
75
99
 
100
+ callees.inject([]) do |combinations, callee|
76
101
  # find callee rule
77
102
  rule = find_callee_rule(callee)
78
103
 
@@ -211,6 +236,11 @@ module Pione
211
236
  # copy data from task domain to this domain
212
237
  @finished << finished
213
238
  copy_data_into_domain(finished.outputs, @domain)
239
+
240
+ # output ticket
241
+ callee.expr.output_ticket_expr.names.each do |name|
242
+ write(Tuple[:ticket].new(@domain, name))
243
+ end
214
244
  end
215
245
 
216
246
  user_message_end("End Task Distribution: %s" % handler_digest)
@@ -21,10 +21,10 @@ module Pione
21
21
  # @param [Object] val
22
22
  # default value
23
23
  # @return [void]
24
- def define_item(name, config, val=nil, &b)
24
+ def define_item(name, configurable, val=nil, &b)
25
25
  @__names__ << name
26
- if config
27
- @__config__[name] = config.kind_of?(TrueClass) ? name : config
26
+ if configurable
27
+ @__config__[name] = configurable ? name : config
28
28
  end
29
29
 
30
30
  singleton_class.module_eval do |mod|
@@ -90,6 +90,13 @@ module Pione
90
90
  # system
91
91
  #
92
92
 
93
+ # @!method monitor
94
+ # Global monitor object for PIONE system.
95
+ #
96
+ # @return [Monitor]
97
+ # monitor object
98
+ define_item(:monitor, false, Monitor.new)
99
+
93
100
  # .pione dir
94
101
  define_item(:dot_pione_dir, true) do
95
102
  Pathname.new("~/.pione").expand_path.tap {|path|