PennMUSH Community

Ticket #6174 (closed suggested feature: fixed)

Opened 5 years ago

Last modified 1 year ago

letq setq

Reported by: anonymous Assigned to: raevnos
Priority: minor Milestone: 1.8.3p3
Keywords: Cc:
Visibility: Public

Description (Last modified by raevnos)

setq/setr is extended to take multiple arguments:

    setq(1,a,2,b,3,c,...)

setr evaluates to the *last* value.

letq is introduced

    letq(1,a,2,b,3,c,..., expression)

This is sort of like localize(setq(1,a,2,b,3,c)[expression]), except 
that letq
only saves and restores those registers listed, whilst localize saves 
and restores all registers.

    [setq(2,X)][letq(1,a,setq(2,b))] %q2             ==> b
    [setq(2,X)][localize((setq(1,a)[setq(2,b)])] %q2 ==> X

Not only does letq allow registers to be changed, it's also notably more 
concise. :-)

# Patch name: setq-letq
# Patch version:
# Author's name: Nathan Baum
# Author's email: nathan_baum@btinternet.com
# Version of PennMUSH: 1.7.7p24
# Date patch made: Sat Nov 1 20:11:16 GMTST 2003
# Author is willing to support (yes/no): yes
# Patch format: Context
#
#
# This is a contributed PennMUSH patch. Its use is subject to the
# same restrictions found in PennMUSH's hdrs/copyrite.h file.
#
# No warranty is given for this patch. It is not necessarily going
# to work on your system, with any version of PennMUSH other than
# the one above, etc.
#
# If the author given above was willing to support the patch, you
# should write to the author if you have any questions or problems. Do
# *NOT* send email messages to Javelin or any PennMUSH mailing list about
# this patch!
#
# Below this line is the author's description of the patch,
# followed by the patch itself. If the patch is in context diff
# format, you'll probably apply it by typing: patch < patchfile
# in your top-level MUSH directory, unless instructed otherwise
# below.
#
#
*** ../vanilla/src/function.c    Tue Oct 21 19:55:52 2003
--- src/function.c    Sat Nov  1 19:57:54 2003
***************
*** 79,84 ****
--- 79,103 ----
    }
  }
 
+ void
+ save_partial_global_reg(const char *funcname, char *preserve[], int i)
+ {
+   preserve[i] = (char *) mush_malloc(BUFFER_LEN, funcname);
+   strcpy(preserve[i], renv[i]);
+ }
+
+ void
+ restore_partial_global_regs(const char *funcname, char *preserve[])
+ {
+   int i;
+   for (i = 0; i < NUMQ; i++) {
+     if (preserve[i]) {
+       strcpy(renv[i], preserve[i]);
+       mush_free(preserve[i], funcname);
+     }
+   }
+ }
+
  /** Restore the q-registers, without freeing the storage array.
   * \param preserve pointer to array to restore the q-registers from.
   */
***************
*** 317,322 ****
--- 336,342 ----
    {"LDELETE", fun_ldelete, 2, 3, FN_REG},
    {"LEFT", fun_left, 2, 2, FN_REG},
    {"LEMIT", fun_lemit, 1, -1, FN_REG},
+   {"LETQ", fun_letq, 1, INT_MAX, FN_NOPARSE},
    {"LEXITS", fun_lexits, 1, 1, FN_REG},
    {"LFLAGS", fun_lflags, 0, 1, FN_REG},
    {"LINK", fun_link, 2, 2, FN_REG},
***************
*** 442,449 ****
    {"SECS", fun_secs, 0, 0, FN_REG},
    {"SECURE", fun_secure, 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},
    {"SETDIFF", fun_setdiff, 2, 5, FN_REG},
    {"SETINTER", fun_setinter, 2, 5, FN_REG},
    {"SETUNION", fun_setunion, 2, 5, FN_REG},
--- 462,469 ----
    {"SECS", fun_secs, 0, 0, FN_REG},
    {"SECURE", fun_secure, 1, -1, FN_REG},
    {"SET", fun_set, 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},
*** ../vanilla/src/funmisc.c    Tue Oct 21 19:55:52 2003
--- src/funmisc.c    Sat Nov  1 20:07:36 2003
***************
*** 140,158 ****
 
  extern signed char qreg_indexes[UCHAR_MAX + 1];
  /* ARGSUSED */
