Post Reply 
Free42 LSTO REGS
09-25-2019, 03:52 PM
Post: #1
Free42 LSTO REGS
Greetings,

This is my first time posting. Generally, I've been content with just reading these forums, but I just discovered something about Free42's LSTO feature that I haven't seen mentioned anywhere and it's too exciting not to share!

This is how it started:

Code:
00 { 23-Byte Prgm }
01▸LBL "TstLSTO"
02 RCL "REGS"
03 LSTO "REGS"
...

If LSTO was used to create a local REGS, would all the commands that normally interact with REGS address that local REGS and leave the global REGS untouched?

I tried STO and RCL and their arithmetic, an assortment of STAT functions, ISG, DSE, printing the REGS, CLΣ and CLRG. I'm sure there's more, but all of these interacted with the local REGS and ignored the global one!

At the moment, I have no real need for this, but I rather like the idea that I can use the whole suite of REGS-related functions in a subroutine without worrying about their impact on previously stored data.
Find all posts by this user
Quote this message in a reply
09-26-2019, 05:50 PM
Post: #2
RE: Free42 LSTO REGS
Wow that's cool!

It might also mean that if you have an old program that uses lots of registers and stores it's results on the stack, then you might be able to run it cleanly by doing LSTO "REGS" and then calling the program.
Find all posts by this user
Quote this message in a reply
09-26-2019, 08:10 PM
Post: #3
RE: Free42 LSTO REGS
(09-26-2019 05:50 PM)David Hayden Wrote:  Wow that's cool!

It might also mean that if you have an old program that uses lots of registers and stores it's results on the stack, then you might be able to run it cleanly by doing LSTO "REGS" and then calling the program.

You even can create temporary "REGS" for use in manual mode only
Code:

01 LBL "AREGS"
02 NEWMAT
03 LSTO "REGS"
04 STOP
05 RTN

Put your desired nRows and 1 on the STACK and run AREGS. After that you'll have that new set of registers available until you hit R/S, this will invoke RTN and thus reactivate the standard REGS.

But wait a minute. Before you hit R/S you could save your "local" REGS as a normal VAR e.g. "REGS1" for later use. Then when you sometime later want to reactivate "REGS1" just recall it and LSTO it to "REGS" but then to return to the original "REGS" you have to do a RTN. GTO .. does it also.

Cool? Günter
Find all posts by this user
Quote this message in a reply
09-28-2019, 02:53 AM
Post: #4
RE: Free42 LSTO REGS
You can also use LSTO from the keyboard; it is not program-only. Like in Günter's example, you end up with a variable that will go away when you do run-mode GTO, XEQ, RTN, BST, edit a program, etc. Specifically, all local variables are deleted by the same set of actions that cause the RTN stack to be cleared on the HP-42S.
Visit this user's website Find all posts by this user
Quote this message in a reply
09-28-2019, 03:19 AM
Post: #5
RE: Free42 LSTO REGS
To elaborate a bit: every local variable is associated with a level of the RTN stack. LSTO creates variables on the current level, and when that level is popped, the associated variables are deleted. And, any action that clears the entire RTN stack, like GTO, XEQ, or RTN in RUN mode, clears all local variables.

There is one quirk to this: LSTO can also create variables when the RTN stack is already empty. It has to be able to do this, in order to work in a subroutine that is invoked from the keyboard. Say you do XEQ "FOO" from the keyboard with this in program memory:

Code:
01 LBL "FOO"
02 LSTO "X"
03 R↓
04 LSTO "Y"
[...]

When the LSTO instructions are performed, there is nothing on the RTN stack, unlike when the XEQ "FOO" is done from a program, but of course you'd want LSTO to work even in this scenario.

