pione 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/History.txt +12 -1
  2. data/example/AbstractRule/AbstractRule.pione +40 -0
  3. data/example/Fib/Fib.pione +12 -5
  4. data/example/LucasNumber/LucasNumber.pione +1 -1
  5. data/example/MakePair/MakePair.pione +21 -6
  6. data/example/OddSelector/OddSelector.pione +17 -0
  7. data/example/OddSelector/data/1.i +0 -0
  8. data/example/OddSelector/data/10.i +0 -0
  9. data/example/OddSelector/data/2.i +0 -0
  10. data/example/OddSelector/data/3.i +0 -0
  11. data/example/OddSelector/data/4.i +0 -0
  12. data/example/OddSelector/data/5.i +0 -0
  13. data/example/OddSelector/data/6.i +0 -0
  14. data/example/OddSelector/data/7.i +0 -0
  15. data/example/OddSelector/data/8.i +0 -0
  16. data/example/OddSelector/data/9.i +0 -0
  17. data/example/SequentialParameter/SequentialParameter.pione +4 -0
  18. data/example/SieveOfEratosthenes/SieveOfEratosthenes.pione +31 -43
  19. data/example/SingleParticlesWithRef/SingleParticlesWithRef.pione +1 -1
  20. data/example/Touch/Touch.pione +3 -0
  21. data/lib/pione/command/pione-syntax-checker.rb +4 -4
  22. data/lib/pione/model/assignment.rb +6 -1
  23. data/lib/pione/model/basic-model.rb +92 -278
  24. data/lib/pione/model/binary-operator.rb +5 -1
  25. data/lib/pione/model/block.rb +17 -0
  26. data/lib/pione/model/boolean.rb +54 -22
  27. data/lib/pione/model/constraints.rb +34 -0
  28. data/lib/pione/model/data-expr.rb +184 -297
  29. data/lib/pione/model/feature-expr.rb +13 -4
  30. data/lib/pione/model/float.rb +24 -41
  31. data/lib/pione/model/integer.rb +75 -41
  32. data/lib/pione/model/keyed-sequence.rb +143 -0
  33. data/lib/pione/model/list.rb +12 -8
  34. data/lib/pione/model/message.rb +8 -4
  35. data/lib/pione/model/ordinal-sequence.rb +75 -0
  36. data/lib/pione/model/package.rb +6 -2
  37. data/lib/pione/model/parameters.rb +61 -9
  38. data/lib/pione/model/pione-method.rb +146 -0
  39. data/lib/pione/model/rule-expr.rb +44 -38
  40. data/lib/pione/model/rule-io.rb +11 -3
  41. data/lib/pione/model/rule.rb +105 -155
  42. data/lib/pione/model/sequence.rb +273 -0
  43. data/lib/pione/model/string.rb +75 -29
  44. data/lib/pione/model/ticket-expr.rb +17 -29
  45. data/lib/pione/model/type.rb +242 -0
  46. data/lib/pione/model/variable-table.rb +52 -53
  47. data/lib/pione/model/variable.rb +8 -4
  48. data/lib/pione/model.rb +34 -0
  49. data/lib/pione/parser/block-parser.rb +44 -20
  50. data/lib/pione/parser/common-parser.rb +2 -1
  51. data/lib/pione/parser/document-parser.rb +6 -1
  52. data/lib/pione/parser/expr-parser.rb +57 -11
  53. data/lib/pione/parser/flow-element-parser.rb +2 -2
  54. data/lib/pione/parser/rule-definition-parser.rb +23 -1
  55. data/lib/pione/patch/rinda-patch.rb +1 -5
  56. data/lib/pione/rule-handler/action-handler.rb +5 -5
  57. data/lib/pione/rule-handler/basic-handler.rb +30 -7
  58. data/lib/pione/rule-handler/empty-handler.rb +14 -0
  59. data/lib/pione/rule-handler/flow-handler.rb +132 -115
  60. data/lib/pione/rule-handler/root-handler.rb +6 -2
  61. data/lib/pione/rule-handler/update-criteria.rb +152 -0
  62. data/lib/pione/rule-handler.rb +14 -0
  63. data/lib/pione/system/identifier.rb +9 -9
  64. data/lib/pione/transformer/block-transformer.rb +4 -0
  65. data/lib/pione/transformer/expr-transformer.rb +1 -1
  66. data/lib/pione/transformer/flow-element-transformer.rb +4 -2
  67. data/lib/pione/transformer/literal-transformer.rb +14 -3
  68. data/lib/pione/transformer/rule-definition-transformer.rb +17 -5
  69. data/lib/pione/tuple-space/data-finder.rb +15 -52
  70. data/lib/pione/version.rb +1 -1
  71. data/lib/pione.rb +12 -38
  72. data/test/agent/spec_task-worker.rb +13 -12
  73. data/test/model/spec_assignment.rb +2 -2
  74. data/test/model/spec_binary-operator.rb +10 -10
  75. data/test/model/spec_block.rb +8 -8
  76. data/test/model/spec_boolean.rb +1 -72
  77. data/test/model/spec_boolean.yml +134 -0
  78. data/test/model/spec_data-expr.rb +50 -237
  79. data/test/model/spec_data-expr.yml +16 -45
  80. data/test/model/spec_data-expr_match.yml +45 -0
  81. data/test/model/spec_feature-expr.rb +2 -43
  82. data/test/model/spec_feature-expr.yml +0 -28
  83. data/test/model/spec_feature-expr_decide.yml +28 -0
  84. data/test/model/spec_float.rb +1 -119
  85. data/test/model/spec_float.yml +17 -0
  86. data/test/model/spec_integer.rb +1 -119
  87. data/test/model/spec_integer.yml +57 -0
  88. data/test/model/spec_keyed-sequence.rb +5 -0
  89. data/test/model/spec_keyed-sequence.yml +22 -0
  90. data/test/model/spec_message.rb +7 -7
  91. data/test/model/spec_parameters.rb +50 -63
  92. data/test/model/spec_pione-method.rb +56 -0
  93. data/test/model/spec_rule-expr.rb +18 -8
  94. data/test/model/spec_rule.rb +12 -12
  95. data/test/model/spec_sequence.rb +5 -0
  96. data/test/model/spec_sequence.yml +60 -0
  97. data/test/model/spec_string.rb +3 -70
  98. data/test/model/spec_string.yml +83 -0
  99. data/test/model/spec_ticket-expr.rb +4 -54
  100. data/test/model/spec_ticket-expr.yml +11 -0
  101. data/test/model/spec_variable-table.rb +41 -42
  102. data/test/model/spec_variable.rb +20 -22
  103. data/test/parser/spec_block-parser.yml +9 -0
  104. data/test/parser/spec_expr-parser.yml +0 -17
  105. data/test/parser/spec_flow-element-parser.yml +1 -1
  106. data/test/parser/spec_rule-definition-parser.yml +0 -4
  107. data/test/rule-handler/spec_update-criteria.pione +39 -0
  108. data/test/rule-handler/spec_update-criteria.rb +53 -0
  109. data/test/rule-handler/spec_update-criteria.yml +158 -0
  110. data/test/test-util.rb +25 -0
  111. data/test/transformer/spec_block-transformer.rb +7 -0
  112. data/test/transformer/spec_expr-transformer.rb +64 -19
  113. data/test/transformer/spec_flow-element-transformer.rb +11 -11
  114. data/test/transformer/spec_literal-transformer.rb +29 -29
  115. data/test/transformer/spec_rule-definition-transformer.rb +39 -21
  116. metadata +57 -11
  117. data/lib/pione/model/undefined-value.rb +0 -24
  118. data/lib/pione/tuple-space/update-criteria.rb +0 -97
  119. data/test/model/spec_list.rb +0 -26
  120. data/test/model/spec_rule-io.rb +0 -32
  121. data/test/spec_update-criteria.rb +0 -83
