class Pione::Lang::Type
Type
is a class for type expression of PIONE model objects.
Attributes
table[R]
Public Class Methods
new(*args)
click to toggle source
Create a type for PIONE model object.
Calls superclass method
# File lib/pione/lang/type.rb, line 16 def initialize(*args) super(*args) Type.table[name] = {parent: parent_type} end
Public Instance Methods
check(env, data)
click to toggle source
Return true if the data has the type.
@return [void]
# 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)
click to toggle source
Define PIONE methods. Arguments are non-evaluated.
# 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)
click to toggle source
Define PIONE methods. Arguments are evaluated immediately.
# 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)
click to toggle source
Find named method.
# 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)
click to toggle source
# 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()
click to toggle source
# File lib/pione/lang/type.rb, line 169 def inspect "#<Type %s>" % name end
map1(seq, &b)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
Return true if the type or the pione model object matches.
@param [BasicModel] target
matching test target
@return [Boolean]
true if it matches, or false
# 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()
click to toggle source
# File lib/pione/lang/type.rb, line 83 def sequence_class Type.table[self.name][:sequence_class] end
sequential_fold1(type, seq1, &b)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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()
click to toggle source
# File lib/pione/lang/type.rb, line 165 def to_s "#<Type %s>" % name end