%%HP: T(3)F(.);
\<<
0. \-> n @ store a value in a local variable.
\<<
69. MENU @ Old MODES MISC menu.
-14.1 KEYEVAL @ [F4] key (toggle last stack saves).
n @ Put the local variable's contents on the
@ stack.
\>>
\>>
If I start with last stack saves disabled, then it enables them
and puts the 0. on the stack, as expected.
But if I start with last stack saves enabled, then it disables
them, and then errors out with "KEYEVAL Error: Undefined Local
Name". Whether -14.1 is returned to the stack as the last argument
depends on the state of flag -55 (as expected).
What happened to my local variable? The system still knew that n
was a local name, but now undefined. Why?
Toggling last stack saves doesn't normally have any effect on
local variables, and although I don't have much experience with
KEYEVAL, it normally doesn't either, as far as I know.
Maybe this is related to previous reports (Google for them) of
strange things happening when KEYEVAL was used in a FOR loop,
which also uses a local variable for its index?
Any ideas?
Yeah, I know: "Don't do that!" ;-)
--
Regard,
James
have you examined what the KEYEVAL code does?
Or have you tried toggling last stack by a direct call?
Regarding the local variables:
They shouldn't interfere, since you're using a named LAM.
Apart from that, I don't see much practical use for KEYEVAL at all;-)
Regards
Raymond
"James M. Prange" <jmpr...@i-is.com> schrieb im Newsbeitrag
news:607e1$44315ada$4267eb73$28...@123.NET...
> What I was trying to accomplish would be sort of a long story, but
> with the following example program on either the 49G or 49g+:
>
> %%HP: T(3)F(.);
> \<<
> 0. \-> n @ store a value in a local variable.
> \<<
> 69. MENU @ Old MODES MISC menu.
> -14.1 KEYEVAL @ [F4] key (toggle last stack saves).
> n @ Put the local variable's contents on the
> @ stack.
> \>>
> \>>
>
> If I start with last stack saves disabled, then it enables them
> and puts the 0. on the stack, as expected.
>
> But if I start with last stack saves enabled, then it disables
> them, and then errors out with "KEYEVAL Error: Undefined Local
> Name". Whether -14.1 is returned to the stack as the last argument
> depends on the state of flag -55 (as expected).
>
> What happened to my local variable? The system still knew that n
> was a local name, but now undefined. Why?
Where do you suppose the stack is saved when you have enabled saving?
It's in a null-named lambda variable (see supported entry SAVELAM)
in an environment, and apparently that environment (or yours) is deleted
when you disable Last Stack; the following thread might be interesting,
not only for this issue, but also for a common error in NULLLAM usage,
which emerges when some programs are run with Last Stack disabled:
http://groups.google.com/group/comp.sys.hp48/browse_frm/thread/d80feedda610cee0
You are not, of course, getting a KEYEVAL error; what happens
is that the last saved user command name was KEYEVAL,
There was also no "corruption" of local variables,
but simply a deleted entire environment,
due to taking too much liberty by invoking in a program
a function not intended to be programmable.
> Yeah, I know: "Don't do that!" ;-)
I think it's best to enable/disable Last Stack only from the keyboard.
Some other KEYEVALs are also very problematic (e.g. may hang)
if performed in the command line (this isn't what you did,
but might as well be mentioned, as another caution).
Incidentally, have you noticed that every HALT level has its own
Last Stack enable/disable ability, and an independent save location
when enabled?
[r->] [OFF]
The toggle menu was purely designed to be called by hand, not in a program.
LAST STACK is actually a block of nullname local variable, when you
enable it it will create the variable. Unfortunately when doing so it
assumes that you have no other local variables existing. So when it
creates the new block, it erases any other that may be existing
>
> Maybe this is related to previous reports (Google for them) of
> strange things happening when KEYEVAL was used in a FOR loop,
> which also uses a local variable for its index?
>
> Any ideas?
yes
This is the same problems that have been reported several times when
using the new choose menu. It took a while to identify all instances of
code creating local variables and also saving the last stack, as each
time other variables were deleted making the code crash sooner or later.
"it's a bad thing" (c) TM
JY
> Apart from that, I don't see much practical use for KEYEVAL at all;-)
To assign the functions of some keys to other keys
(I use it to "swap" some key functions in my calcs, for example).
There are, of course, other keys that have no user equivalent,
like the cursor keys, but there again, IIRC,
it may prove unsatisfactory to try to use some keys via KEYEVAL,
just as it sometimes was for the (still-existing) *libraries*
A1 thru A6 (each corresponding to one entire keyplane of the keyboard,
with keys numbered from zero in the top left corner),
which were introduced in the first 48G.
For example, #A2018h LIBEVAL gives you ACOS on your 49-series calc,
the same as -54.2 KEYEVAL; on the 48G/GX/G+ you have only these
LIBEVALs to rely on, since KEYEVAL was introduced in the 49 series.
Note that the key numbering is different on the 48G/GX/G+ keyboard
(but counting is easier, since every row is straight :)
[r->] [OFF]
I use -55 CF/SF or toggle it with IFTE or similar
jhm>> I think it's best to enable/disable Last Stack only from the keyboard.
> I use -55 CF/SF or toggle it with IFTE or similar
That's the Last *Args* flag (there is no "Last Stack" flag).
By the way, when you toggle Last Args off then back on,
it wipes out any existing references,
which is a neat way (along with things like ERR0
and clearing the stack) of removing any obstacles
to purging libraries because of "object in use."
[r->] [OFF]
"Last Args" is what enables you to use the LASTARG command,
or the keyboard ANS (on 49 series) or [last]ARG (on 48 series),
to recover to the stack the arguments of the last
"User" command which required stack arguments; E.g.
4 8 * (get answer 32); ANS or ARG then recalls 4 and 8 to stack
(while answer 32 remains).
"Last Stack" is what enables you to use UNDO
(which restores the stack as it was before the last keyboard command,
but does not undo any other effects), E.g. 4 8 ENTER *
(get answer 32); UNDO then puts back 4 and 8 but 32 is gone;
note that if you don't press ENTER then you also don't get back
4 and 8 either, because then they weren't already on the stack
just before pressing *
One unusual special recovery action is that keyboard STO
(with either STO or left-shifted VAR menu key) into an
existing variable (oops!) can be undone via *immediately* doing
LASTARG (ANS or ARG on keyboard), STO, LASTARG (again),
provided that "Last Args" was enabled
(especially clever key definitions make this possible);
note that this has nothing to do with UNDO.
[r->] [OFF]
That's right, my flag settings were wrong => thus the "feature"
CASCFG - ah, that helped!
It will be fixed in VPN 2.05 (and it will introduce 2 new "features")
> By the way, when you toggle Last Args off then back on,
> it wipes out any existing references,
> which is a neat way (along with things like ERR0
> and clearing the stack) of removing any obstacles
> to purging libraries because of "object in use."
Last Args Off/On & ERR0 - what else is needed?
> Hi,
>
> have you examined what the KEYEVAL code does?
Well, I did look at it briefly with Nosy, but didn't follow every
branch or attempt to decipher the code objects.
> Or have you tried toggling last stack by a direct call?
Well actually, I have a SysRPL last stack toggler that seems to
work very nicely:
::
CK0NOLASTWD
# 137
JstGETTHEMSG
UNDO_ON?
ITE
::
UNDO_OFF
" Off"
;
::
UNDO_ON
" On"
;
&$
xMSGBOX
;
> Regarding the local variables:
> They shouldn't interfere, since you're using a named LAM.
Maybe they shouldn't, but in this particular case they obviously
do.
> Apart from that, I don't see much practical use for KEYEVAL at all;-)
Like I wrote, I don't have much experience with it myself. Most
things can be accomplished well enough without it. Where I see a
possible use for KEYEVAL is for executing non-programmable
operations. But it seems that some such operations don't work out
very well within a program; I suppose that maybe that's why they
aren't commands.
Anyway, the last stack toggler was just something that I was
fooling around with, and was surprised when it don't work as I'd
expected.
<snip>
--
Regards,
James
<snip>
> Where do you suppose the stack is saved when you have enabled saving?
Umm, some special place in memory?
> It's in a null-named lambda variable (see supported entry SAVELAM)
> in an environment,
And SAVESTACK and undo.
> and apparently that environment (or yours) is deleted
> when you disable Last Stack; the following thread might be interesting,
> not only for this issue, but also for a common error in NULLLAM usage,
> which emerges when some programs are run with Last Stack disabled:
> http://groups.google.com/group/comp.sys.hp48/browse_frm/thread/d80feedda610cee0
Good to know about.
> You are not, of course, getting a KEYEVAL error; what happens
> is that the last saved user command name was KEYEVAL,
Well yes, at least that much was obvious to me.
> There was also no "corruption" of local variables,
> but simply a deleted entire environment,
> due to taking too much liberty by invoking in a program
> a function not intended to be programmable.
>
>> Yeah, I know: "Don't do that!" ;-)
>
> I think it's best to enable/disable Last Stack only from the keyboard.
Probably so, although it does seem to work okay as long as I don't
have any local variables when I disable last stack.
> Some other KEYEVALs are also very problematic (e.g. may hang)
> if performed in the command line (this isn't what you did,
> but might as well be mentioned, as another caution).
>
> Incidentally, have you noticed that every HALT level has its own
> Last Stack enable/disable ability, and an independent save location
> when enabled?
Yes, I often use such "suspended environments". Note that neither
the last stack nor any local variables in a suspended environment
is affected by disabling last stack, as long as last stack is
enabled again when CONT is pressed.
--
Regards,
James
Well, actually the problem that I noticed seemed to be only when
disabling last stack, not when enabling it, but I see what you
mean.
>> Maybe this is related to previous reports (Google for them) of
>> strange things happening when KEYEVAL was used in a FOR loop,
>> which also uses a local variable for its index?
>>
>> Any ideas?
> yes
>
> This is the same problems that have been reported several times when
> using the new choose menu. It took a while to identify all instances of
> code creating local variables and also saving the last stack, as each
> time other variables were deleted making the code crash sooner or later.
>
> "it's a bad thing" (c) TM
Okay, so it's not a bug; I'm glad that I asked here instead of
reporting it on Bugzilla.
It seems that there are indeed possible pitfalls to using
KEYEVAL, yet the documentation doesn't include any suggestion of
this for the unwary user. Perhaps we should consider it to be a
"hacker's" command -- okay for the user who really knows what
he's doing, but potentially dangerous.
Thanks for the information.
--
Regards,
James
<snip>
>> By the way, when you toggle Last Args off then back on,
>> it wipes out any existing references,
>> which is a neat way (along with things like ERR0
>> and clearing the stack) of removing any obstacles
>> to purging libraries because of "object in use."
>
> Last Args Off/On & ERR0 - what else is needed?
Plagiarizing from Bill Wickes's "HP 48 Insights Part I: Principles
and Programming HP 48G/GX Edition":
6.4.2.2 Altering Port Variables
Port variables are intended for object storage that is somewhat more permanent
than that offered by global variables. For this reason, the contents of port
variables can not be changed once they are created, short of deleting them
with PURGE. STO returns the Object In Use error if you attempt to overwrite
the contents of an existing port variable, Furthermore, you can't delete a
port variable if the stored object is referenced, in which case PURGE returns
the same error message as STO. Referenced means that a stored object (or part
of it) has been recalled by one means or another, and the recalled copy is
still present--on the stack, in argument recovery or stack recovery memory, on
the program return stack, or in a local variable. Specifically, this means
that there is a pointer to the port variable object in any of these areas--see
section 5.7. On a HP 48GX, this can only happen for port 0 or port 1, since
objects in higher ports are copied to temporary memory when they are recalled.
To succeed in purging a port 0 or port 1 variable, you must first remove all
such references to the object, either individually, or collectively by
executing a system halt [ON}-[C]). Some references may be very subtle; for
example, if a program enters an object that is left on the stack or in a local
variable, the program will be referenced until the object is removed. Or, if
a program uses DOERR (section 9.6.2) with a string argument defined in the
program, the program will be referenced for the sake of the ERRM command until
ERR0 is executed or some subsequent error generates a new error message.
If you want to delete a port variable while keeping a copy of its stored
object, you must recall the object and either store it in a global variable or
another port variable, or execute NEWOB (section 11.6) with the object in
level 1. This creates a new copy of the object and unreferences the port
variable. Then you can use PURGE to delete the variable.
and about libraries specifically:
PURGE. To remove a library from a port, execute :n:ID PURGE. As in the case
of port variables, you will be unable to purge a library if it is referenced
in any way (Object In Use). In addition to the other ways that an object can
be referenced, a library is referenced when it is attached to the home
directory; you must detach it (see below) before purging.
When you purge a library, you may see the display jump briefly. This is
caused by the movement of display memory arising from the removal of an entry
in the HP 48's internal table of libraries; it is quite harmless.
And from the original edition of "HP 48 Insights Part I":
(In HP 48SX versions 1A - 1D, even a system halt does not clear the ERRM
reference.)
It occurs to me that an object could be referenced in a "suspended
environment" created by HALT and so on, so (unless dereferencing
by a warmstart) a CONT or KILL might be needed.
Of course what he's referring to by "referenced" is that, in many
cases, a "recalled object" hasn't really been "copied", but a
pointer to it that's still "in use" has been created. Changing
what's at the location pointed to would be a bad thing to do.
I suppose that what he wrote about a library attached to the "home
directory" would apply to a library attached to any of its
subdirectories as well, but I haven't experimented with this.
What he wrote about the 48GX ports 0 and 1 also applies to the
48SX port 2. As for how all of this applies to the 49 series
ports, you're on your own there.
It seems obvious, but of course you can't STO or PURGE in a ROM
card or write-protected RAM card; that results in a "Port Not
Available" error.
I consider the "Insights" series indispensable for RPL users, even
users of the 49 series; in case you don't have the books, scans of
them are available on The Museum of HP Calculators CD set / DVD.
See:
http://www.hpmuseum.org/cd/cddesc.htm
--
Regards,
James
Last Args Off
ERR0
KILL
anything else?
Yet another example of how perfectly clear the English language
makes everything. ;-)
By "when" I meant "at the time", as in "while" or "already", so
yes, I meant to enable last stack saves *before* pressing CONT.
But further experimentation shows that I was wrong about that
anyway (at least on the 49g+; I haven't tried it on the other
models). It seems that the state of last stack is preserved in the
suspended environment, as well as the last stack contents
(assuming that last stack was enabled) and any other local
variables. If I execute a HALT while last stack is enabled, then
disable last stack, then press CONT, the last stack is enabled
again, and UNDO gives me the last stack from the previously
suspended environment. Pretty nifty.
But note that the states of last command lines and last arguments
isn't similarly preserved in a suspended environment.
Actually, I almost always leave last stack and last command lines
enabled, turning them off only in low memory situations. Last
arguments I may force off (or on) for the sake of knowing what
will happen in the case of an error in an IFERR trap clause,
though always preserving the flags with RCLF or PUSH before and
restoring them with STOF or POP afterwards.
--
Regards,
James
I use LASTARG disabled for speed
My PC is only 3,06 GHz (+some overclocking)
so the emu runs quite slow
{ I should really learn more SysRPL [or ML (or C) ] }
It's possible to create a local variable at the top of the variable
stack without affecting the existing one.
While the only way you can destroy a variable is to delete "the last one".
That's why you can enable last stack at any time, but you can't disable
last stack without loosing the current local variables.
A new entry points would need to be written. I don't believe this is an
impossible task, it's certainly feasible
JY