Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bug? Using KEYEVAL to toggle last stack corrupts local variables?

21 views
Skip to first unread message

James M. Prange

unread,
Apr 3, 2006, 1:26:44 PM4/3/06
to
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?

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

Raymond Del Tondo

unread,
Apr 3, 2006, 4:36:19 PM4/3/06
to
Hi,

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...

John H Meyers

unread,
Apr 3, 2006, 6:31:02 PM4/3/06
to
On Mon, 03 Apr 2006 12:26:44 -0500, James M. Prange wrote:

> 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]

Jean-Yves Avenard

unread,
Apr 3, 2006, 7:33:00 PM4/3/06
to
James M. Prange wrote:
> 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.

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

John H Meyers

unread,
Apr 3, 2006, 8:38:04 PM4/3/06
to
On Mon, 03 Apr 2006 15:36:19 -0500:

> 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]

Veli-Pekka Nousiainen

unread,
Apr 4, 2006, 5:36:35 AM4/4/06
to
"John H Meyers" <jhme...@miu.edu> wrote in message
news:op.s7gd5...@news.cis.dfn.de...
X

> 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


John H Meyers

unread,
Apr 4, 2006, 4:55:59 AM4/4/06
to
On Tue, 04 Apr 2006 04:36:35 -0500:

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]

John H Meyers

unread,
Apr 4, 2006, 5:23:24 AM4/4/06
to
For any readers wondering:

"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]

Veli-Pekka Nousiainen

unread,
Apr 4, 2006, 10:14:52 AM4/4/06
to
"John H Meyers" <jhme...@miu.edu> wrote in message
news:op.s7g63...@news.cis.dfn.de...

> On Tue, 04 Apr 2006 04:36:35 -0500:
>
> 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).

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?


James M. Prange

unread,
Apr 4, 2006, 7:11:27 PM4/4/06
to
Raymond Del Tondo wrote:

> 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

James M. Prange

unread,
Apr 4, 2006, 7:13:04 PM4/4/06
to
John H Meyers wrote:
> On Mon, 03 Apr 2006 12:26:44 -0500, James M. Prange wrote:

<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

James M. Prange

unread,
Apr 4, 2006, 7:13:46 PM4/4/06
to
Jean-Yves Avenard wrote:
> James M. Prange wrote:
>> 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.
>
> 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

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

James M. Prange

unread,
Apr 4, 2006, 10:13:32 PM4/4/06
to
Veli-Pekka Nousiainen wrote:
> "John H Meyers" <jhme...@miu.edu> wrote in message
> news:op.s7g63...@news.cis.dfn.de...
>> On Tue, 04 Apr 2006 04:36:35 -0500:

<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

Veli-Pekka Nousiainen

unread,
Apr 5, 2006, 6:09:47 AM4/5/06
to
"James M. Prange" <jmpr...@i-is.com> wrote in message
news:b2ab2$4432fd87$4267eab2$24...@123.NET...
X

>> 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.
when?
You mean "before"


Veli-Pekka Nousiainen

unread,
Apr 5, 2006, 6:11:58 AM4/5/06
to
"James M. Prange" <jmpr...@i-is.com> wrote in message
news:3ead9$443327d6$4267eab2$90...@123.NET...

> Veli-Pekka Nousiainen wrote:
>> "John H Meyers" <jhme...@miu.edu> wrote in message
>> news:op.s7g63...@news.cis.dfn.de...
>>> On Tue, 04 Apr 2006 04:36:35 -0500:
>
> <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?
>
> 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.

Last Args Off
ERR0
KILL
anything else?


James M. Prange

unread,
Apr 5, 2006, 5:11:51 PM4/5/06
to

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

Veli-Pekka Nousiainen

unread,
Apr 5, 2006, 9:47:58 PM4/5/06
to
"James M. Prange" <jmpr...@i-is.com> wrote in message
news:b4e81$44343299$4267ea85$48...@123.NET...
X

> 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.

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) ] }

Jean-Yves Avenard

unread,
Apr 5, 2006, 10:25:20 PM4/5/06
to
James M. Prange wrote:
> 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.
>
yes, last stack doesn't use a flag as such to enable/disable it.
But it checks that the local variables used to save the stack exists.
So when you go back to a previous environment, the local variables are
restored and therefore so is laststack

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

0 new messages