Class: Emfrp::Typing::UnionType
- Inherits:
-
Object
- Object
- Emfrp::Typing::UnionType
- Defined in:
- lib/emfrp/typing/union_type.rb
Defined Under Namespace
Classes: UnifyError
Constant Summary collapse
- NameCounter =
(0..10000).to_a
Instance Attribute Summary collapse
-
#name_id ⇒ Object
Returns the value of attribute name_id.
-
#original_typevar_name ⇒ Object
Returns the value of attribute original_typevar_name.
-
#typeargs ⇒ Object
readonly
Returns the value of attribute typeargs.
-
#typename ⇒ Object
readonly
Returns the value of attribute typename.
-
#union ⇒ Object
Returns the value of attribute union.
Class Method Summary collapse
Instance Method Summary collapse
- #clone_utype(tbl = {}) ⇒ Object
- #collect_union(visited = {}) ⇒ Object
- #has_var? ⇒ Boolean
- #include?(other) ⇒ Boolean
-
#initialize(*args) ⇒ UnionType
constructor
A new instance of UnionType.
- #inspect ⇒ Object
- #match?(other) ⇒ Boolean
- #occur_check(var) ⇒ Object
- #to_flatten_uniq_str ⇒ Object
- #to_uniq_str ⇒ Object
- #transform(other) ⇒ Object
- #typevars ⇒ Object
- #unify(other) ⇒ Object
- #unite(a, b) ⇒ Object
- #var? ⇒ Boolean
Constructor Details
#initialize(*args) ⇒ UnionType
Returns a new instance of UnionType.
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/emfrp/typing/union_type.rb', line 36 def initialize(*args) if args.length == 2 @typename = args[0] @typeargs = args[1] elsif args.length == 0 @union = [self] @name_id = NameCounter.shift @original_name_id = @name_id else raise "Wrong number of arguments (#{args.length} for 0, 2)" end end |
Instance Attribute Details
#name_id ⇒ Object
Returns the value of attribute name_id.
12 13 14 |
# File 'lib/emfrp/typing/union_type.rb', line 12 def name_id @name_id end |
#original_typevar_name ⇒ Object
Returns the value of attribute original_typevar_name.
12 13 14 |
# File 'lib/emfrp/typing/union_type.rb', line 12 def original_typevar_name @original_typevar_name end |
#typeargs ⇒ Object (readonly)
Returns the value of attribute typeargs.
11 12 13 |
# File 'lib/emfrp/typing/union_type.rb', line 11 def typeargs @typeargs end |
#typename ⇒ Object (readonly)
Returns the value of attribute typename.
11 12 13 |
# File 'lib/emfrp/typing/union_type.rb', line 11 def typename @typename end |
#union ⇒ Object
Returns the value of attribute union.
12 13 14 |
# File 'lib/emfrp/typing/union_type.rb', line 12 def union @union end |
Class Method Details
.from_type(type, tbl = {}) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/emfrp/typing/union_type.rb', line 15 def self.from_type(type, tbl={}) case type when Emfrp::Type new(type[:name][:desc], type[:args].map{|a| from_type(a, tbl)}) when TypeVar name = type[:name][:desc] if tbl[name] tbl[name] else a = new() tbl[name] = a a.original_typevar_name = name a end when UnionType type else raise "unexpected type #{type.class} (bug)" end end |
Instance Method Details
#clone_utype(tbl = {}) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/emfrp/typing/union_type.rb', line 114 def clone_utype(tbl={}) if self.var? if tbl[self] tbl[self] else alt = self.class.new self.union.each{|t| tbl[t] = alt} alt end else self.class.new(self.typename, self.typeargs.map{|t| t.clone_utype(tbl)}) end end |
#collect_union(visited = {}) ⇒ Object
93 94 95 96 97 98 |
# File 'lib/emfrp/typing/union_type.rb', line 93 def collect_union(visited={}) return [] if visited[self] visited[self] = true res = @union + @union.map{|t| t.collect_union(visited)}.flatten return res.uniq end |
#has_var? ⇒ Boolean
77 78 79 80 81 82 83 |
# File 'lib/emfrp/typing/union_type.rb', line 77 def has_var? if self.var? true else self.typeargs.any?{|x| x.has_var?} end end |
#include?(other) ⇒ Boolean
67 68 69 70 71 72 73 74 75 |
# File 'lib/emfrp/typing/union_type.rb', line 67 def include?(other) if self.match?(other) true elsif !self.var? self.typeargs.any?{|x| x.include?(other)} else false end end |
#inspect ⇒ Object
186 187 188 189 190 191 192 193 194 |
# File 'lib/emfrp/typing/union_type.rb', line 186 def inspect if self.var? #"a#{self.name_id}[#{@original_name_id}]" + (@original_typevar_name ? "(#{@original_typevar_name})" : "") "a#{self.name_id}" + (@original_typevar_name ? "(#{@original_typevar_name})" : "") else args = self.typeargs.size > 0 ? "[#{self.typeargs.map{|t| t.inspect}.join(", ")}]" : "" "#{self.typename}#{args}" end end |
#match?(other) ⇒ Boolean
53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/emfrp/typing/union_type.rb', line 53 def match?(other) if self.var? && other.var? self.name_id == other.name_id elsif !self.var? && !other.var? if self.typename == other.typename && self.typeargs.size == other.typeargs.size self.typeargs.zip(other.typeargs).all?{|a, b| a.match?(b)} else false end else false end end |
#occur_check(var) ⇒ Object
152 153 154 155 156 157 158 159 |
# File 'lib/emfrp/typing/union_type.rb', line 152 def occur_check(var) if !self.var? self.typeargs.each{|t| t.occur_check(var)} end if self == var raise UnifyError.new(nil, nil) end end |
#to_flatten_uniq_str ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/emfrp/typing/union_type.rb', line 174 def to_flatten_uniq_str if self.var? raise "error" end if self.typeargs.size > 0 args = self.typeargs.map{|t| t.to_flatten_uniq_str}.join("_") "#{self.typename}_#{args}" else "#{self.typename}" end end |
#to_uniq_str ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/emfrp/typing/union_type.rb', line 161 def to_uniq_str if self.var? raise "error" end if self.typeargs.size > 0 args = self.typeargs.map{|t| t.to_uniq_str}.join(", ") "#{self.typename}[#{args}]" else "#{self.typename}" end end |
#transform(other) ⇒ Object
108 109 110 111 112 |
# File 'lib/emfrp/typing/union_type.rb', line 108 def transform(other) @typename = other.typename @typeargs = other.typeargs @union = nil end |
#typevars ⇒ Object
100 101 102 103 104 105 106 |
# File 'lib/emfrp/typing/union_type.rb', line 100 def typevars if var? [self] else typeargs.map{|t| t.typevars}.flatten end end |
#unify(other) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/emfrp/typing/union_type.rb', line 128 def unify(other) if !self.var? && !other.var? if self.typename == other.typename && self.typeargs.size == other.typeargs.size self.typeargs.zip(other.typeargs).each{|t1, t2| t1.unify(t2)} else raise UnifyError.new(nil, nil) end elsif !self.var? && other.var? other.collect_union.each do |t| self.occur_check(t) t.transform(self) end elsif self.var? && !other.var? self.collect_union.each do |t| other.occur_check(t) t.transform(other) end else self.unite(self, other) end rescue UnifyError => err raise UnifyError.new(self, other) end |
#unite(a, b) ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/emfrp/typing/union_type.rb', line 85 def unite(a, b) new_union = (a.collect_union + b.collect_union).uniq substitute_id = new_union.map{|t| t.name_id}.min new_union.each{|t| t.name_id = substitute_id} a.union = new_union b.union = new_union end |
#var? ⇒ Boolean
49 50 51 |
# File 'lib/emfrp/typing/union_type.rb', line 49 def var? @union end |