From 0bb1f829c745d94386f17f37ed5568a20c7243e9 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 9 Oct 2016 10:46:03 -0700 Subject: Support curried arguments in umethod and umeth. * share/txr/stdlib/struct.tl (umeth): accept variadic arguments. Evaluate them using the dwim brackets and pass to umethod. The (fun umethod) trick is used to refer to the umethod in the function namespace even if it is shadowed by a variable. * struct.c (struct_init): Update registration of umethod to reflect its new variadic argument signature. (umethod_args_fun): New static function. (umethod): Return a function based on umethod_fun, as before, if there are no variadic args. Otherwise, use umethod_args_fun which deals with them. * struct.h (umethod): Declaration updated. * tests/012/oop.tl: Modest testcase for umeth with curried argument. * tests/012/oop.expected: Updated. * txr.1: Updated documentation of umeth and umethod. --- struct.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'struct.c') diff --git a/struct.c b/struct.c index f8ed361d..61ce4174 100644 --- a/struct.c +++ b/struct.c @@ -154,7 +154,7 @@ void struct_init(void) reg_fun(intern(lit("method"), user_package), func_n2(method)); reg_fun(intern(lit("super-method"), user_package), func_n2(super_method)); reg_fun(intern(lit("uslot"), user_package), func_n1(uslot)); - reg_fun(intern(lit("umethod"), user_package), func_n1(umethod)); + reg_fun(intern(lit("umethod"), user_package), func_n1v(umethod)); } static noreturn void no_such_struct(val ctx, val sym) @@ -1158,9 +1158,42 @@ static val umethod_fun(val sym, struct args *args) } } -val umethod(val slot) +static val umethod_args_fun(val env, struct args *args) { - return func_f0v(slot, umethod_fun); + val self = lit("umethod"); + cons_bind (sym, curried_args, env); + + if (!args_more(args, 0)) { + uw_throwf(error_s, lit("~a: object argument required to call ~s"), + self, env, nao); + } else { + cnum ca_len = c_num(length(curried_args)); + cnum index = 0; + val strct = args_get(args, &index); + args_decl(args_call, max(args->fill + ca_len, ARGS_MIN)); + args_add(args_call, strct); + args_add_list(args_call, curried_args); + args_normalize(args_call, ca_len + 1); + args_cat_zap_from(args_call, args, index); + + struct struct_inst *si = struct_handle(strct, self); + + if (symbolp(sym)) { + loc ptr = lookup_slot(strct, si, sym); + if (!nullocp(ptr)) + return generic_funcall(deref(ptr), args_call); + } + + no_such_slot(self, si->type->self, sym); + } +} + +val umethod(val slot, struct args *args) +{ + if (!args_more(args, 0)) + return func_f0v(slot, umethod_fun); + else + return func_f0v(cons(slot, args_get_list(args)), umethod_args_fun); } static void struct_inst_print(val obj, val out, val pretty) -- cgit v1.2.3