@@ -1,19 +1,7 @@
1
1
  module Pione
2
2
  module Model
3
3
  # PioneString is a string value in PIONE system.
4
- class PioneString < BasicModel
5
- set_pione_model_type TypeString
6
- attr_reader :value
7
-
8
- # Create a string with the value.
9
- #
10
- # @param value [String]
11
- # string value
12
- def initialize(value)
13
- @value = value
14
- super()
15
- end
16
-
4
+ class PioneString < Value
17
5
  # Evaluate the object with the variable table.
18
6
  #
19
7
  # @param vtable [VariableTable]
@@ -32,6 +20,14 @@ module Pione
32
20
  VariableTable.check_include_variable(@value)
33
21
  end
34
22
 
23
+ # Return a sequence that contains self.
24
+ #
25
+ # @return [StringSequence]
26
+ # a sequence
27
+ def to_seq
28
+ StringSequence.new([self])
29
+ end
30
+
35
31
  # @api private
36
32
  def task_id_string
37
33
  "String<#{@value}>"
@@ -62,49 +58,99 @@ module Pione
62
58
  def hash
63
59
  @value.hash
64
60
  end
61
+
62
+ def inspect
63
+ '#<PioneString "%s">' % @value
64
+ end
65
65
  end
66
66
 
67
- TypeString.instance_eval do
68
- define_pione_method("==", [TypeString], TypeBoolean) do |rec, other|
69
- PioneBoolean.new(rec.value == other.value)
67
+ class StringSequence < OrdinalSequence
68
+ set_pione_model_type TypeString
69
+ set_element_class PioneString
70
+ set_shortname "StrSeq"
71
+
72
+ def value
73
+ @value ||= @elements.map{|elt| elt.value}.join
70
74
  end
