Class: Pione::Lang::Type
- Inherits:
-
StructX
- Object
- StructX
- Pione::Lang::Type
- Defined in:
- lib/pione/lang/type.rb
Overview
Type is a class for type expression of PIONE model objects.
Class Attribute Summary collapse
-
.table ⇒ Object
readonly
Returns the value of attribute table.
Instance Method Summary collapse
-
#check(env, data) ⇒ void
Return true if the data has the type.
-
#define_deferred_pione_method(name, inputs, output, &b) ⇒ Object
Define PIONE methods.
-
#define_pione_method(name, inputs, output, &b) ⇒ Object
Define PIONE methods.
-
#find_method(env, name, rec, args) ⇒ Object
Find named method.
- #fold1(val, seq1, &b) ⇒ Object
-
#initialize(*args) ⇒ Type
constructor
Create a type for PIONE model object.
- #inspect ⇒ Object
- #map1(seq, &b) ⇒ Object
- #map2(seq1, seq2, &b) ⇒ Object
-
#match(env, target) ⇒ Boolean
Return true if the type or the pione model object matches.
- #sequence_class ⇒ Object
- #sequential_fold1(type, seq1, &b) ⇒ Object
- #sequential_fold2(type, seq1, seq2, &b) ⇒ Object
- #sequential_map1(type, seq1, &b) ⇒ Object
- #sequential_map2(type, seq1, seq2, &b) ⇒ Object
- #sequential_map3(type, seq1, seq2, seq3, &b) ⇒ Object
- #sequential_pred1(seq1, &b) ⇒ Object
- #sequential_pred2(seq1, seq2, &b) ⇒ Object
- #to_s ⇒ Object
Constructor Details
Class Attribute Details
.table ⇒ Object (readonly)
Returns the value of attribute table.
8 9 10 |
# File 'lib/pione/lang/type.rb', line 8 def table @table end |
Instance Method Details
#check(env, data) ⇒ void
This method returns an undefined value.
Return true if the data has the type.
77 78 79 80 81 |
# File 'lib/pione/lang/type.rb', line 77 def check(env, data) unless match(env, data) raise LangTypeError.new(data, self, env) end end |
#define_deferred_pione_method(name, inputs, output, &b) ⇒ Object
Define PIONE methods. Arguments are non-evaluated.
70 71 72 |
# File 'lib/pione/lang/type.rb', line 70 def define_deferred_pione_method(name, inputs, output, &b) (pione_method[name] ||= []) << PioneMethod.new(:deferred, name, inputs, output, b) end |
#define_pione_method(name, inputs, output, &b) ⇒ Object
Define PIONE methods. Arguments are evaluated immediately.
65 66 67 |
# File 'lib/pione/lang/type.rb', line 65 def define_pione_method(name, inputs, output, &b) (pione_method[name] ||= []) << PioneMethod.new(:immediate, name, inputs, output, b) end |
#find_method(env, name, rec, args) ⇒ Object
Find named method.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/pione/lang/type.rb', line 37 def find_method(env, name, rec, args) # find a suitable method if pione_method.has_key?(name) group = pione_method[name].group_by{|m| m.method_type} # exist deferred methods if group.has_key?(:deferred) if m = group[:deferred].find {|m| m.validate_inputs(env, rec, args)} return m end end # try immediate methods _args = args.map {|arg| arg.pione_type(env)} # FIXME : should be replaced by type inference if group.has_key?(:immediate) return group[:immediate].find {|m| m.validate_inputs(env, rec, _args)} else return nil end end # find from parent type if parent_type return parent_type.find_method(env, name, rec, args) end end |
#fold1(val, seq1, &b) ⇒ Object
126 127 128 129 130 |
# File 'lib/pione/lang/type.rb', line 126 def fold1(val, seq1, &b) seq1.pieces.inject(val) do |obj, elt1| b.call(obj, elt1) end end |
#inspect ⇒ Object
169 170 171 |
# File 'lib/pione/lang/type.rb', line 169 def inspect "#<Type %s>" % name end |
#map1(seq, &b) ⇒ Object
87 88 89 |
# File 'lib/pione/lang/type.rb', line 87 def map1(seq, &b) sequence_class.of(seq.pieces.map{|elt| b.call(elt)}, seq.attribute) end |
#map2(seq1, seq2, &b) ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/pione/lang/type.rb', line 91 def map2(seq1, seq2, &b) seq1.pieces.map do |elt1| seq2.pieces.map do |elt2| b.call(elt1, elt2) end end.flatten.tap {|x| break sequence_class.new(x, seq1.attribute)} end |
#match(env, target) ⇒ Boolean
Return true if the type or the pione model object matches.
27 28 29 30 31 32 33 34 |
# File 'lib/pione/lang/type.rb', line 27 def match(env, target) target_type = target.kind_of?(Type) ? target : target.pione_type(env) while target_type do return true if self == target_type target_type = target_type.parent_type end return false end |
#sequence_class ⇒ Object
83 84 85 |
# File 'lib/pione/lang/type.rb', line 83 def sequence_class Type.table[self.name][:sequence_class] end |
#sequential_fold1(type, seq1, &b) ⇒ Object
132 133 134 135 136 137 |
# File 'lib/pione/lang/type.rb', line 132 def sequential_fold1(type, seq1, &b) seq_class = type_to_class(type) seq1.pieces.inject(seq_class.new([], seq1.attribute)) do |obj, elt1| b.call(elt1, obj) end end |
#sequential_fold2(type, seq1, seq2, &b) ⇒ Object
139 140 141 142 143 144 145 146 |
# File 'lib/pione/lang/type.rb', line 139 def sequential_fold2(type, seq1, seq2, &b) seq_class = type_to_class(type) seq1.pieces.inject(seq_class.new([], seq1.attribute)) do |obj1, elt1| seq2.pieces.inject(obj1) do |obj2, elt2| b.call(obj2, elt1, elt2) end end end |
#sequential_map1(type, seq1, &b) ⇒ Object
99 100 101 102 103 104 |
# File 'lib/pione/lang/type.rb', line 99 def sequential_map1(type, seq1, &b) seq_class = type_to_class(type) seq1.pieces.map do |elt1| seq_class.piece_class.new(b.call(elt1)) end.tap {|x| break seq_class.new(x, seq1.attribute)} end |
#sequential_map2(type, seq1, seq2, &b) ⇒ Object
106 107 108 109 110 111 112 113 |
# File 'lib/pione/lang/type.rb', line 106 def sequential_map2(type, seq1, seq2, &b) seq_class = type_to_class(type) seq1.pieces.map do |elt1| seq2.pieces.map do |elt2| seq_class.piece_class.new(b.call(elt1, elt2)) end end.flatten.tap {|x| break seq1.set(x, seq1.attribute)} end |
#sequential_map3(type, seq1, seq2, seq3, &b) ⇒ Object
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/pione/lang/type.rb', line 115 def sequential_map3(type, seq1, seq2, seq3, &b) seq_class = type_to_class(type) seq1.pieces.map do |elt1| seq2.pieces.map do |elt2| seq3.pieces.map do |elt3| seq_class.piece_class.new(b.call(elt1, elt2, elt3)) end end end.flatten.tap {|x| break seq_class.new(x, seq1.attribute)} end |
#sequential_pred1(seq1, &b) ⇒ Object
148 149 150 151 152 153 |
# File 'lib/pione/lang/type.rb', line 148 def sequential_pred1(seq1, &b) method1 = seq1.every? ? :all? : :any? seq1.pieces.send(method1) do |elt1| PioneBoolean.new(b.call(elt1)) end.tap {|x| break BooleanSequence.new(x)} end |
#sequential_pred2(seq1, seq2, &b) ⇒ Object
155 156 157 158 159 160 161 162 163 |
# File 'lib/pione/lang/type.rb', line 155 def sequential_pred2(seq1, seq2, &b) method1 = seq1.every? ? :all? : :any? method2 = seq2.every? ? :all? : :any? seq1.pieces.send(method1) do |elt1| seq2.pieces.send(method2) do |elt2| b.call(elt1, elt2) end end.tap {|x| break BooleanSequence.new([PioneBoolean.new(x)])} end |
#to_s ⇒ Object
165 166 167 |
# File 'lib/pione/lang/type.rb', line 165 def to_s "#<Type %s>" % name end |