Post Reply 
User-defined functions in Free42
01-10-2021, 02:18 PM
Post: #1
User-defined functions in Free42
Hi all,

In Free42 2.5.23, I introduced a few new functions that are meant to help create subroutines that behave like built-in functions. The idea is to make it easier to implement the proper stack behavior, and to allow subroutines to return error codes and to act as conditionals.

The implementation of these functions in 2.5.23 is functional, but flawed. I wasn't happy about it and made several improvements, in the areas of error handling and RTN behavior.

The descriptions on my web site cover the implementation in the official 2.5.23 release; the following documents the implementation in my current prototype:

FUNC0, FUNC1, and FUNC2: These functions preserve the stack and LASTx, in preparation for restoring registers when the function returns. Upon RTN, a function initialized with FUNC0 will restore all four stack registers and LASTx to their original values; a function initialized with FUNC1 will leave X intact, restore the original X to LASTx, and restore Y, Z, and T to their original values; and a function initialized with FUNC2 will leave X intact, restore the original X to LASTx, and restore T to T and Z, and restore Z to Y.

Thus, in order to implement a binary operator, all that's needed is to call FUNC2 at the beginning of the function, and make sure the result is in X when it returns. The stack restoration happens automagically upon RTN.

The other additions are RTN variations:

RTNYES and RTNNO allow a function to behave like a conditional. In terms of the flow of control, RTNYES acts just like RTN, while RTNNO returns to the line after the one RTN would return to, skipping the line right after the calling XEQ. The reason RTNYES is a separate function is because of its behavior when the function was XEQ'd from the keyboard: in that case, RTNYES will display the message "Yes" ans RTNNO will display the message "No".

RTNERR allows a function to raise an error message. The error message is selected using a number in X, as follows:

0: No Error
1: Alpha Data Is Invalid
2: Out of Range
3: Divide by 0
4: Invalid Type
5: Invalid Data
6: Nonexistent
7: Dimension Error


If the function was called from a program, the error message will be displayed and execution will halt on the calling XEQ; if the function was called from the keyboard or from SOLVE or INTEG, execution will halt on the RTNERR (except for the errors trapped by SOLVE, as usual).

Note that when a function terminates with RTNERR, the stack contents saved by FUNC0/1/2 will be restored to their original state, i.e. all four stack registers and LASTx restored, regardless of which of the three functions was used.

To help implement robust error handling, flag 25 is saved (and cleared) by FUNC0/1/2, and it is restored upon RTN. So, a caller can use flag 25 to catch errors raised by RTNERR, while functions can use, or not use, flag 25 internally as they see fit, and these usages will not interfere with each other.

These changes will be in the next release, but I've put a test build up at https://thomasokken.com/free42/download/...indows.zip for testing. Note that this introduces a new state file version, so be sure to save your existing state before using this if you want to be able to go back to using the previous version after looking at this one.

I hope this is useful. Please feel free to share your thoughts here!

Thomas
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
User-defined functions in Free42 - Thomas Okken - 01-10-2021 02:18 PM



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