71
75
 
72
- define_pione_method("!=", [TypeString], TypeBoolean) do |rec, other|
73
- PioneBoolean.not(rec.call_pione_method("==", other))
76
+ def set_annotation_type(type)
77
+ self.class.new(@elements, @attribute.merge(annotation_type: type))
74
78
  end
79
+ end
75
80
 
81
+ TypeString.instance_eval do
76
82
  define_pione_method("+", [TypeString], TypeString) do |rec, other|
77
- PioneString.new(rec.value + other.value)
83
+ raise Model::AttributeError.new(other.attribute) unless rec.attribute == other.attribute
84
+ rec.elements.map do |rec_elt|
85
+ other.elements.map do |other_elt|
86
+ PioneString.new(rec_elt.value + other_elt.value)
87
+ end
88
+ end.flatten.tap {|x| break StringSequence.new(x, rec.attribute)}
78
89
  end
79
90
 
80
91
  define_pione_method("as_string", [], TypeString) do |rec|
81
92
  rec
82
93
  end
83
94
 
84
- define_pione_method("as_int", [], TypeInteger) do |rec|
85
- PioneInteger.new(rec.value.to_i)
95
+ define_pione_method("as_integer", [], TypeInteger) do |rec|
96
+ sequential_map1(TypeInteger, rec) do |elt|
97
+ elt.value.to_i
98
+ end
86
99
  end
87
100
 
88
101
  define_pione_method("as_float", [], TypeFloat) do |rec|
89
- PioneFloat.new(rec.value.to_f)
102
+ sequential_map1(TypeFloat, rec) do |elt|
103
+ elt.value.to_f
104
+ end
90
105
  end
91
106
 
92
- define_pione_method("length", [], TypeInteger) do |rec|
93
- PioneInteger.new(rec.value.size)
107
+ define_pione_method("as_data_expr", [], TypeDataExpr) do |rec|
108
+ # FIXME
109
+ DataExpr.new(rec.elements.map{|elt| elt.value}.join(":")).to_seq
94
110
  end
95
111
 
96
- define_pione_method("include?", [TypeString], TypeBoolean) do |rec, str|
97
- PioneBoolean.new(rec.value.include?(str.value))
112
+ define_pione_method("count", [], TypeInteger) do |rec|
113
+ sequential_map1(TypeInteger, rec) do |elt|
114
+ elt.value.size
115
+ end
98
116
  end
99
117
 
100
- define_pione_method("as_data_expr", [], TypeDataExpr) do |rec|
101
- DataExpr.new(rec.value)
118
+ define_pione_method("include?", [TypeString], TypeBoolean) do |rec, target|
119
+ sequential_map2(TypeBoolean, rec, target) do |rec_elt, target_elt|
120
+ rec_elt.value.include?(target_elt.value)
121
+ end
102
122
  end
103
123
 
104
124
  define_pione_method("substring",
105
125
  [TypeInteger, TypeInteger],
106
126
  TypeString) do |rec, nth, len|