! FUNCTION(fun_setq)
  {
    /* sets a variable into a local register */
    int qindex;
 
!   if (*args[0] && (*(args[0] + 1) == '\0') &&
!       ((qindex = qreg_indexes[(unsigned char) args[0][0]]) != -1)
!       && renv[qindex]) {
!     strcpy(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);
  }
 
  /* ARGSUSED */
--- 140,210 ----
 
  extern signed char qreg_indexes[UCHAR_MAX + 1];
  /* ARGSUSED */
! FUNCTION(fun_letq)
  {
    /* sets a variable into a local register */
+   char const *p;
    int qindex;
+   int i;
+   char *preserve[NUMQ];
+   int save[NUMQ];
+
+   for (i = 0; i < NUMQ; ++i)
+     save[i] = 0, preserve[i] = 0;
+
+   if (0 == nargs % 2)
+   {
+     safe_str(T("#-1 FUNCTION ("), buff, bp);
+     safe_str(called_as, buff, bp);
+     safe_str(T(") EXPECTS AN ODD NUMBER OF ARGUMENTS"), buff, bp);
+   }
+   else
+   {
+     for (i = 0; i < nargs - 1; i += 2)
+     {
+       if (*args[i] && (*(args[i] + 1) == '\0') &&
+           ((qindex = qreg_indexes[(unsigned char) args[i][0]]) != -1)
+           && renv[qindex]) {
+         save_partial_global_reg("fun_letq", preserve, qindex);
+         strcpy(renv[qindex], args[i+1]);
+       } else
+         safe_str(T("#-1 REGISTER OUT OF RANGE"), buff, bp);
+     }
+  
+     p = args[nargs - 1];
+     process_expression(buff, bp, &p, executor, caller, enactor, 
PE_DEFAULT,
+                PT_DEFAULT, pe_info);
+  
+     restore_partial_global_regs("fun_letq", preserve);
+   }
+
+ }
 
! /* ARGSUSED */
! FUNCTION(fun_setq)
! {
!   /* sets a variable into a local register */
!   int qindex;
!   int i;
!  
!   if (nargs % 2)
!   {
!     safe_str(T("#-1 FUNCTION ("), buff, bp);
!     safe_str(called_as, buff, bp);
!     safe_str(T(") EXPECTS AN EVEN NUMBER OF ARGUMENTS"), buff, bp);
!   }
!   else
!     for (i = 0; i < nargs; i += 2)
!     {
!       if (*args[i] && (*(args[i] + 1) == '\0') &&
!           ((qindex = qreg_indexes[(unsigned char) args[i][0]]) != -1)
!           && renv[qindex]) {
!         strcpy(renv[qindex], args[i + 1]);
!         if (!strcmp(called_as, "SETR") && i == nargs - 2)
!           safe_strl(args[i + 1], arglens[i + 1], buff, bp);
!       } else
!         safe_str(T("#-1 REGISTER OUT OF RANGE"), buff, bp);
!     }
  }
 
  /* ARGSUSED */
*** ../vanilla/hdrs/externs.h    Tue Oct 21 19:55:46 2003
--- hdrs/externs.h    Sat Nov  1 19:46:08 2003
***************
*** 478,483 ****
--- 478,485 ----
      extern char *strip_braces(char const *line);
      extern void save_global_regs(const char *funcname, char *preserve[]);
      extern void restore_global_regs(const char *funcname, char 
*preserve[]);
+     extern void save_partial_global_reg(const char *funcname, char 
*preserve[], int num);
+     extern void restore_partial_global_regs(const char *funcname, char 
*preserve[]);
      extern void load_global_regs(char *preserve[]);
      extern void save_global_env(const char *funcname, char *preserve[]);
      extern void restore_global_env(const char *funcname, char 
*preserve[]);



Change History

03/20/05 19:34:00 changed by

setq in 1.8.1

05/01/07 13:38:07 changed by raevnos

  • owner changed from devteam to raevnos.
  • description changed.
  • milestone set to 1.8.3p3.

Only half of this ever actually got in. Will fix that.

06/10/07 13:55:41 changed by raevnos

  • status changed from new to closed.
  • resolution set to fixed.