lib: Split collections into readable and writable
[nit.git] / src / compiling / compiling_global.nit
index 016ebf9..f883907 100644 (file)
@@ -98,69 +98,66 @@ special ColorContext
        init(c: MMLocalClass) do _local_class = c
 end
 
-redef class MMGlobalProperty
-       # The position of the property in the local class table part
-       # FIXME: It's ugly. store this somewhere else please
-       readable writable attr _pos_of: Int 
-end
-
 redef class MMSrcLocalClass
        # The table element of the subtype check
-       readable attr _class_color_pos: TableEltClassColorPos
+       readable attr _class_color_pos: TableEltClassColor
 
        # The proper local class table part (nor superclasses nor refinments)
-       readable attr _class_layout: Array[LocalTableElt] 
+       readable attr _class_layout: Array[TableElt] 
 
        # The proper local instance table part (nor superclasses nor refinments)
-       readable attr _instance_layout: Array[LocalTableElt] 
+       readable attr _instance_layout: Array[TableElt] 
 
        # Build the local layout of the class and feed the module table
-       meth build_layout_in(tc: ToolContext, module_table: Array[LocalTableElt])
+       meth build_layout_in(tc: ToolContext, module_table: Array[ModuleTableElt])
        do
-               var intro_methods = new Array[MMGlobalProperty] # FIXME: Remove this
-               var intro_attributes = new Array[MMGlobalProperty] # FIXME: Remove this
-               var clt = new Array[LocalTableElt]
+               var clt = new Array[TableElt]
                _class_layout = clt
-               var ilt = new Array[LocalTableElt]
+               var ilt = new Array[TableElt]
                _instance_layout = ilt
 
                if global.intro == self then
-                       module_table.add(new TableEltClassIdPos(self))
-                       _class_color_pos = new TableEltClassColorPos(self)
+                       module_table.add(new TableEltClassId(self))
+                       _class_color_pos = new TableEltClassColor(self)
                        module_table.add(_class_color_pos)
-                       #clt.add(_class_color_pos)
-                       clt.add(new TableEltClassInitTablePos(self))
+                       clt.add(new TableEltClassInitTable(self))
                end
                for p in src_local_properties do
                        var pg = p.global
                        if pg.intro == p then
                                if p isa MMSrcAttribute then
-                                       pg.pos_of = intro_attributes.length
-                                       intro_attributes.add(pg)
-                                       ilt.add(new TableEltAttrPos(p))
+                                       ilt.add(new TableEltAttr(p))
                                else if p isa MMSrcMethod then
-                                       pg.pos_of = intro_methods.length
-                                       intro_methods.add(pg)
-                                       clt.add(new TableEltMethPos(p))
+                                       clt.add(new TableEltMeth(p))
                                end
                        end
                        if p isa MMSrcMethod and p.need_super then
-                               clt.add(new TableEltSuperPos(p))
+                               clt.add(new TableEltSuper(p))
                        end
                end
-               module_table.append(ilt)
-               module_table.append(clt)
+
+               if not ilt.is_empty then
+                       var teg = new ModuleTableEltGroup
+                       teg.elements.append(ilt)
+                       module_table.add(teg)
+               end
+
+               if not clt.is_empty then
+                       var teg = new ModuleTableEltGroup
+                       teg.elements.append(clt)
+                       module_table.add(teg)
+               end
        end
 end
 
 redef class MMSrcModule
        # The local table of the module (refers things introduced in the module)
-       attr _local_table: Array[LocalTableElt]
+       attr _local_table: Array[ModuleTableElt]
 
        # Builds the local tables and local classes layouts
        meth local_analysis(tc: ToolContext)
        do
-               var lt = new Array[LocalTableElt]
+               var lt = new Array[ModuleTableElt]
                _local_table = lt
                for c in src_local_classes do
                        c.build_layout_in(tc, lt)
@@ -424,7 +421,7 @@ redef class MMSrcModule
                for c in local_classes do
                        c.compile_tables_to_c(v)
                end
-               var s = "classtable_t TAG2VFT[4] = \{NULL"
+               var s = new Buffer.from("classtable_t TAG2VFT[4] = \{NULL")
                for t in ["Int","Char","Bool"] do
                        if has_global_class_named(t.to_symbol) then
                                s.append(", (const classtable_t)VFT_{t}")
@@ -433,7 +430,7 @@ redef class MMSrcModule
                        end
                end
                s.append("};")
-               v.add_instr(s)
+               v.add_instr(s.to_s)
        end
 
        # Declare class table (for _sep.h)
@@ -482,27 +479,19 @@ redef class MMSrcModule
                end
                var i = 0
                for e in _local_table do
+                       var value: String
                        if v.tc.global then
-                               v.add_decl("#define {e.symbol} {e.value(v.global_analysis)}")
+                               value = "{e.value(v.global_analysis)}"
                        else
