Merge branch 'wip2'
[nit.git] / src / syntax / icode_generation.nit
index 11b45db..54874d1 100644 (file)
@@ -24,7 +24,7 @@ private import primitive_info
 
 # An AST2ICode context stores the currently built icode informations
 class A2IContext
-special ICodeBuilder
+       super ICodeBuilder
        redef fun stmt(s: ICode)
        do
                if _current_node != null then
@@ -82,9 +82,12 @@ special ICodeBuilder
        # The method associated to the iroutine (if any)
        readable var _method: nullable MMMethod
 
+       # The register of self (if any)
+       var selfreg: nullable IRegister writable
+
        init(visitor: AbsSyntaxVisitor, r: IRoutine, m: nullable MMMethod)
        do
-               super(visitor.module, r)
+               super(visitor.mmmodule, r)
                _visitor = visitor
                _return_seq = r.body
                _return_value = r.result
@@ -177,8 +180,8 @@ redef class MMSrcModule
        fun generate_icode(tc: ToolContext)
        do
                var v = new A2IVisitor(tc, self)
-               for c in src_local_classes do
-                       for p in c.src_local_properties do
+               for c in src_local_classes.values do
+                       for p in c.src_local_properties.values do
                                if p isa MMSrcMethod then
                                        p.generate_iroutine(v)
                                else if p isa MMSrcAttribute then
@@ -279,7 +282,7 @@ redef class MMImplicitInit
 end
 
 class A2IVisitor
-special AbsSyntaxVisitor
+       super AbsSyntaxVisitor
        writable var _icode_ctx: nullable A2IContext
        fun icode_ctx: A2IContext do return _icode_ctx.as(not null)
        redef fun visit(n) do n.accept_icode_generation(self)
@@ -368,6 +371,7 @@ redef class AConcreteMethPropdef
                var params = v.iroutine.params.to_a
                var selfreg = v.variable(self_var)
                v.stmt(new IMove(selfreg, params[0]))
+               v.selfreg = selfreg
                params.shift
 
                var orig_meth: MMLocalProperty = method.global.intro
@@ -383,6 +387,39 @@ redef class AConcreteMethPropdef
                if n_block != null then
                        v.generate_stmt(n_block)
                end
+               v.selfreg = null
+       end
+end
+
+redef class AExternPropdef
+       redef fun fill_iroutine(v, method)
+       do
+               # add all explicit extern calls for this extern method
+               for explicit_import in method.as(MMMethSrcMethod).explicit_imports
+               do
+                       var prop = explicit_import.method
+                       var ic : IAbsCall
+                       if prop.is_init then
+                               ic = new INew(prop.signature.recv, prop, new List[IRegister])
+                       else
+                               ic = new ICall(prop, new List[IRegister])
+                       end
+                       ic.is_explicit_from_extern = true
+                       v.stmt(ic)
+               end
+       end
+end
+
+redef class AExternInitPropdef
+       redef fun fill_iroutine(v, method)
+       do
+               var params = v.iroutine.params
+               var sig = method.signature
+               assert params.length == sig.arity + 1
+               var rtype = sig.recv # sig.return_type
+               v.add_assignment(new IRegister(rtype), v.expr(new INative(method, params), rtype))
+
+               super
        end
 end
 
@@ -403,6 +440,8 @@ redef class AExternMethPropdef
                else
                        v.stmt(new INative(method, params))
                end
+
+               super
        end
 end
 
@@ -625,7 +664,9 @@ redef class AForExpr
                v.seq = iclos.body
                escapable.continue_seq = iclos.body
                escapable.continue_value = null
-               v.stmt(new IMove(v.variable(variable), iclos.params.first))
+               for i in [0..variables.length[ do
+                       v.stmt(new IMove(v.variable(variables[i]), iclos.params[i]))
+               end
                v.generate_stmt(n_block)
 
                # Call closure
@@ -650,7 +691,7 @@ redef class AAssertExpr
                if id == null then
                        v.add_abort("Assert failed")
                else
-                       v.add_abort("Assert %s  failed", id.to_s)
+                       v.add_abort("Assert '%s' failed", id.text.to_s)
                end
                v.seq = seq_old
                return null
@@ -787,7 +828,7 @@ redef class AOrElseExpr
 
                # Compare left and null
                var n = v.lit_null_reg
-               var c = v.expr(new IIs(e, n), v.module.type_bool)
+               var c = v.expr(new IIs(e, n), v.mmmodule.type_bool)
                var iif = new IIf(c)
                v.stmt(iif)
                var old_seq = v.seq
@@ -810,7 +851,7 @@ redef class AIsaExpr
        redef fun generate_icode(v)
        do
                var e = v.generate_expr(n_expr)
-               return v.expr(new ITypeCheck(e, n_type.stype), stype)
+               return v.expr(new ITypeCheck(v.selfreg.as(not null), e, n_type.stype), stype)
        end
 end
 
@@ -958,8 +999,9 @@ end
 redef class AArrayExpr
        redef fun generate_icode(v)
        do
-               var recv = v.add_new_array(stype, n_exprs.length)
-               for ne in n_exprs do
+               var nes = n_exprs.n_exprs
+               var recv = v.add_new_array(stype, nes.length)
+               for ne in nes do
                        var e = v.generate_expr(ne)
                        v.add_call_array_add(recv, e)
                end
@@ -996,12 +1038,13 @@ redef class ASuperExpr
                end
                var args = new Array[IRegister].with_capacity(arity + 1)
                args.add(v.iroutine.params[0])
-               if n_args.length != arity then
+               var nas = n_args.n_exprs
+               if nas.length != arity then
                        for i in [0..arity[ do
                                args.add(v.iroutine.params[i + 1])
                        end
                else
-                       for na in n_args do
+                       for na in nas do
                                args.add(v.generate_expr(na))
                        end
                end
@@ -1318,3 +1361,11 @@ redef class AClosureCallExpr
                return r
        end
 end
+
+redef class ADebugTypeExpr
+       redef fun generate_icode(v)
+       do
+               # Do nothing.
+               return null
+       end
+end