When a program performs RTN while the RTN stack is empty, this causes the empty-stack locals (referred to as "level 0" in the source code, the RTN stack "level" being the number of pending returns) to be deleted, so when the program "FOO" above ends with a RTN, its locals disappear, even though they were never associated with an actual RTN. And this same mechanism can be used in RUN mode.
Visit this user's website Find all posts by this user
Quote this message in a reply
10-04-2019, 12:34 PM (This post was last modified: 10-04-2019 12:36 PM by Namir.)
Post: #6
RE: Free42 LSTO REGS
The technique of of using local REGS is wonderful! I wrote a short test where I stored values in regular registers, called a subroutine, created a local copy of REGS, and accessed the copies. This method allows you to pass values not only in the stack, but also though numbered registers to a subroutines. The called subroutine can return the result(s) in the stack OR in gobal named variables. Using local REGS allows the subroutine to use any numbered register, that does not supply it with input values, to store whatever intermediate results needed.

Thanks Thomas for making the feature of local REGS available!

Here is my short test program:

Code:
01▸LBL "AA"
02 100
03 STO 00
04 200
05 STO 01
06 XEQ "BB"
07 "X="
08 ARCL 00
09 PROMPT
10 RTN
11▸LBL "BB"
12 RCL "REGS"
13 LSTO "REGS"
14 1
15 STO 00
16 "XS="
17 ARCL 00
18 PROMPT
19 "YS="
20 ARCL 01
21 PROMPT

Namir
Find all posts by this user
Quote this message in a reply
10-05-2019, 08:46 AM
Post: #7
RE: Free42 LSTO REGS
The 34S introduced local variables that were allocated per return stack frame (thanks Marcus). These were initially used by some of the internal keystroke programmes (XROM). They are not at the same level of sophistication that Free42 now has. I suspect that there might be some middle ground between the two but why would anyone compromise?

The most important benefit is that the two major HP calculator projects have been learning from each other,

Pauli
Find all posts by this user
Quote this message in a reply
10-21-2019, 09:31 AM
Post: #8
RE: Free42 LSTO REGS
Just came across one of my programs that uses DIM to create a matrix in memory without using another stack register. Haven't found a way to LSTO/LDIM this without creating a matrix on the stack first. Of course now I can save the stack content first.
Visit this user's website Find all posts by this user
Quote this message in a reply
10-21-2019, 03:07 PM
Post: #9
RE: Free42 LSTO REGS
(10-21-2019 09:31 AM)SammysHP Wrote:  Just came across one of my programs that uses DIM to create a matrix in memory without using another stack register. Haven't found a way to LSTO/LDIM this without creating a matrix on the stack first. Of course now I can save the stack content first.

I think...

Code:
NEWMAT
LSTO "MAT"
DIM?

...should take your rows and columns from Y and X, make a new matrix, store it locally in REGS and then return your rows and columns to Y and X. That should account for everything but the LastX register, which would have your new matrix in it instead.

I was thinking you could even slap the "LDIM" label on it and make it a program, but that would be self-defeating since it would discard the LSTO'ed matrix once it returns to whatever called it.
Find all posts by this user
Quote this message in a reply
10-23-2019, 12:01 PM
Post: #10
RE: Free42 LSTO REGS
(10-21-2019 03:07 PM)Epidiah Wrote:  I was thinking you could even slap the "LDIM" label on it and make it a program, but that would be self-defeating since it would discard the LSTO'ed matrix once it returns to whatever called it.

Yes, this is a bit of a problem. It would be nice if you could create subroutines for preserving state, like preserving the entire stack, and right now, you can't.

One way to fix this would be to add a modified RTN instruction, let's call it LRTN for now, that has the effect of not popping local variables created at the current level, instead moving them one level up the stack, as if they had been created by the caller. So you could write a stack saver like

LBL "SPUSH" LSTO "X" R↓ LSTO "Y" R↓ LSTO "Z" R↓ LSTO "T" LASTX LSTO "L" LRTN

and restore the entire stack with

LBL "SPOP" RCL "L" STO ST L RCL "T" RCL "Z" RCL"Y" RCL "X" RTN

leaving the local variables to be popped automatically:

LBL "SOMEFUN" XEQ "SPUSH" <do something useful here> XEQ "SPOP" RTN

(Of course the sequence XEQ "FOO" RTN can be replaced by GTO "FOO" (tail call optimization) but that can make the code harder for humans to understand.)

Variations on the SPOP function could be created to mimic the behavior of unary or binary operators as well.

