Move primitive method selection.
authorJean Privat <jean@pryen.org>
Thu, 26 Feb 2009 11:31:52 +0000 (06:31 -0500)
committerJean Privat <jean@pryen.org>
Thu, 26 Feb 2009 11:31:52 +0000 (06:31 -0500)
Move primitive method selection from compiling_methods to typing.

src/compiling/compiling_methods.nit
src/syntax/syntax_base.nit
src/syntax/typing.nit

index ed0c4ab..4a56520 100644 (file)
@@ -1002,37 +1002,17 @@ redef class AForVardeclExpr
        redef meth compile_stmt(v)
        do
                var e = v.compile_expr(n_expr)
-               var prop = n_expr.stype.local_class.select_method(once "iterator".to_symbol)
-               if prop == null then
-                       printl("No iterator")
-                       return
-               end
-               var ittype = prop.signature.return_type
+               var ittype = meth_iterator.signature.return_type
                v.cfc.free_var(e)
                var iter = v.cfc.get_var
-               v.add_assignment(iter, prop.compile_call(v, [e]))
-               var prop2 = ittype.local_class.select_method(once "is_ok".to_symbol)
-               if prop2 == null then
-                       printl("No is_ok")
-                       return
-               end
-               var prop3 = ittype.local_class.select_method(once "item".to_symbol)
-               if prop3 == null then
-                       printl("No item")
-                       return
-               end
-               var prop4 = ittype.local_class.select_method(once "next".to_symbol)
-               if prop4 == null then
-                       printl("No next")
-                       return
-               end
+               v.add_assignment(iter, meth_iterator.compile_call(v, [e]))
                v.add_instr("while (true) \{ /*for*/")
                v.indent
                var ok = v.cfc.get_var
-               v.add_assignment(ok, prop2.compile_call(v, [iter]))
+               v.add_assignment(ok, meth_is_ok.compile_call(v, [iter]))
                v.add_instr("if (!UNTAG_Bool({ok})) break; /*for*/")
                v.cfc.free_var(ok)
-               var e = prop3.compile_call(v, [iter])
+               var e = meth_item.compile_call(v, [iter])
                e = v.ensure_var(e)
                var cname = v.cfc.register_variable(variable)
                v.add_assignment(cname, e)
@@ -1043,7 +1023,7 @@ redef class AForVardeclExpr
                        v.compile_stmt(n_block)
                end
                v.add_instr("{v.nmc.continue_label}: while(0);")
-               e = prop4.compile_call(v, [iter])
+               e = meth_next.compile_call(v, [iter])
                assert e == null
                v.unindent
                v.add_instr("}")
@@ -1196,9 +1176,8 @@ end
 redef class AStringFormExpr
        redef meth compile_expr(v)
        do
-               var prop = stype.local_class.select_method(once "with_native".to_symbol)
                compute_string_info
-               return prop.compile_constructor_call(v, stype , ["BOX_NativeString(\"{_cstring}\")", "TAG_Int({_cstring_length})"])
+               return meth_with_native.compile_constructor_call(v, stype , ["BOX_NativeString(\"{_cstring}\")", "TAG_Int({_cstring_length})"])
        end
 
        # The raw string value
@@ -1252,18 +1231,14 @@ end
 redef class ASuperstringExpr
        redef meth compile_expr(v)
        do
-               var prop = stype.local_class.select_method(once "init".to_symbol)
-               var recv = prop.compile_constructor_call(v, stype, new Array[String]) 
-
-               var prop2 = stype.local_class.select_method(once "append".to_symbol)
+               var recv = meth_init.compile_constructor_call(v, stype, new Array[String])
 
-               var prop3 = stype.local_class.select_method(once "to_s".to_symbol)
                for ne in n_exprs do
                        var e = v.ensure_var(v.compile_expr(ne))
                        if ne.stype != stype then
-                               v.add_assignment(e, prop3.compile_call(v, [e]))
+                               v.add_assignment(e, meth_to_s.compile_call(v, [e]))
                        end
-                       prop2.compile_call(v, [recv, e])
+                       meth_append.compile_call(v, [recv, e])
                end
 
                return recv
@@ -1280,13 +1255,11 @@ end
 redef class AArrayExpr
        redef meth compile_expr(v)
        do
-               var prop = stype.local_class.select_method(once "with_capacity".to_symbol)
-               var recv = prop.compile_constructor_call(v, stype, ["TAG_Int({n_exprs.length})"])
+               var recv = meth_with_capacity.compile_constructor_call(v, stype, ["TAG_Int({n_exprs.length})"])
 
-               var prop2 = stype.local_class.select_method(once "add".to_symbol)
                for ne in n_exprs do
                        var e = v.compile_expr(ne)
-                       prop2.compile_call(v, [recv, e])
+                       meth_add.compile_call(v, [recv, e])
                end
                return recv
        end
@@ -1295,20 +1268,10 @@ end
 redef class ARangeExpr
        redef meth compile_expr(v)
        do
-               var prop = stype.local_class.select_method(propname)
                var e = v.compile_expr(n_expr)
                var e2 = v.compile_expr(n_expr2)
-               return prop.compile_constructor_call(v, stype, [e, e2])
+               return meth_init.compile_constructor_call(v, stype, [e, e2])
        end
-       # The constructor that must be used for the range
-       protected meth propname: Symbol is abstract
-end
-
-redef class ACrangeExpr
-       redef meth propname do return once "init".to_symbol
-end
-redef class AOrangeExpr
-       redef meth propname do return once "without_last".to_symbol
 end
 
 redef class ASuperExpr
