pione 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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|