Until makes writing applications with multiple interpreters trivial.
The normal Until outer interpreter is only about half a page of code.
Writing a specialized interpreter for an application is a very powerful
capability. The core interpreter can be used as a starting point for
other any specialized interpreter.

A typical approach is using the normal Until interpreter for startup to
load the application (.APP) file, then invoke the application specific
interpreter. The is the approach take for the IFP program in
[SMITH2].

#### UPDATE ####

Another successful multi-interpreter application is a document
interpreter for Standard Generalized Markup Language
(SGML) documents. A document viewer was easily
built
on top of the SGML interpreter that executes the document as a program
to format and display the document's contents. This software is
available via anonymous FTP at
FTP.IFI.UIO.NO in the
directory /pub/SGML/Demo/. The files are sengine.zip for the SGML
document interpreter and sviewer.zip for the SGML document viewer.

The rough equivalent of saving a turnkey application is sealing an Until
program. Sealed applications have the code hidden or 'sealed' from the
user. Sealing does not save the current state of the system the way
most traditional Forths do. The approach taken for Until is to encrypt
the source code then load it in the crypted form. The last thing in the
file must be the word that executes the application.

Sealing an application is done with the seal word:

seal until.app

The file UNTIL.BIN is created in this case.

seal is crude, but effective. There
appears
to be not good way to save the state of the dictionary that is not too
complex and portable. There are several enhancements that could be made
to seal. These include:

Accepting multiple input files

Appending to an existing .BIN file

True file compression, such as Hoffman encoding

A word, unseal, is included to allow you to view the result
of seal. If you are distributing sealed code, you might want
to disable unseal.

This section does not detail the Until implementation of
vocabularies; rather it simply identifies the words that are affected by
vocabulary operations. i.e. If you change anything relating to
vocabularies, count on having to change these words too!

This section describes the C-level I/O vector features in Until.
Skip Carter originally supplied these changes. C I/O vector code is
activated by defining the symbol VECTORED_C_IO in COMPILER.H. Including
this code slows normal processing slightly because some additional
function calls are made and there is a level of indirection to
all writes to the screen, whether informational messages or
Forth console output words such as type or emit
also are slower.

Two typical uses of this code are directing output to a file
or communicating across a network. Skip original test program
set up a socket network interface and ran Until on a remote
computer.

The general scheme is to set the vectors using the
user_outer_hook() function to set up the vectors. The
vectors are stdout_vect, stderr_vect, and
stdin_vect.

The Forth words affected by VECTOREC_C_IO are:

emit

printf

.

type

cr

."

abort"

.(

key #### CHECK ON ####

Those are the hints; implementation details are left to the
reader. (Hopefully, I'll fill in some details in a
future update.)

S-Engine is a Standard Generalized Markup Language (SGML) document
interpreter that embeds Until to form a powerful scripting language
for processing SGML documents. SGML is ISO Standard 8879:1986 and
is widely used by both government and industry.

SGML is a language for defining document markup languages. Think of
a markup language for memos for example. You define tags for
<from>, <to>, <subject>, etc. SGML markup
languages generally defines
document structure rather than document format. There are exceptions.
HTML is an SGML defined markup language that defines electronic
document format rather than structure.

S-Engine reads the SGML file, extracts tags, then executes them
as a word. There is a very structured scheme for using S-Engine.
Each SGML element is treated as an event where SGML data is
collected or processed. The general scheme is:

Define a string variable for each element that contains
data. Wrapper elements do not need strings.

Define colon definitions for each the start and
end element tags.

The start tag must be in <...>, i.e. <name>.

The end tag name must be in </...>, i.e. </name>

The colon definition for the start tag must specify
the SGML input buffer by calling read_into. For
example, : <name> name read_into ;

SGML attributes must have a string variable defined.

The attribute variable name must start with the element
name it applies to, followed by a `.', followed by the
attribute name. An attribute called `type' for element <name>
requires a string variable named name.type. Be sure that
the string is large enough to hold the data collected by
read_into.

The attribute value is available when the element word
executes. In <name type="xxx">, the "xxx" is available
when <name> executes.

SGML general entity substitution is done by defining a
colon definition. The first character must be an `&' and the
last character must be `;'. The body of the of the definition
should include a string with the substitution value. For
example, : &Forth; " Until" ;. Whenever "&Forth;" occurs
in the input stream, "Until" is substituted in the SGML
buffer.

Specify the SGML file with sengine_init.

Start S-Engine execution with sengine.

Use wrapper tags to do most of the processing.

Now let's see a simple example. This code can be found in
the files SGMLEX.APP and SGMLEX.SGM. There is only one element,
element, one attribute, attrib, and one entity,
SGML. So, the following variables must be set up:

This section identifies and describe the sample Until source files.
Some, but not all of these files are described in various places in
this manual. I figured the more examples the better, so I included
extra files in the distribution.