index 9605b87..77177c3 100644 (file)
@@ -256,6 +256,12 @@ end
 # Visitor used during the syntax analysis
 class AbsSyntaxVisitor
 special Visitor
+       # The root type Object
+       meth type_object: MMType
+       do
+               return _module.class_by_name(once ("Object".to_symbol)).get_type
+       end
+
        # The primitive type Bool
        meth type_bool: MMType
        do
index 04c1a62..93640e6 100644 (file)
@@ -461,6 +461,10 @@ redef class AForExpr
 end
 
 redef class AForVardeclExpr
+       readable attr _meth_iterator: MMMethod
+       readable attr _meth_is_ok: MMMethod
+       readable attr _meth_item: MMMethod
+       readable attr _meth_next: MMMethod
        redef meth after_typing(v)
        do
                v.variable_ctx = v.variable_ctx.sub
@@ -472,18 +476,28 @@ redef class AForVardeclExpr
                if not v.check_conform_expr(n_expr, v.type_collection) then
                        return
                end
-               var prop = expr_type.local_class.select_method(once ("iterator".to_symbol))
-               if prop == null then
+               _meth_iterator = expr_type.local_class.select_method(once ("iterator".to_symbol))
+               if _meth_iterator == null then
                        v.error(self, "Error: Collection MUST have an iterate method")
                        return
                end
-               var iter_type = prop.signature_for(expr_type).return_type
-               var prop2 = iter_type.local_class.select_method(once ("item".to_symbol))
-               if prop2 == null then
+               var iter_type = _meth_iterator.signature_for(expr_type).return_type
+               _meth_is_ok = iter_type.local_class.select_method(once ("is_ok".to_symbol))
+               if _meth_is_ok == null then
+                       v.error(self, "Error: {iter_type} MUST have an is_ok method")
+                       return
+               end
+               _meth_item = iter_type.local_class.select_method(once ("item".to_symbol))
+               if _meth_item == null then
                        v.error(self, "Error: {iter_type} MUST have an item method")
                        return
                end
-               var t = prop2.signature_for(iter_type).return_type
+               _meth_next = iter_type.local_class.select_method(once ("next".to_symbol))
+               if _meth_next == null then
+                       v.error(self, "Error: {iter_type} MUST have a next method")
+                       return
+               end
+               var t = _meth_item.signature_for(iter_type).return_type
                if not n_expr.is_self then t = t.not_for_self
                va.stype = t
        end
@@ -670,16 +684,28 @@ redef class ACharExpr
 end
 
 redef class AStringFormExpr
+       readable attr _meth_with_native: MMMethod
        redef meth after_typing(v)
        do
                _stype = v.type_string
+               _meth_with_native = _stype.local_class.select_method(once "with_native".to_symbol)
+               if _meth_with_native == null then v.error(self, "{_stype} MUST have a with_native method.")
        end
 end
 
 redef class ASuperstringExpr
+       readable attr _meth_init: MMMethod
+       readable attr _meth_append: MMMethod
+       readable attr _meth_to_s: MMMethod
        redef meth after_typing(v)
        do
                _stype = v.type_string
+               _meth_init = _stype.local_class.select_method(once "init".to_symbol)
+               if _meth_init == null then v.error(self, "{_stype} MUST have an init method.")
+               _meth_append = _stype.local_class.select_method(once "append".to_symbol)
+               if _meth_append == null then v.error(self, "{_stype} MUST have a append method.")
+               _meth_to_s = v.type_object.local_class.select_method(once "to_s".to_symbol)
+               if _meth_to_s == null then v.error(self, "Object MUST have a to_s method.")
        end
 end
 
@@ -691,7 +717,8 @@ redef class ANullExpr
 end
 
 redef class AArrayExpr
-       private meth stype=(t: MMType) do _stype = t
+       readable attr _meth_with_capacity: MMMethod
+       readable attr _meth_add: MMMethod
 
        redef meth after_typing(v)
        do
@@ -705,11 +732,22 @@ redef class AArrayExpr
                for n in n_exprs do
                        v.check_conform_expr(n, stype)
                end
-               _stype = v.type_array(stype)
+               do_typing(v, stype)
+       end
+
+       private meth do_typing(v: TypingVisitor, element_type: MMType)
+       do
+               _stype = v.type_array(element_type)
+
+               _meth_with_capacity = _stype.local_class.select_method(once "with_capacity".to_symbol)
+               if _meth_with_capacity == null then v.error(self, "{_stype} MUST have a with_capacity method.")
+               _meth_add = _stype.local_class.select_method(once "add".to_symbol)
+               if _meth_add == null then v.error(self, "{_stype} MUST have an add method.")
        end
 end
 
 redef class ARangeExpr
+       readable attr _meth_init: MMMethod
        redef meth after_typing(v)
        do
                var ntype = n_expr.stype
@@ -730,6 +768,22 @@ redef class ARangeExpr
        end
 end
 
+redef class ACrangeExpr
+       redef meth after_typing(v)
+       do
+               super
+               _meth_init = stype.local_class.select_method(once "init".to_symbol)
+       end
+end
+redef class AOrangeExpr
+       redef meth after_typing(v)
+       do
+               super
+               _meth_init = stype.local_class.select_method(once "without_last".to_symbol)
+       end
+end
+
+
 redef class ASuperExpr
 special ASuperInitCall
        # readable attr _prop: MMSrcMethod
@@ -932,7 +986,7 @@ special PExpr
                                        arg_idx = arg_idx + 1
                                end
                                var aa = new AArrayExpr.init_aarrayexpr(star)
-                               aa.stype = v.type_array(par_type)
+                               aa.do_typing(v, par_type)
                                a = aa
                        else
                                a = raw_args[arg_idx]