From 042cbb6c15f26711f293758425c8bec22b73cf47 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Tue, 28 Jul 2009 09:26:47 -0400 Subject: [PATCH] syntax: vararg arguments are processed by icode syntax/typing.nit does the type verification only. syntax/icode_generation generate the implicit Array for vararg. Signed-off-by: Jean Privat --- src/syntax/icode_generation.nit | 35 +++++++++++++++++++++++++++-------- src/syntax/syntax_base.nit | 2 -- src/syntax/typing.nit | 27 ++++++--------------------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/syntax/icode_generation.nit b/src/syntax/icode_generation.nit index 46c1263..f002863 100644 --- a/src/syntax/icode_generation.nit +++ b/src/syntax/icode_generation.nit @@ -1192,10 +1192,29 @@ end redef class AAbsAbsSendExpr # Compile each argument and add them to the array - fun generate_icode_for_arguments_in(v: A2IContext, args: Array[IRegister]) - do - for a in arguments do - args.add(v.generate_expr(a)) + fun generate_icode_for_arguments_in(v: A2IContext, args: Array[IRegister], signature: MMSignature) + do + var par_arity = signature.arity + var par_vararg = signature.vararg_rank + var raw_args = raw_arguments + var raw_arity = raw_args.length + var arg_idx = 0 + for par_idx in [0..par_arity[ do + var a: AExpr + var par_type = signature[par_idx] + if par_idx == par_vararg then + var arr = v.add_new_array(v.visitor.type_array(par_type), raw_arity-par_arity) + for i in [0..(raw_arity-par_arity)] do + a = raw_args[arg_idx] + v.add_call_array_add(arr, v.generate_expr(a)) + arg_idx = arg_idx + 1 + end + args.add(arr) + else + a = raw_args[arg_idx] + args.add(v.generate_expr(a)) + arg_idx = arg_idx + 1 + end end end end @@ -1206,8 +1225,8 @@ redef class ASendExpr var recv = v.generate_expr(n_expr) var args = new Array[IRegister] args.add(recv) - generate_icode_for_arguments_in(v, args) var prop = prop + generate_icode_for_arguments_in(v, args, prop.signature.as(not null)) var r: nullable IRegister = null # The full result of the send (raw call + breaks) var r2: nullable IRegister # The raw result of the call @@ -1260,7 +1279,7 @@ redef class ASendReassignExpr if n_expr.stype.is_nullable then v.add_null_reciever_check(recv) var args = new Array[IRegister] args.add(recv) - generate_icode_for_arguments_in(v, args) + generate_icode_for_arguments_in(v, args, read_prop.signature.as(not null)) var e2 = v.expr(new ICall(read_prop, args), read_prop.signature.return_type.as(not null)) var e3 = v.generate_expr(n_value) @@ -1276,7 +1295,7 @@ redef class ANewExpr redef fun generate_icode(v) do var args = new Array[IRegister] - generate_icode_for_arguments_in(v, args) + generate_icode_for_arguments_in(v, args, prop.signature.as(not null)) return v.expr(new INew(stype, prop, args), stype) end end @@ -1350,7 +1369,7 @@ redef class AClosureCallExpr do # Geneate arguments var args = new Array[IRegister] - generate_icode_for_arguments_in(v, args) + generate_icode_for_arguments_in(v, args, variable.closure.signature) # Prepare icall var closdecl = v.closurevariables[variable] diff --git a/src/syntax/syntax_base.nit b/src/syntax/syntax_base.nit index a12eebf..03a25a9 100644 --- a/src/syntax/syntax_base.nit +++ b/src/syntax/syntax_base.nit @@ -750,8 +750,6 @@ special AExpr # The raw arguments used (without vararg transformation) (require is_typed) fun raw_arguments: Array[AExpr] is abstract - # The real arguments used (after star transformation) (require is_typed) - fun arguments: Array[AExpr] is abstract end class AAbsSendExpr diff --git a/src/syntax/typing.nit b/src/syntax/typing.nit index ed0e044..27e469c 100644 --- a/src/syntax/typing.nit +++ b/src/syntax/typing.nit @@ -1067,12 +1067,9 @@ redef class AAbsAbsSendExpr print "{location} no compute_raw_arguments" return null end - # The real arguments used (after star transformation) (once computed) - redef fun arguments do return _arguments.as(not null) - var _arguments: nullable Array[AExpr] # Check the conformity of a set of arguments `raw_args' to a signature. - private fun process_signature(v: TypingVisitor, psig: MMSignature, name: Symbol, raw_args: nullable Array[AExpr]): nullable Array[AExpr] + private fun process_signature(v: TypingVisitor, psig: MMSignature, name: Symbol, raw_args: nullable Array[AExpr]): Bool do var par_vararg = psig.vararg_rank var par_arity = psig.arity @@ -1080,32 +1077,25 @@ redef class AAbsAbsSendExpr if raw_args == null then raw_arity = 0 else raw_arity = raw_args.length if par_arity > raw_arity or (par_arity != raw_arity and par_vararg == -1) then v.error(self, "Error: '{name}' arity missmatch.") - return null + return false end var arg_idx = 0 - var args = new Array[AExpr] for par_idx in [0..par_arity[ do var a: AExpr var par_type = psig[par_idx] if par_idx == par_vararg then - var star = new Array[AExpr] for i in [0..(raw_arity-par_arity)] do a = raw_args[arg_idx] v.check_conform_expr(a, par_type) - star.add(a) arg_idx = arg_idx + 1 end - var aa = new AArrayExpr.init_aarrayexpr(star) - aa.do_typing(v, par_type) - a = aa else a = raw_args[arg_idx] v.check_conform_expr(a, par_type) arg_idx = arg_idx + 1 end - args.add(a) end - return args + return true end # Check the conformity of a set of defined closures @@ -1161,13 +1151,11 @@ redef class AAbsSendExpr var prop = get_property(v, type_recv, is_implicit_self, name) if prop == null then return var sig = get_signature(v, type_recv, prop, recv_is_self) - var args = process_signature(v, sig, prop.name, raw_args) - if args == null then return + if not process_signature(v, sig, prop.name, raw_args) then return var rtype = process_closures(v, sig, prop.name, closure_defs) if rtype == null and sig.return_type != null then return _prop = prop _prop_signature = sig - _arguments = args _return_type = rtype end @@ -1345,7 +1333,6 @@ redef class ASendReassignExpr _read_prop = prop raw_args = raw_args.to_a - var old_args = arguments raw_args.add(n_value) do_typing(v, n_expr.stype, n_expr.is_implicit_self, n_expr.is_self, "{name}=".to_symbol, raw_args, null) @@ -1357,7 +1344,6 @@ redef class ASendReassignExpr end end - _arguments = old_args # FIXME: What if star parameters do not match betwen the two methods? _is_typed = true end end @@ -1562,13 +1548,12 @@ redef class AClosureCallExpr var va = variable if va.closure.is_break then v.variable_ctx.unreash = true var sig = va.closure.signature - var args = process_signature(v, sig, n_id.to_symbol, n_args.to_a) + var s = process_signature(v, sig, n_id.to_symbol, compute_raw_arguments) if not n_closure_defs.is_empty then process_closures(v, sig, n_id.to_symbol, n_closure_defs.to_a) end - if args == null then return + if not s then return _prop_signature = sig - _arguments = args _stype = sig.return_type _is_typed = true end -- 1.7.9.5