107
- PioneString.new(rec.value[nth.value, len.value])
127
+ sequential_map2(TypeString, nth, len) do |nth_elt, len_elt|
128
+ rec.value[nth_elt.value-1, len_elt.value]
129
+ end
130
+ end
131
+
132
+ # insert : (pos : integer) -> (other : string) -> string
133
+ define_pione_method("insert", [TypeInteger, TypeString], TypeString) do |rec, pos, other|
134
+ sequential_map3(TypeString, rec, pos, other) do |rec_elt, pos_elt, other_elt|
135
+ rec_elt.value.clone.insert(pos_elt.value-1, other_elt.value)
136
+ end
137
+ end
138
+
139
+ # join : string
140
+ define_pione_method("join", [], TypeString) do |rec|
141
+ rec.call_pione_method("join", PioneString.new(rec.separator).to_seq)
142
+ end
143
+
144
+ # join : (sep : string) -> string
145
+ define_pione_method("join", [TypeString], TypeString) do |rec, sep|
146
+ sequential_map1(TypeString, sep) do |sep_elt|
147
+ rec.elements.map{|elt| elt.value}.join(sep_elt.value)
148
+ end
149
+ end
150
+
151
+ # author : string
152
+ define_pione_method("author", [], TypeString) do |rec|
153
+ rec.set_annotation_type(:author)
108
154
  end
109
155
  end
110
156
  end
@@ -14,9 +14,7 @@ module Pione
14
14
  # End
15
15
  # @example TicketExpr represents a set
16
16
  # TicketExpr.new("T1") + TicketExpr.new("T2") #=> TicketExpr.new(["T1", "T2"])
17
- class TicketExpr < BasicModel
18
- set_pione_model_type TypeTicketExpr
19
-
17
+ class TicketExpr < Element
20
18
  class << self
21
19
  # Return an emtpy ticket expression. Empty ticket expression has no
22
20
  # ticket conditions.
@@ -26,25 +24,15 @@ module Pione
26
24
  end
27
25
 
28
26
  # ticket names
29
- attr_reader :names
27
+ attr_reader :name
28
+ alias :value :name
30
29
 
31
30
  # Create a ticket expression with names.
32
31
  #
33
32
  # @param names [Set, Array]
34
33
  # ticket names
35
- #
36
- # @example
37
- # TicketExpr.new(["T1", "T2"])
38
- # @example
39
- # TicketExpr.new(Set.new(["T1", "T2"]))
40
- def initialize(names)
41
- @names = Set.new(names)
42
- super()
43
- end
44
-
45
- # Return true if the ticket expression is empty.
46
- def empty?
47
- @names.empty?
34
+ def initialize(name)
35
+ @name = name
48
36
  end
49
37
 
50
38
  # Evaluate the object with the variable table.
@@ -89,33 +77,33 @@ module Pione
89
77
  # @api private
90
78
  def ==(other)
91
79
  return false unless other.kind_of?(self.class)
92
- @names == other.names
80
+ @name == other.name
93
81
  end
94
82
  alias :eql? :"=="
95
83
 
96
84
  # @api private
97
85
  def hash
98
- @names.hash
86
+ @name.hash
99
87
  end
100
88
  end
101
89
 
102
- TypeTicketExpr.instance_eval do
103
- define_pione_method("==", [TypeTicketExpr], TypeBoolean) do |rec, other|
104
- PioneBoolean.new(rec.names == other.names)
105
- end
90
+ class TicketExprSequence < OrdinalSequence
91
+ set_pione_model_type TypeTicketExpr
92
+ set_element_class TicketExpr
93
+ set_shortname "TSeq"
106
94
 
107
- define_pione_method("!=", [TypeTicketExpr], TypeBoolean) do |rec, other|
108
- PioneBoolean.not(rec.call_pione_method("==", other))
95
+ def names
96
+ @elements.map do |elt|
97
+ elt.name
98
+ end
109
99
  end
100
+ end
110
101
 
102
+ TypeTicketExpr.instance_eval do
111
103
  define_pione_method("==>", [TypeRuleExpr], TypeRuleExpr) do |rec, other|
112
104
  other.add_input_ticket_expr(rec)
113
105
  end
114
106
 
115
- define_pione_method("+", [TypeTicketExpr], TypeTicketExpr) do |rec, other|
116
- rec + other
117
- end
118
-
119
107
  define_pione_method("as_string", [], TypeString) do |rec|
120
108
  rec.textize
121
109
  end
