Building Standalone Programs

The basics

After all the initialisation has been performed, the deferred word ENTRYPOINT is executed. The most basic way to make a turnkey application is just to set ENTRYPOINT and then SAVE the application. Some examples follow.

Later sections in this chapter discuss startup and shutdown in detail.

Windows GUI

You can use a messagebox or a modal dialog as the application; anything that runs the Windows message pump will work.


: start  \ hmodule 0 commandline show -- res
  4drop
  WalkColdChain          \ run startup chain
  0 z" Hello World" z" VFX Forth" MB_OK MessageBox drop
  0
;
' start is EntryPoint
Save hello
bye

Windows console


: start  \ hmodule 0 commandline show -- res
  4drop
  WalkColdChain          \ run startup chain
  ." Hello World! from VFX" cr
  0
;
' start is EntryPoint
SaveConsole hello
bye

OS X and Linux console


: start  \ hmodule 0 commandline show -- res
  4drop
  WalkColdChain          \ run startup chain
  ." Hello World! from VFX" cr
  0
;
' start is EntryPoint
Save hello
bye

Sequence of Events

When a Forth program runs there are five stages from program launch to termination.

OS_Startup

The code required to bridge the gap between Forth and the host operating system. This code is handwritten by MPE and cannot be changed in any manner (to do so would cripple the system)

Initialisation

The setup of various system variables, stack pointers, user areas etc. Also the initialisation of import DLL functions etc. The various words which perform these operations are formed into a linked list called the Cold Chain which is executed automatically at the start of EntryChain.

BootStrap

The execution of either the default interpreter or the end-user's turnkey application. There is a little stub of code which sets up some input parameters before calling the DEFERed word EntryPoint.

EntryPoint

Should run WalkColdChain and then the application code which runs until shut down.

Shutdown

When the application terminates, VFX Forth runs an exit chain similar to the cold chain. Any actions required for a clean shutdown should be added to this chain.

To generate stand-alone executable programs, three steps are required.

The EntryPoint word

At the end of the start up chain EntryPoint is called. This word is DEFERed and can be re-assigned by the user.

The entrypoint definition is supplied by the end-user for a turnkey application. The system has a default entry point which simply launches the interpreter. An entry point definition has the following format:-


  MyEntryPoint    \ hmodule 0 commandline show -- res

Where the parameters are:

HMODULE

The "module handle". For instance under Windows the module-handle is the base address of the parent process when running in memory.

0

A reserved field.

COMMANDLINE

A zero terminated string from the operating system describing the command line used to launch the system. Where this information is unavailable this field will be 0.

SHOW

An operating system specific field describing what visual effect should be used to start the application. In Windows this value can be passed directly to ShowWindow().

RES

The result with which to exit the program.

The syntax used to reset the entry point is:


  ASSIGN <myword> TO-DO ENTRYPOINT
or
  ' <myword> IS ENTRYPOINT

and should be placed at the end of your source build before SAVE.

Under some operating systems and I/O devices, you must flush pending output before shutting down, otherwise it will be unseen (still be buffered) when the program terminates. For example, this may not work.


: start  \ hmodule 0 commandline show -- res
  4drop
  ." Hello World! from VFX" cr
  0
;
Assign start to-do EntryPoint
Save hello
bye

What happens is that the buffered output has not been displayed before the program terminates. To fix this there are three options:

Note that under some operating systems you cannot save a file of the same name as the one that is currently executing.

Startup and Shutdown words

: ShowColdChain         \ --
Show on the console the sequence of events which make up the current start up code. The sequence is shown in the order in which it is executed.

: ShowExitChain         \ --
Show on the console the sequence of events which make up the current exit actions. The sequence is shown in the order in which it is executed.

: WalkColdChain         \ --
Walk the cold chain. Used during startup.

: WalkExitChain         \ --
Walk the exit chain. Used during shutdown.

: AtCold        \ xt --
Specify a new XT to execute when the Cold chain sequence is run.

: AtExit        \ xt --
Add a new XT to execute on BYE.

: FREEZE        \ --
Setup initial user area/global values for SAVE. FREEZE is performed by the guts of SAVE.

: (init)        \ --
Set up system variables, task0 user area, search order etc.

variable ExitCode       \ -- addr
Holds exit code returned to the operating system.

: bye           \ --
Runs the shutdown chain, and exits to the operating system, returning the exit code from the variable ExitCode. The meaning of the exit code is operating system dependent.

: cold          \ --
System entry point. Runs the cold chain and then the application EntryPoint code. When the application finishes, the exit chain is run and the application terminates.

Saving to an Mach-o file

The following sequence performs this operation:


ok SAVE myfile.mo
ok BYE
poop> ./myfile.mo

: Mb            \ n -- nMb ; nMb = n * 1048576
Given n, returns n megabytes. Useful before SET-SIZE or ALLOCATE.

: Kb            \ n -- nKb ; nKb = n * 1024
Given n, returns n kilobytes. Useful before SET-SIZE or ALLOCATE.

: get-size      \ -- size
Return the amount of memory used by the Forth dictionary and system headers.

: set-size      \ size --
Set the amount of memory to be used by the Forth dictionary and system headers. This will not take effect until the system has been SAVEd to form a new Mach-o file. The new dictionary size will be used when the new Mach-o file is run.

: get-stacks    \ -- size
Return the amount of memory available for Forth stacks and user areas.

: set-stacks    \ size --
Set the amount of memory to be used by the Forth stacks and user area. This will not take effect until the system has been SAVEd to form a new Mach-o file. The new size will be used when the new Mach-o file is run.

: $SaveImage    \ caddr len -- len'
Save the Forth image to the given file. The image file size is returned.

: setExecPerms  \ caddr len --
Set execute permissions on the file.

: Save          \ "<name>" -- ; SAVE <name>
Save the application to the file given by the following file name. No extension is applied to the name. The image is saved as a Mach-o file.