Post Reply 
HP48GX - Simple Program Question
08-29-2019, 07:56 AM (This post was last modified: 09-11-2019 05:23 AM by Giuseppe Donnini.)
Post: #3
RE: HP48GX - Simple Program Question
The following chart might help you understand what is really going on under the hood.


           «                While a program is being typed in, it
 TEXT       SIN             merely exists as a text string--in a
STRING      3.1415 *        format freely chosen by the user.
           »
               |
               |            Once [ENTER] is pressed, the string is
            PARSING         parsed and potential syntax errors
               &            are catched.  If there are no errors,
           COMPILING        the string is converted into a proper
               |            program object.
               |
               v
        +-------------+
        |D9D20E1632CA4|     Regardless of the format in which the
PROGRAM |B133920000000|     text string was originally entered,
OBJECT  |0000514130EED|     this internal representation will
        |A193632B2130 |     always have the same bit pattern.
        +-------------+
               |
               |            If the system later needs to display
               |            the program in a readable form, it will
               |            reconvert a copy of the program object
               |            into a text string according to certain
               |            rules.  For example, if the purpose is
               |            to show the program on the stack, the
               |            conversion will take into account the
               |            current display mode, e.g. if 2 FIX mode
               |            is active, 3.1415 will be displayed as
               |            3.14.  If on the other hand the purpose
               v            is to display the program in the editor,
               |            real numbers are shown in STD notation
               |            to avoid loss of precision; program
               |            structure words, like IF...THEN...END,
               |            are indented according to their level of
               |            nesting to make them stand out, etc.
               |            All this, however, does NOT in any way
               |            change the internal representation of
               |            the program.
               |
               +--------------------+--------------------+------------------+
               |                    |                    |                  |
         DECOMPILATION       DECOMPILATION         DECOMPILATION           etc.
          FOR EDITING          FOR STACK             FOR ASCII
               |            DISPLAY (2 FIX)        FILE TRANSFER
               |                    |                    |
               v                    v                    v
 TEXT    « SIN 3.1415 *      « SIN 3.14 * »      ( determined by )
STRING   »                                       ( TRANSIO value )


So in the end—as Bob already pointed out—the resulting program object will always be the same, whether you changed the line length of your source code or not.

But the very fact that you wanted to adjust it is quite interesting, because it reveals an actual problem: what might be a convenient format for the calculator's screen might become a real headache on a PC, and vice-versa. Unfortunately, when you transfer a program to the PC in ASCII mode, the line wrap width is automatically set to the HP-48's system default of 19 characters per line. Even if the nesting level of your program is only moderately deep, the result can be quite confusing on a PC screen.

The easiest solution to this problem is to convert the program to a string (using \->STR) before sending it to the PC. As a matter of fact, \->STR uses a line wrap width of 0, while still indenting all the program structure words. The contrast between a direct ASCII transfer:


%%HP: T(3)A(R)F(.);
\<< \-> test
  \<<
    IF DUP SIZE 1 >
    THEN OBJ\-> DUP 2
/ 1 + ROLL NEWOB \->
x
      \<< { } { } 2 4
ROLL
        START ROT
          IF DUP x
test EVAL
          THEN ROT
+ SWAP
          ELSE +
          END
        NEXT test
GSORT SWAP test
GSORT x + SWAP +
      \>>
    END
  \>>
\>>


and one preceded by \->STR:


%%HP: T(3)A(R)F(.);
\<< \-> test
  \<<
    IF DUP SIZE 1 >
    THEN OBJ\-> DUP 2 / 1 + ROLL NEWOB \-> x
      \<< { } { } 2 4 ROLL
        START ROT
          IF DUP x test EVAL
          THEN ROT + SWAP
          ELSE +
          END
        NEXT test GSORT SWAP test GSORT x + SWAP +
      \>>
    END
  \>>
\>>


speaks for itself, I think.

[The program used for the sake of illustration is Bill Wickes' GSORT (General-purpose Sort) program, which you will find on p. 328 of his excellent book "HP-48 Insights — I. Principles and Programming of the HP-48 — HP-48G/GX Edition," Corvallis 1993.]

But what if you need a specific line width? What if neither 19 nor 0 fits your bill? Take for example a long list of several hundreds or even thousands of numbers. You definitely don't want those displayed on a single line in your PC text editor! What you most probably want is one number per line, but a line wrap width of 19 will almost certainly produce something very different—and very messy.

So here is a little utility which I wrote for my own purposes that lets YOU specifiy the line wrap width (a compiled version is attached to the posting):


*******************************************************************************
* DCMP
*******************************************************************************
* ABSTRACT : Decompiles an object in standard display format, breaking down the
*            resulting string into lines of specified length.
*
* STACK    : ( ob %len --> $ )
*
*            * If %len = 0, no newlines are added after decompilation.
*
*            * If %len > 255, a line length of %len MOD 256 chars will be used.
*
*            * If ob is a string, no decompilation takes place, but newlines
*              are still inserted according to %len (if the latter is zero, the
*              string remains unchanged).
*******************************************************************************
ASSEMBLE

* Binary transfer header ; remove if compiled directly on the HP-48.

        NIBASC /HPHP48-A/

* Unsupported, but stable entry points:

=ResetSTKDC  EQU #159B4
=ederr       EQU #15A40

RPL

::
 0LASTOWDOB!     ( *Clear command name* )
 CK2NOLASTWD     ( *Require 2 arguments ; don't save command name* )
 CKREAL          ( *Require real on stack level 1* )
 ResetSTKDC      ( *Declare decompilation for editing, not for stack display* )
 COERCE          ( ob #len --> )
 !DcompWidth     ( ob --> ) ( *Set line length* )
 savefmt1        ( *Save user's wordsize & display format ; set 64bit & STD* )
 ERRSET          
   editdecomp$w  ( $ ) ( *Decompile using specified line length* )
 ERRTRAP         
   ederr         ( *If an error occurs, do rstfmt1 before erroring out* )
 rstfmt1         ( *Restore user's wordsize & display format* )
;


To carry on the list example above, just put your list on stack level 2, the real number 1 on stack level 1, and run DCMP. Theoretically, this would insert a line break after every single character, but since whole words are never broken up, the result will be the desired one-number-per-line format.

Compare the uses of:

—  \->STR or  0 DCMP  (no line wrapping):

%%HP: T(3)A(R)F(.);
{ 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400 }


—  normal ASCII transfer or  19 DCMP  (line wrap width = 19):

%%HP: T(3)A(R)F(.);
{ 1 4 9 16 25 36 49
64 81 100 121 144
169 196 225 256 289
324 361 400 }


—  and  1 DCMP  (line wrap width = 1):

%%HP: T(3)A(R)F(.);
{
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225
256
289
324
361
400
}


Attached File(s)
.zip  DCMP.zip (Size: 185 bytes / Downloads: 7)
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: HP48GX - Simple Program Question - Giuseppe Donnini - 08-29-2019 07:56 AM



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