@@ -0,0 +1,242 @@
1
+ module Pione
2
+ module Model
3
+ # Type is a class for type expression of PIONE model objects.
4
+ class Type < System::PioneObject
5
+ @table = Hamster.hash
6
+
7
+ class << self
8
+ def put(name, value)
9
+ @table = @table.put(name, value)
10
+ end
11
+
12
+ def get(name)
13
+ @table.get(name)
14
+ end
15
+ end
16
+
17
+ attr_reader :name
18
+ attr_reader :parent_type
19
+ attr_reader :pione_method
20
+
21
+ # Create a type for PIONE model object.
22
+ #
23
+ # @param name [Symbol]
24
+ # type name
25
+ # @param parent_type [Type]
26
+ # parent type
27
+ def initialize(name, parent_type=nil)
28
+ @name = name
29
+ @parent_type = parent_type
30
+ @pione_method = Hamster.hash
31
+ Type.put(name, self)
32
+ end
33
+
34
+ # Return true if the type or the pione model object matches.
35
+ #
36
+ # @param [BasicModel] target
37
+ # matching test target
38
+ # @return [Boolean]
39
+ # true if it matches, or false
40
+ def match(target)
41
+ target_type = target.pione_model_type
42
+ while target_type do
43
+ return true if self == target_type
44
+ target_type = target_type.parent_type
45
+ end
46
+ return false
47
+ end
48
+
49
+ # Find named method.
50
+ #
51
+ # @param name [String]
52
+ # method name
53
+ # @param rec [Callable]
54
+ # receiver
55
+ # @param args [Array<BasicModel>]
56
+ # arguments
57
+ # @return [void]
58
+ def find_method(name, rec, *args)
59
+ name = name.to_s
60
+ if @pione_method.has_key?(name)
61
+ @pione_method[name].each do |pione_method|
62
+ if pione_method.validate_inputs(rec, *args)
63
+ return pione_method
64
+ end
65
+ end
66
+ else
67
+ return @parent_type ? @parent_type.find_method(name, rec, *args) : nil
68
+ end
69
+ end
70
+
71
+ # Define PIONE model object methods.
72
+ #
73
+ # @param name [Symbol]
74
+ # method name
75
+ # @param inputs [Array<Type>]
76
+ # input types of the method
77
+ # @param output [Type]
78
+ # output type of the method
79
+ # @param [Proc] b
80
+ # @return [void]
81
+ def define_pione_method(name, inputs, output, &b)
82
+ name = name.to_s
83
+ method = PioneMethod.new(name, inputs, output, b)
84
+ list = @pione_method.fetch(name, Hamster.list)
85
+ @pione_method = @pione_method.put(name, list.cons(method))
86
+ end
87
+
88
+ # Return true if the data has the type.
89
+ #
90
+ # @return [void]
91
+ def check(data)
92
+ unless match(data)
93
+ raise PioneModelTypeError.new(data, self)
94
+ end
95
+ end
96
+
97
+ def type_to_class(type)
98
+ case type
99
+ when TypeString
100
+ StringSequence
101
+ when TypeInteger
102
+ IntegerSequence
103
+ when TypeFloat
104
+ FloatSequence
105
+ when TypeBoolean
106
+ BooleanSequence
107
+ when TypeDataExpr
108
+ DataExprSequence
109
+ when TypeTicketExpr
110
+ TicketExprSequence
111
+ end
112
+ end
113
+
114
+ def map1(seq, &b)
115
+ seq_class = type_to_class(self)
116
+ seq_class.new(seq.elements.map{|elt| b.call(elt)}, seq.attribute)
117
+ end
118
+
119
+ def map2(seq1, seq2, &b)
120
+ seq_class = type_to_class(self)
121
+ seq1.elements.map do |elt1|
122
+ seq2.elements.map do |elt2|
123
+ b.call(elt1, elt2)
124
+ end
125
+ end.flatten.tap {|x| break seq_class.new(x, seq1.attribute)}
126
+ end
127
+
128
+ def sequential_map1(type, seq1, &b)
129
+ seq_class = type_to_class(type)
130
+ seq1.elements.map do |elt1|
131
+ seq_class.element_class.new(b.call(elt1))
132
+ end.tap {|x| break seq_class.new(x, seq1.attribute)}
133
+ end
134
+
135
+ def sequential_map2(type, seq1, seq2, &b)
136
+ seq_class = type_to_class(type)
137
+ seq1.elements.map do |elt1|
138
+ seq2.elements.map do |elt2|
139
+ seq_class.element_class.new(b.call(elt1, elt2))
140
+ end
141
+ end.flatten.tap {|x| break seq_class.new(x, seq1.attribute)}
142
+ end
143
+
144
+ def sequential_map3(type, seq1, seq2, seq3, &b)
145
+ seq_class = type_to_class(type)
146
+ seq1.elements.map do |elt1|
147
+ seq2.elements.map do |elt2|
148
+ seq3.elements.map do |elt3|
149
+ seq_class.element_class.new(b.call(elt1, elt2, elt3))
150
+ end
151
+ end
152
+ end.flatten.tap {|x| break seq_class.new(x, seq1.attribute)}
153
+ end
154
+
155
+ def sequential_fold1(type, seq1, &b)
156
+ seq_class = type_to_class(type)
157
+ seq1.elements.inject(seq_class.new([], seq1.attribute)) do |obj, elt1|
158
+ b.call(elt1, obj)
159
+ end
160
+ end
161
+
162
+ def sequential_fold2(type, seq1, seq2, &b)
163
+ seq_class = type_to_class(type)
164
+ seq1.elements.inject(seq_class.new([], seq1.attribute)) do |obj1, elt1|
165
+ seq2.elements.inject(obj1) do |obj2, elt2|
166
+ b.call(obj2, elt1, elt2)
167
+ end
168
+ end
169
+ end
170
+
171
+ def sequential_pred1(seq1, &b)
172
+ method1 = seq1.every? ? :all? : :any?
173
+ seq1.elements.send(method1) do |elt1|
174
+ PioneBoolean.new(b.call(elt1))
175
+ end.tap {|x| break BooleanSequence.new(x)}
176
+ end
177
+
178
+ def sequential_pred2(seq1, seq2, &b)
179
+ method1 = seq1.every? ? :all? : :any?
180
+ method2 = seq2.every? ? :all? : :any?
181
+ seq1.elements.send(method1) do |elt1|
182
+ seq2.elements.send(method2) do |elt2|
183
+ b.call(elt1, elt2)
184
+ end
185
+ end.tap {|x| break BooleanSequence.new([PioneBoolean.new(x)])}
186
+ end
187
+
188
+ def to_s
189
+ "#<Type %s>" % @name
190
+ end
191
+ end
192
+
193
+ # TypeSequence is a type for sequence of something.
194
+ TypeSequence = Type.new("sequence")
195
+
196
+ # TypeOrdinalSequence is a type for integer indexed sequence.
197
+ TypeOrdinalSequence = Type.new("ordinal-sequence", TypeSequence)
198
+
199
+ # TypeKeyedSequence is a type for something indexed sequence.
200
+ TypeKeyedSequence = Type.new("keyed-sequence", TypeSequence)
201
+
202
+ # TypeBoolean is a type for integer indexed boolean sequence.
203
+ TypeBoolean = Type.new("boolean", TypeOrdinalSequence)
204
+
205
+ # TypeInteger is a type for integer indexed integer sequence.
206
+ TypeInteger = Type.new("integer", TypeOrdinalSequence)
207
+
208
+ # TypeFloat is a type for float
209
+ TypeFloat = Type.new("float", TypeOrdinalSequence)
210
+
211
+ # string type for PIONE system
212
+ TypeString = Type.new("string", TypeOrdinalSequence)
213
+
214
+ # data expression type for PIONE system
215
+ TypeDataExpr = Type.new("data-expr", TypeOrdinalSequence)
216
+
217
+ # feature type for PIONE system
218
+ TypeFeature = Type.new("feature", TypeOrdinalSequence)
219
+
220
+ # rule expression type for PIONE system
221
+ TypeRuleExpr = Type.new("rule-expr", TypeOrdinalSequence)
222
+
223
+ # parameters type for PIONE system
224
+ TypeParameters = Type.new("parameters", TypeOrdinalSequence)
225
+
226
+ # assignment type for PIONE system
227
+ TypeAssignment = Type.new("assignment", TypeOrdinalSequence)
228
+
229
+ # variable table type for PIONE system
230
+ TypeVariableTable = Type.new("variable-table", TypeOrdinalSequence)
231
+
232
+ # package type for PIONE system
233
+ TypePackage = Type.new("package", TypeOrdinalSequence)
234
+
235
+ # ticket expression type
236
+ TypeTicketExpr = Type.new("ticket-expr", TypeOrdinalSequence)
237
+
238
+ def TypeSequence.match(other)
239
+ true
240
+ end
241
+ end
242
+ end
@@ -58,8 +58,6 @@ module Pione
58
58
 
