gallaher@topaz.ARPA (Mike Gallaher) (04/07/85)
Fix for Emacs version: V2.00, V2.01 Description: The ++, --, and assignment/operation operator MLisp functions (+=, -=, etc.) do not work properly when given system variables as arguments. Fix: There are three files that need to be patched: mlvars.h, mlarith.c, and mlargs.c. mlvars.h -------- 1) Change extern Expression *GetArg1(); to extern BINDING *GetArg1(); 2) Add the following code to mlvars.h, just after the definition of struct Binding. This defines macros for referencing, reading, and setting MLisp variables, taking into account whether they are system or MLisp-defined. -------------------- start of patch to mlvars.h -------------------- /* Macros for referencing variable values. */ #define IntVarVal(b) (b)->b_exp->exp_int #define StrVarPtr(b) (b)->b_exp->exp_v.v_string #define StrVarLen(b) (b)->b_exp->exp_int #define SysIntVarVal(b) *(int *)((b)->b_exp->exp_v.v_string) #define SysStrVarPtr(b) (b)->b_exp->exp_v.v_string #define SysStrVarLen(b) strlen(SysStrVarPtr(b)) /* Macros for reading and setting variable values */ #define GetIntVarVal(b) ((b)->IsSystem ? SysIntVarVal(b) \ : IntVarVal(b)) #define SetIntVarVal(b,n) if ((b)->IsSystem) \ SysIntVarVal(b) = (n);\ else \ IntVarVal(b) = (n) -------------------- end of patch to mlvars.h -------------------- mlargs.c -------- Change GetArg1 to return the binding of the first argument rather than the expression within that binding by doing the following: 1) Change the declared type of the function GetArg from Expression * to BINDING *. 2) Change the return(e) in GetArg1 [there is only one such return in this function] to return(b). mlarith.c --------- Change plusplus, minusminus, and AsgOp to use the new variable value macros, and to reflect the change of the type of GetArg1 from Expression to BINDING. The simplest way to do this is to replace their definitions entirely with the code below. Following this code in the source file should be the calls to AsgOp. -------- begin patch to mlarith.c ------------------------------ /* * This implements the `++' prefix operator in C. It requires its * arg to be a varname. It returns the incremented value. (friedl at kentvax) */ hidden int plusplus() { register BINDING *b; register int n; if ((b = GetArg1()) != NULL) { n = GetIntVarVal(b); MLvalue->exp_int = ++n; SetIntVarVal(b, n); } return(NULL); } /* * minusminus() * * This implements the -- prefix operator in C. It requires its * arg to be a varname. It returns the decremented value. (friedl at kentvax) */ hidden int minusminus() { register BINDING *b; register int n; if ((b = GetArg1()) != NULL) { n = GetIntVarVal(b); MLvalue->exp_int = --n; SetIntVarVal(b, n); } return(NULL); } /* * AsgOp(OPNAME, OP) * * This macro implements the assignment operator - just * like those in C. They are of the form * * (OP var e1 e2 ...) * * where all the expressions are optional. All of them * return integer values (friedl at Kentvax). */ #define AsgOp(OPNAME, OP) \ hidden int \ OPNAME()\ {\ register BINDING *b;\ if ((b = GetArg1()) != NULL)\ {\ register int n = GetIntVarVal(b);\ while (!Emacs_Err && EI.ArgN < EI.ArgMax)\ n OP NumericArg(EI.Nis);\ MLvalue->exp_int = n;\ SetIntVarVal(b, n);\ }\ return(NULL);\ } -------- end patch to mlarith.c ------------------------------