X-Git-Url: http://nitlanguage.org diff --git a/src/frontend/parallelization_phase.nit b/src/frontend/parallelization_phase.nit index 7da80ff..080efe6 100644 --- a/src/frontend/parallelization_phase.nit +++ b/src/frontend/parallelization_phase.nit @@ -22,6 +22,7 @@ private import parser_util import modelize import astbuilder private import annotation +private import astvalidation redef class ToolContext # Transforms a function annotated with "threaded" @@ -36,29 +37,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 +60,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 +113,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