Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / frontend / parallelization_phase.nit
index 7da80ff..b5cc9fd 100644 (file)
@@ -36,29 +36,22 @@ private class ParallelizationPhase
                if nat.n_atid.n_id.text != "threaded" then return
 
                if not nmethdef isa AMethPropdef then
-                       toolcontext.error(nmethdef.location, "Syntax error: only a method can be threaded.")
-                       return
-               end
-               if nmethdef.n_signature.n_params.length != 0 then
-                       toolcontext.error(nmethdef.location, "Syntax error: parametrized method not supported yet.")
-                       return
-               end
-               if nmethdef.n_signature.n_type != null then
-                       toolcontext.error(nmethdef.location, "Syntax error: method with a return value not supported yet.")
+                       toolcontext.error(nat.location, "Syntax Error: only a method can be threaded.")
                        return
                end
 
+               #TODO: check for self calls
+
                # Get the module associated with this method
                var amod = nmethdef.parent.parent
                assert amod isa AModule
 
                # Construct the name of the generated class
-               var modulename = amod.n_moduledecl.n_name.n_id.text
-               var classname = "Threaded" + modulename
+               var classname = "Threaded"
 
                # Try to get the name of the class
                if nmethdef.parent isa AStdClassdef then
-                       classname += nmethdef.parent.as(AStdClassdef).n_id.text
+                       classname += nmethdef.parent.as(AStdClassdef).n_qid.n_id.text
                end
 
                # Try to get the name of the method
@@ -66,21 +59,50 @@ private class ParallelizationPhase
                        classname += nmethdef.n_methid.as(AIdMethid).n_id.text
                end
 
-               # Create a string corresponding to the threaded class
-               var s ="""
+               # Handle methods with a return value
+               var has_rvalue = nmethdef.n_signature.n_type != null
+               var vtype = ""
+               if has_rvalue then
+                       vtype = "redef type E: " + nmethdef.n_signature.n_type.n_qid.n_id.text
+               end
+
+               # create a return type
+               var n_id = new TClassid
+               n_id.text = classname
+               var n_qid = new AQclassid
+               n_qid.n_id = n_id
+               var n_type = new AType
+               n_type.n_qid = n_qid
+               nmethdef.n_signature.n_type = n_type
+
+               var params = new Array[String]
+               for param in nmethdef.n_signature.n_params do
+                       var typ = param.n_type.n_qid.n_id.text
+                       if param.n_type.n_kwnullable != null then typ = "nullable {typ}"
+                       params.add """
+var {{{param.n_id.text}}}: {{{typ}}}
+"""
+               end
+
+               # String corresponding to the generated class
+               var classdef_source = """
 class {{{classname}}}
        super Thread
 
+       {{{vtype}}}
+
+       {{{params.join("\n")}}}
        redef fun main do
        end
 end
 """
 
                # Parse newly obtained classdef
-               var classdef = toolcontext.parse_classdef(s).as(AStdClassdef)
+               var classdef = toolcontext.parse_classdef(classdef_source)
+               assert classdef isa AStdClassdef
 
                # Get the `main` fun of the class
-               var mainfun : nullable AMethPropdef = null
+               var mainfun: nullable AMethPropdef = null
                for prop in classdef.n_propdefs do
                        if prop isa AMethPropdef then mainfun = prop
                end
@@ -90,21 +112,40 @@ end
                mainfun.n_block = nmethdef.n_block
 
                # Add "return null" to the end of the `main` function
-               var s_nullreturn = "return null"
-               var nullreturn = toolcontext.parse_something(s_nullreturn)
-               assert nullreturn isa AExpr
-               mainfun.n_block.as(ABlockExpr).n_expr.add(nullreturn)
+               if not has_rvalue then
+                       var s_nullreturn = "return null"
+                       var nullreturn = toolcontext.parse_something(s_nullreturn)
+                       assert nullreturn isa AExpr
+                       mainfun.n_block.as(ABlockExpr).n_expr.add(nullreturn)
+               end
 
                # Create new body for the annotated fun
-               var s_newbody ="""
+               var s_newbody : String
+               if nmethdef.n_signature.n_params.not_empty then
+                       var init_params = new Array[String]
+                       for param in nmethdef.n_signature.n_params do
+                               init_params.add(param.n_id.text)
+                       end
+                       s_newbody ="""
+var thread = new {{{classname}}}({{{init_params.join(",")}}})
+thread.start
+return thread
+"""
+               else
+                       s_newbody = """
 var thread = new {{{classname}}}
 thread.start
+return thread
 """
+               end
 
                var newbody = toolcontext.parse_something(s_newbody)
                nmethdef.n_block = newbody.as(ABlockExpr)
 
+               nmethdef.validate
+
                # Add the new class to the module
                amod.n_classdefs.add(classdef)
+               classdef.validate
        end
 end