-                               v.add_decl("#define {e.symbol} SFT_{name}[{i}]")
+                               value = "SFT_{name}[{i}]"
                                i = i + 1
                        end
+                       e.compile_macros(v, value)
                end
                for c in src_local_classes do
                        for pg in c.global_properties do
                                var p = c[pg]
                                if p.local_class == c then
-                                       if pg.intro == p then
-                                               if p isa MMAttribute then
-                                                       v.add_decl("#define {pg.attr_access}(recv) ATTR(recv, {pg.color_id})")
-                                               else if p isa MMMethod then
-                                                       v.add_decl("#define {pg.meth_call}(recv) (({p.cname}_t)CALL((recv), {pg.color_id}))")
-                                               end
-                                       end
-                                       if p isa MMSrcMethod and p.need_super then
-                                               v.add_decl("#define {p.super_meth_call}(recv) (({p.cname}_t)CALL((recv), {p.color_id_for_super}))")
-                                       end
                                        p.compile_property_to_c(v)
                                end
                                if pg.is_init_for(c) then
@@ -536,24 +525,59 @@ redef class MMSrcModule
        end
 end
 
-class TableElt
+###############################################################################
+
+# An element of a class, an instance or a module table
+abstract class AbsTableElt
+       # Compile the macro needed to use the element and other related elements
+       meth compile_macros(v: CompilerVisitor, value: String) is abstract
+end
+
+# An element of a class or an instance table
+# Such an elements represent method function pointers, attribute values, etc.
+abstract class TableElt
+special AbsTableElt
+       # Is the element conflict to class `c' (used for coloring)
        meth is_related_to(c: MMLocalClass): Bool is abstract
+
+       # Number of sub-elements. 1 if none
        meth length: Int do return 1
+
+       # Access the ith subelement.
        meth item(i: Int): TableElt do return self
+
+       # Return the value of the element for a given class
        meth compile_to_c(v: CompilerVisitor, c: MMLocalClass): String is abstract
 end
 
-class LocalTableElt
-special TableElt
-       meth symbol: String is abstract
+# An element of a module table
+# Such an elements represent colors or identifiers
+abstract class ModuleTableElt
+special AbsTableElt
+       # Return the value of the element once the global analisys is performed
        meth value(ga: GlobalAnalysis): String is abstract
 end
 
-class TableEltPropPos
-special LocalTableElt
+# An element of a module table that represents a group of TableElt defined in the same local class
+class ModuleTableEltGroup
+special ModuleTableElt
+       readable attr _elements: Array[TableElt] = new Array[TableElt]
+
+       redef meth value(ga) do return "{ga.color(_elements.first)} /* Group of ? */"
+       redef meth compile_macros(v, value)
+       do
+               var i = 0
+               for e in _elements do
+                       e.compile_macros(v, "{value} + {i}")
+                       i += 1
+               end
+       end
+end
+
+# An element that represents a class property
+abstract class TableEltProp
+special TableElt
        attr _property: MMLocalProperty
-       redef meth symbol do return _property.global.color_id
-       redef meth value(ga) do return "{ga.color(self)} /* Property {_property} */"
 
        init(p: MMLocalProperty)
        do
@@ -561,19 +585,31 @@ special LocalTableElt
        end
 end
 
-class TableEltMethPos
-special TableEltPropPos
+# An element that represents a function pointer to a global method
+class TableEltMeth
+special TableEltProp
+       redef meth compile_macros(v, value)
+       do
+               var pg = _property.global
+               v.add_decl("#define {pg.meth_call}(recv) (({pg.intro.cname}_t)CALL((recv), ({value})))")
+       end
+
        redef meth compile_to_c(v, c)
        do
                var p = c[_property.global]
                return p.cname
        end
-       init(p) do super 
 end
 
-class TableEltSuperPos
-special TableEltPropPos
-       redef meth symbol do return _property.color_id_for_super
+# An element that represents a function pointer to the super method of a local method
+class TableEltSuper
+special TableEltProp
+       redef meth compile_macros(v, value)
+       do
+               var p = _property
+               v.add_decl("#define {p.super_meth_call}(recv) (({p.cname}_t)CALL((recv), ({value})))")
+       end
+
        redef meth compile_to_c(v, c)
        do
                var pc = _property.local_class
@@ -595,55 +631,73 @@ special TableEltPropPos
                assert false
                return null
        end
-
-       init(p) do super 
 end
 
-class TableEltAttrPos
-special TableEltPropPos
+# An element that represents the value stored for a global attribute
+class TableEltAttr
+special TableEltProp
+       redef meth compile_macros(v, value)
+       do
+               var pg = _property.global
+               v.add_decl("#define {pg.attr_access}(recv) ATTR(recv, ({value}))")
+       end
+
        redef meth compile_to_c(v, c)
        do
                var ga = v.global_analysis
                var p = c[_property.global]
                return "/* {ga.color(self)}: Attribute {c}::{p} */"
        end
