HP 48GX Indefinite Loops
|
03-28-2022, 01:11 AM
Post: #1
|
|||
|
|||
HP 48GX Indefinite Loops
When using indefinite loops, is there a logical way to end the loop before it executes one more time? Take a WHILE loop for example. I have a string that contains two line feed characters. The third line has no line feed character because no line proceeds it. My test condition is the value of POS when searching for the position of a line feed character. While POS isn't zero the loop continues. My program fails because the loop executes one more time, and there's no starting position for the final SUB. Any thoughts?
|
|||
03-28-2022, 03:33 AM
Post: #2
|
|||
|
|||
RE: HP 48GX Indefinite Loops
What about a DO... UNTIL... END loop? It works like a WHILE loop but the loop ends when a condition is met.
DO loop-clause UNTIL "string" "return character" POS 0 == END |
|||
03-28-2022, 04:11 AM
Post: #3
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(03-28-2022 01:11 AM)MNH Wrote: ...While POS isn't zero the loop continues. My program fails because the loop executes one more time, and there's no starting position for the final SUB. Any thoughts? If you're using the WHILE-REPEAT-END construct, keep in mind that REPEAT will take the value it's checking from the stack. You'd almost certainly want to make a copy of that value before REPEAT is executed so that you can use it later as needed. The "execution clause" between REPEAT and END definitely won't be executed if there's a 0 in stack level 1 when REPEAT is executed. Any value other than 0 (including negative numbers) will cause the execution clause to execute. Seeing your code in context along with sample input would be helpful to see what you're trying to do and perhaps why things aren't working as expected. |
|||
03-28-2022, 06:13 PM
Post: #4
|
|||
|
|||
RE: HP 48GX Indefinite Loops
I've seen some inelegant tricks of throwing an error inside an IFERR structure to act as an ersatz BREAK statement, but this is a case where a proper GOTO or BREAK would be very useful.
|
|||
03-28-2022, 07:13 PM
Post: #5
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(03-28-2022 06:13 PM)Dave Britten Wrote: I've seen some inelegant tricks of throwing an error inside an IFERR structure to act as an ersatz BREAK statement (…) E.g. in this earlier thread: RPL equivalents to BREAK, CYCLE, EXIT, etc.? |
|||
03-29-2022, 12:30 PM
Post: #6
|
|||
|
|||
RE: HP 48GX Indefinite Loops
I don't see a problem with just using the standard WHILE...REPEAT...END structure for something like this. The following will take a string with embedded linefeeds as input and return a list of the substrings delineated by those linefeeds. I'm sure this could be optimized more, but I just wanted to show a fairly straightforward approach.
Code: \<< |
|||
03-30-2022, 01:02 AM
Post: #7
|
|||
|
|||
RE: HP 48GX Indefinite Loops
I've used two methods for the 50g (depending on other items). One is the DO...WHILE..END pattern and the other is to use the FOR...NEXT and set the FOR statement's bound dummy outside the correct range to trigger a stop. Either works.
In a language I developed (along with another colleague), I used several types of loops. (It still didn't fix the common DO...UNTIL...UNLESS..IN WHICH CASE... method of thinking. Just to make things complicated, any combination of conditions could be combined. Loops could be named and these names were part of the syntax. The basic syntax for a Fortran style loop (the 50g FOR is like Fortran 66 rather than like Fortran 77 and later) Some of these structures might be useful if anyone makes another calculator language. Loops initiated by DO followed by any of several conditions I:j:k:l (I is the bound variable and j, k, l as the beginning, end, and increment. Default start and increment were each 1 (though, like Fortran, any values could be used to match the ability to index with negative numbers).) WHILE logical_value (evaluated before the loop executes.) k TIMES (k is the number of times the loop executes_ k IN (ENUMERATED SET) (Goes through an enumerated set defined elsewhere) (There may have been more, I don't remember.) Loops did have two types of ending. END_DO UNTIL logical_value One could write things like: LOOP: DO WHILE x > .001 100000 TIMES LOOP: UNTIL Y < .007 The point of putting labels first is for ease of reading; it's psychologically hard not to left-justify each loop. The statements CYCLE and EXIT or CYCLE_IF and EXIT _IF allow for "emergency" exits. Nested loops CYCLE or EXIT from the inside out or to the label with LABEL: EXIT or the like. There were some other weird but useful things like a BLOCK and END_BLOCK statement which can have and EXIT or newly defined variables with scope within the block. And while I'm rambling. The GOTO statement could only target numbered labels like GOTO 234 and the statement 234: CONTINUE as a target. The idea is that one could put these labels in numerical order for ease of reading. Numerical labels were "nonstructured" but alphanumeric labels were "structured" thought with lots of exits. Lots of array stuff and other numerical stuff, including unlimited integers and reals (though the latters two were not guaranteed to be fast.) |
|||
04-02-2022, 02:15 PM
Post: #8
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(03-28-2022 03:33 AM)Eddie W. Shore Wrote: What about a DO... UNTIL... END loop? It works like a WHILE loop but the loop ends when a condition is met. Thanks for replying! I tried the following. Program: CSV→ Checksum: # CAC6h Bytes: 282.5 Purpose: Remove line feed characters from a string. Store the resulting strings in a list. \<< 1 CF CSV DUP SIZE 10 CHR { } 1 \→ csv size char points position \<< DO csv DUP DUP char POS DUP DUP 0 == \<< 1 SF \>> IFT 'position' STO 2 - 1 SWAP SUB points SWAP + 'points' STO position 1 + size SUB 'csv' STO UNTIL 1 FS? END points \>> \>> @ Source: Notepad .csv file. 248,1529945.48000,521921.77300,100.60300,IRC 5/8 IL 249,1530002.95100,521922.24500,99.85000,AXLE 250,1530006.67800,521982.23700,102.17700,IRC 1/2 IL @ Input: Load Object... to Emu48. "248,1529945.48000,521921.77300,100.60300,IRC 5/8 IL ■ 249,1530002.95100,521922.24500,99.85000,AXLE ■ 250,1530006.67800,521982.23700,102.17700,IRC 1/2 IL" @ First iteration: Substring stored in 'points.' "248,1529945.48000,521921.77300,100.60300,IRC 5/8 IL" @ First iteration: Remaining string stored in 'csv.' "249,1530002.95100,521922.24500,99.85000,AXLE ■ 250,1530006.67800,521982.23700,102.17700,IRC 1/2 IL" @ Second iteration: Substring stored in 'points.' "249,1530002.95100,521922.24500,99.85000,AXLE" @ Second iteration: Remaining string stored in 'csv.' "250,1530006.67800,521982.23700,102.17700,IRC 1/2 IL" @ Third iteration: POS 0 ==, end WHILE loop @ Output: Error! @ Last string is empty. { "248,1529945.48000,521921.77300,100.60300,IRC 5/8 IL" "249,1530002.95100,521922.24500,99.85000,AXLE" "" } @ Desired output. { "248,1529945.48000,521921.77300,100.60300,IRC 5/8 IL" "249,1530002.95100,521922.24500,99.85000,AXLE" "250,1530006.67800,521982.23700,102.17700,IRC 1/2 IL" } |
|||
04-03-2022, 01:59 AM
(This post was last modified: 04-03-2022 02:16 AM by MNH.)
Post: #9
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(03-29-2022 12:30 PM)DavidM Wrote: I don't see a problem with just using the standard WHILE...REPEAT...END structure for something like this. The following will take a string with embedded linefeeds as input and return a list of the substrings delineated by those linefeeds. I'm sure this could be optimized more, but I just wanted to show a fairly straightforward approach. Thanks for your effort! I ran your code and didn't get the expected results. Input: 1: CSV @ .txt file (comma-separated values) Output: 4: "248,1529945.48000... 3: 0.0000 2: '→d' 1: << WHILE DUP 10.000... I had trouble debugging your code as evidenced by stack level one above. My second attempt at writing a solution appears below. Program: CSV→ Checksum: # 3AFBh Bytes: 305.0 Purpose: Remove line feed characters from a string. Store the resulting strings in a list. \<< 1 CF CSV DUP SIZE 10 CHR { } 1 \→ csv size char points position \<< DO csv DUP DUP char POS DUP DUP 0 ≠ \<< 'position' STO 2 - 1 SWAP SUB 'points' STO position 1 + size SUB 'csv' STO \>> \<< 1 SF 3 DROPN points SWAP + \>> IFTE UNTIL 1 FS? END \>> \>> Although the desired output has been attained, the DO...UNTIL...END structure still repeats one more time after the test condition returns a true (nonzero) result. I have to clean up the stack, which I shouldn't have to do if the program worked as expected. Any thoughts? |
|||
04-03-2022, 02:39 AM
Post: #10
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(03-29-2022 12:30 PM)DavidM Wrote: I'm sure this could be optimized more (…) Mostly copied but using local variables str and pos: Code: \<< I try to avoid modifying local variables using STO. |
|||
04-03-2022, 03:09 AM
Post: #11
|
|||
|
|||
RE: HP 48GX Indefinite Loops | |||
04-03-2022, 10:58 AM
Post: #12
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(04-03-2022 01:59 AM)MNH Wrote: Thanks for your effort! I ran your code and didn't get the expected results. As Thomas has indicated, there's very likely at least one typo in your transcription. In particular, there should be a space between the "→" and the "d". I should have included the size/checksum for verification so that you'd be able to compare it. I'll include that now: Size: 115 bytes Checksum: #1A7Bh You can avoid typos for something like this if you use a program that can translate a string using "trigraphs" into a compiled program. That way you can just copy and paste the program straight from the post into your emulated 48GX, translate it, and then store the result into a global variable of your choosing. No typing of the program required! One such program can be found in this post (usually referred to as INOUT). That program also converts a compiled program object that's on the stack into a string, with all special characters replaced by their trigraph equivalents. You can think of it as toggling what's in stack level 1 between text and compiled program forms. That should allow you to get the program entered into your emulated 48GX successfully for testing. |
|||
04-03-2022, 11:39 AM
Post: #13
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(04-03-2022 01:59 AM)MNH Wrote: \<< 1 CF CSV DUP SIZE Hmmm.... several thoughts. See the above post about INOUT, which would make it easier for others to be able to test the code. Also, placing the code into a code block (see the "#" button above the text when typing a post/response) would at least preserve the original ascii text along with the intended indentation. It also makes it a little easier to copy and paste (IMHO). I loaded your program into an emulated 48GX for testing and stepped through the flow with SST. If I'm understanding things correctly, you're wanting the 'points' local to have a list with each line in it. That local is only a list for a very short time, however, namely when it is first created as an empty list with the local assignment operator (→). Your code replaces that list with a string assignment in the THEN clause by using STO instead of STO+. Also, if you want the strings to be in the same order they are encountered in CSV, then you'll want to swap the new string and 'points' prior to STO+ being executed. In its current form, your program simply concatenates the previous string with the final string and leaves it on the stack. I don't believe that's what you intended, but I could be confused about exactly what your code is trying to achieve. Stepping through the code, the main loop is terminated correctly if flag 1 is set. Have you tried single-stepping through the code to see what it is doing? In summary: If I change this Code: 'points' STO Code: 'points' SWAP STO+ Hope this helps! |
|||
04-03-2022, 12:57 PM
Post: #14
|
|||
|
|||
RE: HP 48GX Indefinite Loops | |||
04-03-2022, 02:31 PM
Post: #15
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(04-03-2022 11:39 AM)DavidM Wrote: Also, placing the code into a code block (see the "#" button above the text when typing a post/response) would at least preserve the original ascii text along with the intended indentation. It also makes it a little easier to copy and paste (IMHO). Cf. How to Indent in MoHPC Forum |
|||
04-03-2022, 04:25 PM
Post: #16
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(04-03-2022 02:31 PM)Thomas Klemm Wrote:(04-03-2022 11:39 AM)DavidM Wrote: Also, placing the code into a code block (see the "#" button above the text when typing a post/response) would at least preserve the original ascii text along with the intended indentation. It also makes it a little easier to copy and paste (IMHO). Wow! My first post! |
|||
04-03-2022, 05:39 PM
(This post was last modified: 04-03-2022 05:52 PM by MNH.)
Post: #17
|
|||
|
|||
RE: HP 48GX Indefinite Loops
(04-03-2022 11:39 AM)DavidM Wrote: In summary: All of the information you provided helps. Thanks! I need some time to go over everything. I need to improve my programming skills. The use of 1E8 in your program is interesting. I'll be using my text file line feed character removal program to transfer files between my Emu48 and a tablet computer I use at work. The surveying software on the tablet is not very easy to use in some instances, so I'm trying to make my life easier by writing my own. Will I need a program to append line feed characters to a list of strings in order to send data to the tablet? I bought a thumb drive adapter for my Samsung phone for all of this. |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 2 Guest(s)