59
59
  # VariableTable represents variable tables for rule context.
60
60
  class VariableTable < BasicModel
61
- set_pione_model_type TypeVariableTable
62
-
63
61
  # Return empty variable table.
64
62
  #
65
63
  # @return [VariableTable]
@@ -134,7 +132,7 @@ module Pione
134
132
  check_argument_type(variable, Variable)
135
133
  check_argument_type(new_value, BasicModel)
136
134
  if old_value = @table[variable]
137
- unless old_value.kind_of?(UndefinedValue) or new_value == old_value
135
+ unless old_value.void? or new_value == old_value
138
136
  raise VariableBindingError.new(variable, new_value, old_value)
139
137
  end
140
138
  end
@@ -164,11 +162,11 @@ module Pione
164
162
  variables = to_hash
165
163
  new_str = str.to_s.gsub(/\{(\$.+?)\}/) do
166
164
  expr = DocumentTransformer.new.apply(DocumentParser.new.expr.parse($1))
167
- expr.eval(self).call_pione_method("as_string").to_ruby
165
+ expr.eval(self).call_pione_method("textize").first.value
168
166
  end
169
167
  new_str.gsub(/\<\?\s*(.+?)\s*\?\>/) do
170
168
  expr = DocumentTransformer.new.apply(DocumentParser.new.expr.parse($1))