-
-       init(p) do super 
 end
 
-class TableEltClassPos
-special LocalTableElt
+# An element representing a class information
+class AbsTableEltClass
+special AbsTableElt
+       # The local class where the information comes from
        attr _local_class: MMLocalClass
-       redef meth is_related_to(c)
-       do
-               var bc = c.module[_local_class.global]
-               return c.cshe <= bc
-       end
 
        init(c: MMLocalClass)
        do
                _local_class = c
        end
+
+       # The C macro name refering the value
+       meth symbol: String is abstract
+
+       redef meth compile_macros(v, value)
+       do
+               v.add_decl("#define {symbol} ({value})")
+       end
 end
 
-class TableEltClassIdPos
-special TableEltClassPos
+# An element of a class table representing a class information 
+class TableEltClass
+special TableElt
+special AbsTableEltClass
+       redef meth is_related_to(c)
+       do
+               var bc = c.module[_local_class.global]
+               return c.cshe <= bc
+       end
+end
+
+# An element representing the id of a class in a module table 
+class TableEltClassId
+special ModuleTableElt
+special AbsTableEltClass
        redef meth symbol do return _local_class.global.id_id
+
        redef meth value(ga)
        do
                return "{ga.compiled_classes[_local_class.global].id} /* Id of {_local_class} */"
        end
-
-       init(c) do super
 end
 
-class TableEltClassInitTablePos
-special TableEltClassPos
+# An element representing the constructor marker position in a class table
+class TableEltClassInitTable
+special TableEltClass
        redef meth symbol do return _local_class.global.init_table_pos_id
-       redef meth value(ga)
-       do
-               return "{ga.color(self)} /* Color of {_local_class} */"
-       end
+
        redef meth compile_to_c(v, c)
        do
                var ga = v.global_analysis
@@ -655,36 +709,40 @@ special TableEltClassPos
                end
                return "{i} /* {ga.color(self)}: {c} < {cc.local_class}: superclass init_table position */"
        end
-
-       init(c) do super
 end
 
-class TableEltClassColorPos
-special TableEltClassPos
+# An element used for a cast
+# Note: this element is both a TableElt and a ModuleTableElt.
+# At the TableElt offset, there is the id of the super-class
+# At the ModuleTableElt offset, there is the TableElt offset (ie. the color of the super-class).
+class TableEltClassColor
+special TableEltClass
+special ModuleTableElt
        redef meth symbol do return _local_class.global.color_id
+
        redef meth value(ga)
        do
                return "{ga.color(self)} /* Color of {_local_class} */"
        end
+
        redef meth compile_to_c(v, c)
        do
                var ga = v.global_analysis
                var cc = ga.compiled_classes[_local_class.global]
                return "{cc.id} /* {ga.color(self)}: {c} < {cc.local_class}: superclass typecheck marker */"
        end
-
-       init(c) do super
 end
 
+# A Group of elements introduced in the same global-class that are colored together
 class TableEltComposite
 special TableElt
-       attr _table: Array[LocalTableElt]
+       attr _table: Array[TableElt]
        attr _cc: CompiledClass
        attr _offsets: HashMap[MMLocalClass, Int]
        redef meth length do return _table.length
        redef meth is_related_to(c) do return c.cshe <= _cc.local_class
 
-       meth add(c: MMLocalClass, tab: Array[LocalTableElt])
+       meth add(c: MMLocalClass, tab: Array[TableElt])
        do
                _offsets[c] = _table.length
                _table.append(tab)
@@ -697,11 +755,12 @@ special TableElt
        init(cc: CompiledClass)
        do
                _cc = cc
-               _table = new Array[LocalTableElt]
+               _table = new Array[TableElt]
                _offsets = new HashMap[MMLocalClass, Int]
        end
 end
 
+# The element that represent the class id
 class TableEltClassSelfId
 special TableElt
        redef meth is_related_to(c) do return true
@@ -710,10 +769,9 @@ special TableElt
                var ga = v.global_analysis
                return "{v.global_analysis.compiled_classes[c.global].id} /* {ga.color(self)}: Identity */"
        end
-
-       init do end
 end
 
+# The element that 
 class TableEltVftPointer
 special TableElt
        redef meth is_related_to(c) do return true
@@ -722,10 +780,10 @@ special TableElt
                var ga = v.global_analysis
                return "/* {ga.color(self)}: Pointer to the classtable */"
        end
-
-       init do end
 end
 
+###############################################################################
+
 # Used to sort local class in a deterministic total order
 # The total order superset the class refinement and the class specialisation relations
 class ClassSorter