compiler: compile ASuperstringExpr using `native_to_s`
authorJean Privat <jean@pryen.org>
Sat, 21 Mar 2015 15:38:19 +0000 (22:38 +0700)
committerJean Privat <jean@pryen.org>
Tue, 24 Mar 2015 00:21:42 +0000 (07:21 +0700)
Signed-off-by: Jean Privat <jean@pryen.org>

src/compiler/abstract_compiler.nit
src/rapid_type_analysis.nit

index 88bbc2c..522230f 100644 (file)
@@ -2775,14 +2775,35 @@ end
 redef class ASuperstringExpr
        redef fun expr(v)
        do
-               var array = new Array[RuntimeVariable]
+               var type_string = mtype.as(not null)
+
+               # Collect elements of the superstring
+               var array = new Array[AExpr]
                for ne in self.n_exprs do
+                       # Drop literal empty string.
+                       # They appears in things like "{a}" that is ["", a, ""]
                        if ne isa AStringFormExpr and ne.value == "" then continue # skip empty sub-strings
-                       var i = v.expr(ne, null)
-                       array.add(i)
+                       array.add(ne)
                end
-               var a = v.array_instance(array, v.object_type)
-               var res = v.send(v.get_property("to_s", a.mtype), [a])
+
+               # The native array that will contains the elements to_s-ized.
+               # For fast concatenation.
+               var a = v.native_array_instance(type_string, v.int_instance(array.length))
+
+               # Stringify the elements and put them in the native array
+               var to_s_method = v.get_property("to_s", v.object_type)
+               for i in [0..array.length[ do
+                       var ne = array[i]
+                       var e = v.expr(ne, null)
+                       # Skip the `to_s` if the element is already a String
+                       if not e.mcasttype.is_subtype(v.compiler.mainmodule, null, type_string) then
+                               e = v.send(to_s_method, [e]).as(not null)
+                       end
+                       v.native_array_set(a, i, e)
+               end
+
+               # Fast join the native string to get the result
+               var res = v.send(v.get_property("native_to_s", a.mtype), [a])
                return res
        end
 end
index bcae37f..69e9023 100644 (file)
@@ -560,11 +560,13 @@ redef class ASuperstringExpr
                var object_type = mmodule.object_type
                var arraytype = mmodule.array_type(object_type)
                v.add_type(arraytype)
-               v.add_type(mmodule.native_array_type(object_type))
+               var nattype = mmodule.native_array_type(object_type)
+               v.add_type(nattype)
                var prop = v.get_method(arraytype, "join")
                v.add_monomorphic_send(arraytype, prop)
                var prop2 = v.get_method(arraytype, "with_native")
                v.add_monomorphic_send(arraytype, prop2)
+               v.add_monomorphic_send(nattype, v.get_method(nattype, "native_to_s"))
        end
 end