ni_nitdoc: added fast copy past utility to signatures.
[nit.git] / src / primitive_info.nit
index db9d38b..039cc88 100644 (file)
 # Common things for NIT compilation and C generation
 package primitive_info
 
-#FIXME Split this package into 2: one in metamodel and one in compiling
+#FIXME Split this module into 2: one in metamodel and one in compiling
 
 import metamodel
 
 redef class MMLocalClass
+       # extern type of extern classes
+       fun extern_c_type : String is abstract
+
        # Cached primitive_info result
        var _primitive_info_cache: nullable PrimitiveInfo = null
 
@@ -30,7 +33,6 @@ redef class MMLocalClass
 
        # Return the primitive information of the class.
        # Return null if the class is not primitive
-       # FIXME: Only here since there is no universal type yet
        fun primitive_info: nullable PrimitiveInfo
        do
                if _primitive_info_b == true then return _primitive_info_cache
@@ -41,11 +43,17 @@ redef class MMLocalClass
                        _primitive_info_b = true
                        return _primitive_info_cache
                end
+               if global.is_extern then
+                       var pi = new PrimitiveInfo( name, false, extern_c_type )
+                       _primitive_info_cache = pi
+                       _primitive_info_b = true
+                       return _primitive_info_cache
+               end
                var i = ctypes.iterator
                while i.is_ok do
                        var n = i.key
-                       if module.has_global_class_named(n) then
-                               var c = module.class_by_name(n)
+                       if mmmodule.has_global_class_named(n) then
+                               var c = mmmodule.class_by_name(n)
                                if cshe < c then
                                        _primitive_info_cache = i.item
                                        _primitive_info_b = true
@@ -62,9 +70,9 @@ redef class MMLocalClass
        private fun primitive_ctypes: HashMap[Symbol, PrimitiveInfo]
        do
                var res = new HashMap[Symbol, PrimitiveInfo]
-               var pnames = ["Int",    "Char", "Bool", "Float", "NativeString", "NativeArray", "Pointer"]
-               var tagged = [true,     true,   true,   false,   false,          false,         false]
-               var cnames = ["bigint", "char", "int",  "float", "char *",       "val_t *",     "void *"]
+               var pnames = ["Int",    "Char", "Bool", "Float", "NativeString", "Pointer"]
+               var tagged = [true,     true,   true,   false,   false,          false]
+               var cnames = ["bigint", "char", "int",  "float", "char *",       "void *"]
                for i in [0..pnames.length[ do
                        var n = pnames[i].to_symbol
                        var pi = new PrimitiveInfo(n, tagged[i], cnames[i])
@@ -130,7 +138,7 @@ redef class MMType
        fun boxtype(s: String): String
        do
                var pi = local_class.primitive_info
-               if pi == null then
+               if pi == null or is_nullable then
                        return s
                else if pi.tagged then
                        return "TAG_{local_class.name}({s})"
@@ -144,7 +152,7 @@ redef class MMType
        fun unboxtype(s: String): String
        do
                var pi = local_class.primitive_info
-               if pi == null then
+               if pi == null or is_nullable then
                        return s
                else if pi.tagged then
                        return "UNTAG_{local_class.name}({s})"
@@ -154,3 +162,65 @@ redef class MMType
        end
 end
 
+redef class MMMethod
+       fun default_extern_name : String
+       do
+               return "{friendly_extern_name(local_class)}___impl"
+       end
+
+       # Friendly name for this method. Is mainly the class name followed by the
+       # function name. It is prefixed with "new" for a constructor.
+       fun friendly_extern_name( local_class : MMLocalClass ) : String
+       do
+               if not global.is_init then
+                       var native_fun_name : String
+                       var method_name = name.to_s
+                       if method_name == "+" then
+                               native_fun_name = "_plus" # add
+                       else if method_name == "-" then
+                               native_fun_name = "_minus" # sub
+                       else if method_name == "*" then
+                               native_fun_name = "_star" # multi
+                       else if method_name == "/" then
+                               native_fun_name = "_slash" # div
+                       else if method_name == "%" then
+                               native_fun_name = "_percent" # mod
+                       else if method_name == "[]" then
+                               native_fun_name = "_index" # brackets
+                       else if method_name == "[]=" then
+                               native_fun_name = "_index_assign" # brackets
+                       else if method_name == "==" then
+                               native_fun_name = "_equal" # eq
+                       else if method_name == "<" then
+                               native_fun_name = "_less" # lt
+                       else if method_name == ">" then
+                               native_fun_name = "_greater" # gt
+                       else if method_name == "<=" then
+                               native_fun_name = "_less_or_equal" # greater_or_equal
+                       else if method_name == ">=" then
+                               native_fun_name = "_ge" # smaller_or_equal
+                       else if method_name == "!=" then
+                               native_fun_name = "_not_equal" # bang
+                       else if method_name == ">>" then
+                               native_fun_name = "_right"
+                       else if method_name == "<<" then
+                               native_fun_name = "_left"
+                       else if method_name == "<=>" then
+                               native_fun_name = "_starship"
+                       else if method_name[ method_name.length-1 ] == '=' then
+                               native_fun_name = "{method_name.substring(0,method_name.length-1)}__assign"
+                       else
+                               native_fun_name = method_name
+                       end
+
+                       return "{local_class.name}_{native_fun_name}"
+               else
+                       if name == once "init".to_symbol then
+                               return "new_{local_class.name}"
+                       else
+                               return "new_{local_class.name}_{name}"
+                       end
+               end
+       end
+end
+