171
- expr.eval(self).call_pione_method("as_string").to_ruby
169
+ expr.eval(self).call_pione_method("textize").first.value
172
170
  end
173
171
  end
174
172
 
@@ -246,15 +244,13 @@ module Pione
246
244
  @table.hash
247
245
  end
248
246
 
249
- private
250
-
251
247
  # Make input or output auto variables.
252
248
  #
253
249
  # @api private
254
250
  def make_io_auto_variables(type, expr, data, index)
255
251
  expr = expr.eval(self)
256
252
  prefix = (type == :input ? "I" : "O")
257
- case expr.modifier
253
+ case expr.distribution
258
254
  when :all
259
255
  make_io_auto_variables_by_all(type, prefix, expr, data, index)
260
256
  when :each
@@ -262,37 +258,52 @@ module Pione
262
258
  end
263
259
  end
264
260
 
265
- # Make input or output auto variables for 'exist' modified data name
266
- # expression.
261
+ # Make input/output auto variables by data expression with each
262
+ # distribution.
267
263
  #
268
- # @api private
264
+ # @param prefix [String]
265
+ # "I" or "O"
266
+ # @param expr [DataExpr]
267
+ # data expression
268
+ # @param tuple [DataTuple]
269
+ # data tuple
270
+ # @param index [Integer]
271
+ # index number of the input/output
272
+ # @return [void]
269
273
  def make_io_auto_variables_by_each(prefix, expr, tuple, index)
270
274
  return if tuple.nil?
275
+
271
276
  # variable
272
277
  var = Variable.new(prefix)
278
+
273
279
  # matched data
274
- md = expr.match(tuple.name).to_a
280
+ md = expr.first.match(tuple.name).to_a
275
281
 
276
- # setup rule-io list
277
- list = get(var)
278
- list = RuleIOList.new unless list
279
- elt = RuleIOElement.new(PioneString.new(tuple.name))
280
- elt.uri = PioneString.new(tuple.location.uri.to_s)
281
- elt.match = PioneList.new(*md.map{|d| PioneString.new(d)})
282
+ # setup data expression sequence
283
+ seq = get(var) || KeyedSequence.empty
284
+ data_expr = DataExpr.new(tuple.name, location: tuple.location, matched_data: md)
282
285
 
283
- # update the list
284
- set!(var, list.add(elt))
286
+ # update variable table
287
+ set!(var, seq.put(PioneInteger.new(index), data_expr))
285
288
 
286
- # set special variable if index equals 1
289
+ # set the special variable if index is 1
287
290
  if prefix == 'I' && index == 1
