Libraries, Functions, Callbacks, and Threads
Order SwiftForth™ for Windows, Mac OS X and Linux programming. Examples, source, documentation, more.
Mac and the Mac logo are trademarks of Apple Inc., registered in the U.S. and other countries.
Because SwiftForth was designed from the outset as a hosted system, great care has been given to make the interface to system and library functions as clean and easy to use as possible, given the inherent complexity of the OS environment.
System functions in Windows, Linux, and Mac OS X are provided to an application program via the dynamic library mechanism. SwiftForth supports a simple library function import mechanism that is based on the C function prototype.
Before referencing a function in a library, you must first open the library:
Any function in a library may be made available as a Forth word:
FUNCTION: <name> ( params -- result )
…where name is the (case-sensitive) published function name, params represents the list of paramters passed to the library function and the (optional) result is the returned value. Parameters are provided on the stack in the order described in the function prototype, so it's easy to reference the function from a Forth program.
Both C-prototype and Pascal-prototype library functions may be called; SwiftForth passes the parameter stack to the external functions automatically. Functions with identical names from different libraries may be invoked without name collision via an alias mechanism. Lists of currently attached libraries and their imported functions may be displayed in the debug window at any time.
Here is an example of the import of the Windows global memory allocation function from Kernel32.dll:
LIBRARY Kernel32 FUNCTION: GlobalAlloc ( uFlags dwBytes -- h )
This is the import of the Linux heap memory allocation function from libc:
LIBRARY libc.so.6 FUNCTION: malloc ( u -- addr )
The Mac OS X version is nearly identical to the Linux one:
LIBRARY libc.dylib FUNCTION: malloc ( u -- addr )
A callback is an entry point into your program. It is provided for the OS to call in certain circumstances to pass messages or signals to your program.
A callback is much like an interrupt in other programming environments, in that the code that responds to it is not executing as a sequential part of your application. In SwiftForth, callbacks are handled by a transient "task" with its own stacks and user area; it exists only for the duration of the callback function. Callbacks may execute any reentrant SwiftForth words, but may not directly communicate with the running program other than by storing data where the program may find it.
You may define a callback with any number of parameters, using the form:
<xt> <n> CB: <name>
…where xt is the execution token of the routine to respond to the callback, and n is the number of parameters passed to the callback.
A callback must always return a single integer result, which is used as the return value from the callback function. The defining word CB: wraps the execution of the xt with the necessary code to construct and discard the transient task environment in which the callback runs. Executing name returns the address to pass to the OS (e.g., as a message or signal handler).
SwiftForth provides a simple facility for defining and activating tasks which are themselves threads within the SwiftForth program. A thread is similar to the background task of other Forth implementations in that it is given its own Forth stacks and user area and is executing code from within SwiftForth's dictionary space.