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