288
- set(Variable.new("*"), PioneString.new(md[1]))
291
+ set(Variable.new("*"), StringSequence.new([PioneString.new(md[1])], separator: DataExpr::SEPARATOR))
289
292
  end
290
293
  end
291
294
 
292
- # Make input or output auto variables for 'all' modified data name
293
- # expression.
295
+ # Make input/output auto variables by data expression with all
296
+ # distribution.
294
297
  #
295
- # @api private
298
+ # @param prefix [String]
299
+ # "I" or "O"
300
+ # @param expr [DataExpr]
301
+ # data expression
302
+ # @param tuple [DataTuple]
303
+ # data tuple
304
+ # @param index [Integer]
305
+ # index number of the input/output
306
+ # @return [void]
296
307
  def make_io_auto_variables_by_all(type, prefix, expr, tuples, index)
297
308
  # FIXME: output
298
309
  return if type == :output
@@ -300,44 +311,32 @@ module Pione
300
311
  # variable
301
312
  var = Variable.new(prefix)
302
313
 
303
- # setup rule-io list
304
- list = get(var)
305
- list = RuleIOList.new unless list
306
- io_list = RuleIOList.new()
314
+ # setup data expression sequence(this is $I/$O)
315
+ seq = get(var) || KeyedSequence.empty(separator: DataExpr::SEPARATOR)
307
316
 
308
317
  asterisk = []
309
318
 
310
319
  # convert each tuples
311
- tuples.each do |tuple, i|
312
- asterisk << expr.match(tuple.name).to_a[1]
313
-
314
- elt = RuleIOElement.new(PioneString.new(tuple.name))
315
- elt.uri = PioneString.new(tuple.location.uri.to_s)
316
- elt.match = PioneList.new(
317
- *expr.match(tuple.name).to_a.map{|m| PioneString.new(m)}
318
- )
319
- io_list.add!(elt)
320
+ matched_seq = tuples.inject(seq) do |_seq, tuple|
321
+ # matched data
322
+ md = expr.first.match(tuple.name).to_a
323
+ asterisk << md[1]
324
+
325
+ # make a date expression
326
+ data_expr = DataExpr.new(tuple.name, location: tuple.location, matched_data: md)
327
+
328
+ # put it with index
329
+ _seq.put(PioneInteger.new(index), data_expr)
320
330
  end
321
331
 
322
332
  # set special variable if index equals 1
323
333
  if prefix == 'I' && index == 1
324
- set(Variable.new("*"), PioneString.new(asterisk.join(":")))
334
+ strs = asterisk.map{|str| PioneString.new(str)}
335
+ set(Variable.new("*"), StringSequence.new(strs, separator: DataExpr::SEPARATOR))
325
336
  end
326
337
 
327
- # update
328
- set!(var, list.add(io_list))
329
- end
330
-
331
- #
332
- # pione methods
333
- #
334
-
335
- define_pione_method("get", [TypeString], TypeAny) do |name|
336
- get(Variable.new(name.value))
337
- end
338
-
339
- define_pione_method("keys", [], TypeList.new(TypeString)) do
340
- PioneList.new(@table.keys.map{|var| PioneString.new(var.name)})
338
+ # update sequence
339
+ set!(var, matched_seq)
341
340
  end
342
341
  end
343
342
  end
@@ -2,9 +2,8 @@ module Pione
2
2
  module Model
3
3
  # Variable represent variable name objects. A variable object can evaluates
4
4
  # its value with the variable table.
5
- class Variable < BasicModel
6
- set_pione_model_type TypeAny
7
-
5
+ class Variable < Callable
6
+ set_pione_model_type TypeSequence
8
7
  attr_reader :name
9
8
 
10
9
  # true if the variable is user parameter
@@ -95,9 +94,14 @@ module Pione
95
94
 
96
95
  # @api private
97
96
  def inspect
98
- "#<Pione::Model::Variable @name=%s>" % @name.inspect
97
+ "#<Variable %s>" % @name.inspect
99
98
  end
100
99
  alias :to_s :inspect
101
100
  end
101
+
102
+ # class VariableSequence < Sequence
103
+ # set_pione_model_type TypeSequence
104
+ # set_element_class Variable
105
+ # end
102
106
  end
103
107
  end