Thoughts? Would LRTN be a good name, or can someone suggest something better, i.e. a better name for that function, or an altogether better way to fix this LSTO limitation?
Visit this user's website Find all posts by this user
Quote this message in a reply
10-23-2019, 01:38 PM
Post: #11
RE: Free42 LSTO REGS
Cool idea! This makes it trivial to save the stack state, go do 'whatever' and then restore it.

"LRTN" seems a good name, reinforcing the idea of preserving the local state.

I suppose this could lead to some confusion if the user forgets to LRTN, is adding a new "L" annunciator feasible?

This new capability would be nicely complemented by a pair of commands that get and save the state of all flags (user and system), perhaps GETF and SAVEF; using these in SPUSH and SPOP (also adding available commands to save the registers) would allow them to save the full machine state, from the user's perspective, while running 'whatever'.

It's possible that some system flags could be problematic here, but I imagine you would know about those and they could be 'skipped' if needed.

--Bob Prosperi
Find all posts by this user
Quote this message in a reply
10-23-2019, 02:22 PM
Post: #12
RE: Free42 LSTO REGS
(10-23-2019 12:01 PM)Thomas Okken Wrote:  Thoughts? Would LRTN be a good name, or can someone suggest something better, i.e. a better name for that function, or an altogether better way to fix this LSTO limitation?

Would a LXEQ be feasible? Something that would let the program doing the calling decide if it wanted to preserve the local variables from the subroutine?

I feel like that's more flexible, but LRTN does have the advantage of not having to remember which subroutines you want to recall the local variables from.
Find all posts by this user
Quote this message in a reply
10-23-2019, 11:51 PM
Post: #13
RE: Free42 LSTO REGS
Once you try to add functions that make it possible to truly emulate function-like behavior of subroutines, things seem to get messy pretty quickly. Even LRTN isn't as elegant as I first thought, because pushing locals into the caller's stack frame means possible name clashes, so now you have to make sure that the names of your locals don't collide with those used by your SPUSH function.

Bah. Back to the drawing board. Smile
Visit this user's website Find all posts by this user
Quote this message in a reply
10-24-2019, 11:37 AM
Post: #14
RE: Free42 LSTO REGS
A more thorough approach to the problem of creating subroutines that look and behave like built-in functions might go like this:

First, a special kind of label, let's call it FLBL. This works just like a regular LBL, the difference being that a call to FLBL "FOO" is displayed as FOO, not XEQ "FOO".

