Post Reply 
How do I create a Subroutine using System RPL?
09-29-2022, 04:38 PM
Post: #9
RE: How do I create a Subroutine using System RPL?
(09-28-2022 10:10 PM)wmundstock Wrote:  I found the following example, but seems rather overly complicated for something simple.
Code:
RPL 
( C:\Users\User\Documents\HP Projects\SystemRPL\NonLibrarySubroutines\CMP.s, part of the NonLibrarySubroutine.hpp project, created by <> on 29/09/2022 )

* Main program starts here
::

    ' ( puts next object into the stack, in this case some short code )
    ::
       "Equal are the values"
    ;
    
    ' ( puts the second function to the stack )
    ::
       "Different are the values"
    ;
    
    ( Name each one of the LAMS as below. )
    { LAM ValuesAreEqual
            LAM ValuesAreDifferent }
            
    BIND ( This "stores the LAMs - creates temporary context )
    ( Carry on with your MAIN program )
    CK2&Dispatch
 REALREAL ::  ( note: REALREAL is in ROM and defined as #00011 )
    %= ITE
       LAM ValuesAreEqual ( this is how to call a LAM )
       LAM ValuesAreDifferent
 ;
        ABND ( Purge the temporary variables ).
        
;

There are a couple of structural problems above. I'll try to summarize.

The code word CK2&Dispatch should only be used in a library command, and it should be the first item in the code (after the initial ::, of course). This example is, by definition, a stand-alone program instead of a library command. So instead of CK2&Dispatch, you would use two separate code words:

CK2NOLASTWD
CK&DISPATCH1

Generally speaking, you start a program with the argument check/dispatch tools, then you proceed with setting up locals and validating argument applicability. I usually validate the arguments before setting up locals, unless the locals being defined would make it simpler to validate things. Forcing an early exit by raising an error will normally take care of an active temp environment, but it has to be marked appropriately for that to work. That marking is done with the CK<n>NOLASTWD command, which is but one reason that needs to be first in the code.

Here's how I would change your program to follow this flow:
Code:
RPL

INCLUDE DirMacro.s

ASSEMBLE
    Dir <CMPprog>
RPL
::
   CK2NOLASTWD
   CK&DISPATCH1
   REALREAL ::

      ( validate the arguments [none needed here] )
      ( if the reals needed to be in a certain range, or positive, or have
        no fractional part, or ..., this is where we would check those values )

      ( subroutine - values are equal )
      ' ::
         "Equal are the values"
      ;

      ( subroutine - values are not equal )
      ' ::
         "Different are the values"
      ;

      ( establish locals )
      {
         LAM ValuesAreEqual
         LAM ValuesAreDifferent
      }
      BIND

      ( main program - check for equality )
      %= ITE
         LAM ValuesAreEqual
         LAM ValuesAreDifferent

      ( abandon the LAMs )
      ABND
   ;
;

This is fine for an example program. You'll eventually want to explore null-named LAMs (instead of the named ones like we've used here). You can still give them names in the source code using DEFINE statements, but they are more memory efficient and measurably faster in a running program. The only time I use named LAMs is when I can't predict in advance if there will be intermediate temporary environments in existence later in the running program. Their existence would have the consequence of renumbering the null-named locals, so it would be difficult to deal with the renumbering without a lot of cumbersome code.

(Note: the inclusion of DirMacro.s and the "ASSEMBLE..RPL" header allow you to create a directory with multiple programs/objects -- see the example named "Direct" in the Debug4x Examples folder in your My Documents folder for more info)
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: How do I create a Subroutine using System RPL? - DavidM - 09-29-2022 04:38 PM



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