# Generate code that initialize the attributes on a new instance
fun generate_init_attr(v: VISITOR, recv: RuntimeVariable, mtype: MClassType)
do
- for cd in mtype.collect_mclassdefs(self.mainmodule)
- do
+ var cds = mtype.collect_mclassdefs(self.mainmodule).to_a
+ self.mainmodule.linearize_mclassdefs(cds)
+ for cd in cds do
var n = self.modelbuilder.mclassdef2nclassdef[cd]
for npropdef in n.n_propdefs do
if npropdef isa AAttrPropdef then
# Generate code that check if an attribute is correctly initialized
fun generate_check_attr(v: VISITOR, recv: RuntimeVariable, mtype: MClassType)
do
- for cd in mtype.collect_mclassdefs(self.mainmodule)
- do
+ var cds = mtype.collect_mclassdefs(self.mainmodule).to_a
+ self.mainmodule.linearize_mclassdefs(cds)
+ for cd in cds do
var n = self.modelbuilder.mclassdef2nclassdef[cd]
for npropdef in n.n_propdefs do
if npropdef isa AAttrPropdef then
end
end
+ # Generate a super call from a method definition
+ fun supercall(m: MMethodDef, recvtype: MClassType, args: Array[RuntimeVariable]): nullable RuntimeVariable is abstract
+
fun adapt_signature(m: MMethodDef, args: Array[RuntimeVariable]) is abstract
# Box or unbox a value to another type iff a C type conversion is needed
fun monomorphic_send(m: MMethod, t: MType, args: Array[RuntimeVariable]): nullable RuntimeVariable
do
assert t isa MClassType
- var propdefs = m.lookup_definitions(self.compiler.mainmodule, t)
- if propdefs.length == 0 then
- abort
- end
- if propdefs.length > 1 then
- self.debug("NOT YET IMPLEMENTED conflict for {t}.{m}: {propdefs.join(" ")}. choose the first")
- end
- var propdef = propdefs.first
+ var propdef = m.lookup_first_definition(self.compiler.mainmodule, t)
return self.call(propdef, t, args)
end
end
end
-redef class ANode
- type VISITOR: AbstractCompilerVisitor
-end
+# Node visit
redef class APropdef
- fun compile_to_c(v: VISITOR, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])
+ fun compile_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])
do
v.add("printf(\"NOT YET IMPLEMENTED {class_name} {mpropdef} at {location.to_s}\\n\");")
debug("Not yet implemented")
end
end
- fun init_expr(v: VISITOR, recv: RuntimeVariable)
+ fun init_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable)
do
var nexpr = self.n_expr
if nexpr != null then
end
end
- fun check_expr(v: VISITOR, recv: RuntimeVariable)
+ fun check_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable)
do
var nexpr = self.n_expr
if nexpr != null then return
end
redef class AClassdef
- private fun compile_to_c(v: VISITOR, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])
+ private fun compile_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])
do
if mpropdef == self.mfree_init then
var super_inits = self.super_inits
redef class AExpr
# Try to compile self as an expression
# Do not call this method directly, use `v.expr' instead
- private fun expr(v: VISITOR): nullable RuntimeVariable
+ private fun expr(v: AbstractCompilerVisitor): nullable RuntimeVariable
do
v.add("printf(\"NOT YET IMPLEMENTED {class_name}:{location.to_s}\\n\");")
var mtype = self.mtype
# Try to compile self as a statement
# Do not call this method directly, use `v.stmt' instead
- private fun stmt(v: VISITOR)
+ private fun stmt(v: AbstractCompilerVisitor)
do
var res = expr(v)
if res != null then v.add("{res};")
end
# stantard call-next-method
- var mpropdef = v.frame.mpropdef
- # FIXME: we do not want an ugly static call!
- var mpropdefs = mpropdef.mproperty.lookup_super_definitions(mpropdef.mclassdef.mmodule, mpropdef.mclassdef.bound_mtype)
- if mpropdefs.length != 1 then
- v.add("printf(\"NOT YET IMPLEMENTED {class_name} {mpropdef} at {location.to_s}\\n\");")
- debug("MPRODFEFS for super {mpropdef} for {recv}: {mpropdefs.join(", ")}")
- end
- mpropdef = mpropdefs.first
- assert mpropdef isa MMethodDef
- var res = v.call(mpropdef, recv.mtype.as(MClassType), args)
- return res
+ return v.supercall(v.frame.mpropdef.as(MMethodDef), recv.mtype.as(MClassType), args)
end
end
do
# do nothing
end
-end
\ No newline at end of file
+end
+
+# Utils
+
+redef class HashSet[E]
+ init from(elements: Collection[E]) do
+ init
+ self.add_all(elements)
+ end
+end
+
+redef class Array[E]
+ init from(elements: Collection[E]) do
+ init
+ self.add_all(elements)
+ end
+
+ # Return a new Array with the elements only contened in 'self' and not in 'o'
+ fun -(o: Array[E]): Array[E] do
+ var res = new Array[E]
+ for e in self do if not o.has(e) then res.add(e)
+ return res
+ end
+end
+
+redef class MModule
+
+ # Return a linearization of a set of mtypes
+ fun linearize_mtypes(mtypes: Set[MType]): Array[MType] do
+ var lin = new Array[MType].from(mtypes)
+ var sorter = new TypeSorter(self)
+ sorter.sort(lin)
+ return lin
+ end
+
+ # Return a reverse linearization of a set of mtypes
+ fun reverse_linearize_mtypes(mtypes: Set[MType]): Array[MType] do
+ var lin = new Array[MType].from(mtypes)
+ var sorter = new ReverseTypeSorter(self)
+ sorter.sort(lin)
+ return lin
+ end
+
+ # Return super types of a `mtype` in `self`
+ fun super_mtypes(mtype: MType, mtypes: Set[MType]): Set[MType] do
+ if not self.super_mtypes_cache.has_key(mtype) then
+ var supers = new HashSet[MType]
+ for otype in mtypes do
+ if otype == mtype then continue
+ if mtype.is_subtype(self, null, otype) then
+ supers.add(otype)
+ end
+ end
+ self.super_mtypes_cache[mtype] = supers
+ end
+ return self.super_mtypes_cache[mtype]
+ end
+
+ private var super_mtypes_cache: Map[MType, Set[MType]] = new HashMap[MType, Set[MType]]
+
+ # Return all sub mtypes (directs and indirects) of a `mtype` in `self`
+ fun sub_mtypes(mtype: MType, mtypes: Set[MType]): Set[MType] do
+ if not self.sub_mtypes_cache.has_key(mtype) then
+ var subs = new HashSet[MType]
+ for otype in mtypes do
+ if otype == mtype then continue
+ if otype.is_subtype(self, null, mtype) then
+ subs.add(otype)
+ end
+ end
+ self.sub_mtypes_cache[mtype] = subs
+ end
+ return self.sub_mtypes_cache[mtype]
+ end
+
+ private var sub_mtypes_cache: Map[MType, Set[MType]] = new HashMap[MType, Set[MType]]
+
+ # Return a linearization of a set of mclasses
+ fun linearize_mclasses_2(mclasses: Set[MClass]): Array[MClass] do
+ var lin = new Array[MClass].from(mclasses)
+ var sorter = new ClassSorter(self)
+ sorter.sort(lin)
+ return lin
+ end
+
+ # Return a reverse linearization of a set of mtypes
+ fun reverse_linearize_mclasses(mclasses: Set[MClass]): Array[MClass] do
+ var lin = new Array[MClass].from(mclasses)
+ var sorter = new ReverseClassSorter(self)
+ sorter.sort(lin)
+ return lin
+ end
+
+ # Return all super mclasses (directs and indirects) of a `mclass` in `self`
+ fun super_mclasses(mclass: MClass): Set[MClass] do
+ if not self.super_mclasses_cache.has_key(mclass) then
+ var supers = new HashSet[MClass]
+ if self.flatten_mclass_hierarchy.has(mclass) then
+ for sup in self.flatten_mclass_hierarchy[mclass].greaters do
+ if sup == mclass then continue
+ supers.add(sup)
+ end
+ end
+ self.super_mclasses_cache[mclass] = supers
+ end
+ return self.super_mclasses_cache[mclass]
+ end
+
+ private var super_mclasses_cache: Map[MClass, Set[MClass]] = new HashMap[MClass, Set[MClass]]
+
+ # Return all parents of a `mclass` in `self`
+ fun parent_mclasses(mclass: MClass): Set[MClass] do
+ if not self.parent_mclasses_cache.has_key(mclass) then
+ var parents = new HashSet[MClass]
+ if self.flatten_mclass_hierarchy.has(mclass) then
+ for sup in self.flatten_mclass_hierarchy[mclass].direct_greaters do
+ if sup == mclass then continue
+ parents.add(sup)
+ end
+ end
+ self.parent_mclasses_cache[mclass] = parents
+ end
+ return self.parent_mclasses_cache[mclass]
+ end
+
+ private var parent_mclasses_cache: Map[MClass, Set[MClass]] = new HashMap[MClass, Set[MClass]]
+
+ # Return all sub mclasses (directs and indirects) of a `mclass` in `self`
+ fun sub_mclasses(mclass: MClass): Set[MClass] do
+ if not self.sub_mclasses_cache.has_key(mclass) then
+ var subs = new HashSet[MClass]
+ if self.flatten_mclass_hierarchy.has(mclass) then
+ for sub in self.flatten_mclass_hierarchy[mclass].smallers do
+ if sub == mclass then continue
+ subs.add(sub)
+ end
+ end
+ self.sub_mclasses_cache[mclass] = subs
+ end
+ return self.sub_mclasses_cache[mclass]
+ end
+
+ private var sub_mclasses_cache: Map[MClass, Set[MClass]] = new HashMap[MClass, Set[MClass]]
+
+ # All 'mproperties' associated to all 'mclassdefs' of `mclass`
+ fun properties(mclass: MClass): Set[MProperty] do
+ if not self.properties_cache.has_key(mclass) then
+ var properties = new HashSet[MProperty]
+ var parents = self.super_mclasses(mclass)
+ for parent in parents do
+ properties.add_all(self.properties(parent))
+ end
+
+ for mclassdef in mclass.mclassdefs do
+ for mpropdef in mclassdef.mpropdefs do
+ properties.add(mpropdef.mproperty)
+ end
+ end
+ self.properties_cache[mclass] = properties
+ end
+ return properties_cache[mclass]
+ end
+
+ private var properties_cache: Map[MClass, Set[MProperty]] = new HashMap[MClass, Set[MProperty]]
+end
+
+# A sorter for linearize list of types
+private class TypeSorter
+ super AbstractSorter[MType]
+
+ private var mmodule: MModule
+
+ init(mmodule: MModule) do self.mmodule = mmodule
+
+ redef fun compare(a, b) do
+ if a == b then
+ return 0
+ else if a.is_subtype(self.mmodule, null, b) then
+ return -1
+ end
+ return 1
+ end
+end
+
+# A sorter for reverse linearization
+private class ReverseTypeSorter
+ super TypeSorter
+
+ init(mmodule: MModule) do end
+
+ redef fun compare(a, b) do
+ if a == b then
+ return 0
+ else if a.is_subtype(self.mmodule, null, b) then
+ return 1
+ end
+ return -1
+ end
+end
+
+# A sorter for linearize list of classes
+private class ClassSorter
+ super AbstractSorter[MClass]
+
+ var mmodule: MModule
+
+ redef fun compare(a, b) do
+ if a == b then
+ return 0
+ else if self.mmodule.flatten_mclass_hierarchy.has(a) and self.mmodule.flatten_mclass_hierarchy[a].greaters.has(b) then
+ return -1
+ end
+ return 1
+ end
+end
+
+# A sorter for reverse linearization
+private class ReverseClassSorter
+ super AbstractSorter[MClass]
+
+ var mmodule: MModule
+
+ redef fun compare(a, b) do
+ if a == b then
+ return 0
+ else if self.mmodule.flatten_mclass_hierarchy.has(a) and self.mmodule.flatten_mclass_hierarchy[a].greaters.has(b) then
+ return 1
+ end
+ return -1
+ end
+end