Second, an easy way to save and restore state. Saving state could be done by a new function FSAVE, possibly to be combined with FLBL, and it would save the stack registers, LASTx, ALPHA, and all flags. Restoring state would be done by a new function FRTN, with variants FRTN_U, FRTN_B, FRTN_E for functions that act like unary operators, binary operators, or return an error status, respectively. (Error status can also be used to implement conditionals; the special behavior of the "Yes" and "No" messages is part of the system already and it's how all the built-in conditionals are implemented.) Of course it gets more complicated, because what if a function is supposed to have multiple side effects?

Third, because all this encourages the creation of large function libraries, the flat program space becomes an issue and directories are back on the agenda. Those same directories that were supposed to be unnecessary once easy state file switching was implemented.

TL;DR Once you start thinking hard about extending RPN keystroke programming, all roads lead to RPL. Smile
Visit this user's website Find all posts by this user
Quote this message in a reply
10-24-2019, 12:26 PM
Post: #15
RE: Free42 LSTO REGS
(10-24-2019 11:37 AM)Thomas Okken Wrote:  TL;DR Once you start thinking hard about extending RPN keystroke programming, all roads lead to RPL. Smile

I realised this quite some years ago Smile


The 34S has a pair of functions Xin and Xout which allow the internal keystroke programs to behave like builtin commands. Xin takes an argument that specifies the number of input and output arguments and the stack handling is done behind the scenes. There are a number of other features/complications involved.

Pauli
Find all posts by this user
Quote this message in a reply
10-24-2019, 12:57 PM (This post was last modified: 10-24-2019 12:57 PM by Epidiah.)
Post: #16
RE: Free42 LSTO REGS
It's a long, dark road, indeed!

Not to distract from any discussion about function-like routines--because if I'm honest, I find the prospect of a FLBL thrilling and looking at the 17 files states I've built around program themes it's clear this is the direction I'm naturally drifting toward--I wanted to sing the praises of LSTO REGS one more time.

This combo has made working with two matrices and moving data between them without disturbing the contents of REGS a bit of a breeze. Here's a quick one I whipped up that takes a vector and turns it into the main diagonal of a square matrix.

Code:
00 { 89-Byte Prgm }
01▸LBL "V→[\]"
02 LSTO "L"
03 LSTO "REGS"
04 R↓
05 LSTO "Y"
06 R↓
07 LSTO "Z"
08 R↓
09 LSTO "T"
10 R↓
11 DIM?
12 X<Y?
13 X<>Y
14 ENTER
15 NEWMAT
16 -1
17 RCL+ ST L
18 1ᴇ-3
19 ×
20 LSTO "#"
21 R↓
22 EDIT
23▸LBL 00
24 RCL IND "#"
25 →
26 ↓
27 ISG "#"
28 GTO 00
29 EXITALL
30 RCL "L"
31 STO ST L
32 R↓
33 RCL "T"
34 X<>Y
35 RCL "Z"
36 X<>Y
37 RCL "Y"
38 X<>Y
39 END

I'm throwing LSTO all over the place here to preserve the stack and the REGS, but the main thing is that I can have the program EDIT one matrix while another sits in REGS where I can pluck entries out of it at whim. That's so much easier than flopping back and forth, indexing one matrix after another, adjusting I and J each time.
Find all posts by this user
Quote this message in a reply
10-25-2019, 01:50 AM
Post: #17
RE: Free42 LSTO REGS
(10-21-2019 03:07 PM)Epidiah Wrote:  I think...

Code:
NEWMAT
LSTO "MAT"
DIM?

...should take your rows and columns from Y and X, make a new matrix, store it locally in REGS and then return your rows and columns to Y and X. That should account for everything but the LastX register, which would have your new matrix in it instead.

Wait! It's not nearly elaborate as all that!

All you need is:
Code:
LSTO "MAT"
DIM "MAT"
The LSTO creates the local variable and the DIM turns it into what you want.

This has me thinking about getting into the habit of declaring local variables and then calling the subroutines that fill them.
Find all posts by this user
Quote this message in a reply
10-25-2019, 06:21 AM
Post: #18
RE: Free42 LSTO REGS
Barring the stack save-and-restore, that can be done a bit more easily:

Code:
>LBL "DIAG"
 LSTO "X"
 DIM?
 +
 ENTER
 DSE ST X
 DIM "X"
 RCL "X"
 TRANS
 STO "X"
 Rv
 ENTER
 DIM "X"
 RCL "X"
 END

Too bad DIM only works on named variables, or I could've done it all in the stack.

Cheers, Werner

41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE
Find all posts by this user
Quote this message in a reply
10-25-2019, 02:02 PM
Post: #19
RE: Free42 LSTO REGS
Oh, that's clever! I hadn't thought about redimensioning the matrix. It'll work to reverse it, too!

Code:
00 { 36-Byte Prgm }
01▸LBL "GAID"
02 LSTO "X"
03 DIM?
04 1
05 +
06 DIM "X"
07 RCL "X"
08 TRANS
09 STO "X"
10 R↑
11 1
12 DIM "X"
13 RCL "X"
14 END

My search for an indispensable use of LSTO REGS continues...
Find all posts by this user
Quote this message in a reply
10-25-2019, 07:17 PM (This post was last modified: 10-25-2019 07:17 PM by SammysHP.)
Post: #20
RE: Free42 LSTO REGS
(10-25-2019 01:50 AM)Epidiah Wrote:  All you need is:
Code:
LSTO "MAT"
DIM "MAT"
The LSTO creates the local variable and the DIM turns it into what you want.

Thanks, didn't thought about storing whatever is on the stack just to declare the variable!
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)