From 35d846d158980bfc9bd3aca06307014a13c291d5 Mon Sep 17 00:00:00 2001 From: Ari Johnson Date: Tue, 20 Feb 2007 21:50:18 +0000 Subject: [PATCH] setq()/setr() parallel register setting --- game/txt/hlp/cobra_func.hlp | 76 ++++++++++++++++++------------------- src/function.c | 4 +- src/funmisc.c | 24 ++++++++---- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/game/txt/hlp/cobra_func.hlp b/game/txt/hlp/cobra_func.hlp index e1656c4..40f8bec 100644 --- a/game/txt/hlp/cobra_func.hlp +++ b/game/txt/hlp/cobra_func.hlp @@ -3063,59 +3063,59 @@ for an object named "Test", preferring a thing over other types. & SETQ() & SETR() - setq(,) - setr(,) + setq(,[,,,...]) + setr(,[,,,...]) The setq() and setr() functions are used to copy strings into local registers. setq() returns a null string; it is a purely "side effect" - function. setr() returns the value stored. - - There are thirty-six local registers, numbered 0 through 9 and A through Z. - They are cleared at the start of each new queue cycle (i.e. whenever - a new command is evaluated). They are most useful for storing - complex function evaluations which are used repeatedly within a - single command. - + function. setr() returns the value stored. Multiple registers can be + assigned with a single setq() or setr(), with additional pairs of + registers and values in the function's arguments. In this case, + setr() returns the value stored in the first register listed. + + There are thirty-six local registers, numbered 0 through 9 and A + through Z. They are cleared at the start of each new queue cycle + (i.e. whenever a new command is evaluated). They are most useful for + storing complex function evaluations which are used repeatedly within + a single command. + Registers set via setq() or setr() can be accessed via the r() function, or via the %qN percent-substitution. - + See "help SETQ2" for examples of its use. - + & SETQ2 - + The setq() function is probably best used at the start of the string being manipulated, such as in the following example: - - &TEST object=[strlen(%0)] - &CMD object=$test *:"[setq(0,u(TEST,%0))]Test. %0 has length [r(0)]. - test Foo - > Object says, "Test. Foo has length 3." - - In this case, it is a waste to use setq(), since we only use the function - result once, but if TEST was a complex function being used multiple times - within the same command, it would be much more efficient to use the local - register, since TEST would then only be evaluated once. - - setq() can thus be used to improve the readability of MUSH code, as well - as to cut down the amount of time needed to do complex evaluations. - + + &TEST object=[strlen(%0)] &CMD object=$test + *:"[setq(0,u(TEST,%0))]Test. %0 has length [r(0)]. test Foo > + Object says, "Test. Foo has length 3." + + In this case, it is a waste to use setq(), since we only use the + function result once, but if TEST was a complex function being used + multiple times within the same command, it would be much more efficient + to use the local register, since TEST would then only be evaluated once. + + setq() can thus be used to improve the readability of MUSH code, as + well as to cut down the amount of time needed to do complex evaluations. + See "help SETQ3" for scoping rules of setq(). - + & SETQ3 The registers set by setq() can be used in later commands in the same thread. That is, the registers are set to null on all $-commands, - ^-commands, A-attribute triggers, etc., but are then retained from - that point forward through the execution of all your code. Code - branches like @wait and @switch retain the register values from the - time of the branch, so the code: - + ^-commands, A-attribute triggers, etc., but are then retained from that + point forward through the execution of all your code. Code branches + like @wait and @switch retain the register values from the time of + the branch, so the code: + say setr(a,foo); @wait 0=say %qa; say setr(a,bar) - + produces the following when executed by an object: - - Object says "foo" - Object says "bar" - Object says "foo" + + Object says "foo" Object says "bar" Object says "foo" & SETUNION() setunion(, [, ][, ][, ]) diff --git a/src/function.c b/src/function.c index d7a6319..3eef453 100644 --- a/src/function.c +++ b/src/function.c @@ -586,8 +586,8 @@ FUNTAB flist[] = { {"SECURE", fun_secure, 1, -1, FN_REG}, {"SENT", fun_sent, 1, 1, FN_REG}, {"SET", fun_set, 2, 2, FN_REG}, - {"SETQ", fun_setq, 2, 2, FN_REG}, - {"SETR", fun_setq, 2, 2, FN_REG}, + {"SETQ", fun_setq, 2, INT_MAX, FN_REG}, + {"SETR", fun_setq, 2, INT_MAX, FN_REG}, {"SETDIFF", fun_setdiff, 2, 5, FN_REG}, {"SETINTER", fun_setinter, 2, 5, FN_REG}, {"SETUNION", fun_setunion, 2, 5, FN_REG}, diff --git a/src/funmisc.c b/src/funmisc.c index 738699d..df20f50 100644 --- a/src/funmisc.c +++ b/src/funmisc.c @@ -159,15 +159,23 @@ FUNCTION(fun_setq) { /* sets a variable into a local register */ int qindex; + int n; - if (*args[0] && (*(args[0] + 1) == '\0') && - ((qindex = qreg_indexes[(unsigned char) args[0][0]]) != -1) - && global_eval_context.renv[qindex]) { - strcpy(global_eval_context.renv[qindex], args[1]); - if (!strcmp(called_as, "SETR")) - safe_strl(args[1], arglens[1], buff, bp); - } else - safe_str(T("#-1 REGISTER OUT OF RANGE"), buff, bp); + if ((nargs % 2) != 0) { + safe_str(T("#-1 FUNCTION EXPECTS AN EVEN NUMBER OF ARGUMENTS"), buff, bp); + return; + } + + for (n = 0; n < nargs; n += 2) { + if (*args[n] && (*(args[n] + 1) == '\0') && + ((qindex = qreg_indexes[(unsigned char) args[n][0]]) != -1) + && global_eval_context.renv[qindex]) { + strcpy(global_eval_context.renv[qindex], args[n + 1]); + if (n == 0 && !strcmp(called_as, "SETR")) + safe_strl(args[n + 1], arglens[n + 1], buff, bp); + } else + safe_str(T("#-1 REGISTER OUT OF RANGE"), buff, bp); + } } /* ARGSUSED */ -- 2.30.2