th1-sgb  HowTo

Exceedingly Brief HowTo...

The canonical example program is in test.c. It shows what one needs to do to set up an interpreter and execute code through it.

Examples of binding custom functions can be found in th1*.c. Search those files for where "Th1_RegisterCommands" is called and follow the nearby function lists. The file th1.c holds the core interpreter, th1_lang.c holds the language-defined functions and function-like constructs, and th1_main.c holds "app-level" functions. The file th1_client.c is a stub which clients can use to get started with.

More documentation can be found here:

  • Paul Ruizendaal's TH Manual (PDF) is essentially the only user's guide to Fossil's TH1 language, and is invaluable for anyone wanting to use TH1.
  • i have ported Paul's document into Google Docs, expanding it a bit to include features specific to this TH1 implementation.

At its simplest, here is how one sets up an interpreter:

#include "th1.h"
...
Th1_Vtab vtab = Th1_Vtab_basic;
Th1_Interp * interp = Th1_CreateInterp( &vtab );

...
int rc;
rc = Th1_Eval_code( interp, "puts \"hi, world\\n\"\n", 0 );
rc = Th1_Eval_filename( interp, "foo.th1", 1 );
...

Th1_DeleteInterp( interp );

The real value in th1 comes in binding one's own C functions to it, such that they can be called from script code. How to do that is demonstrated in the various th1*.c files, and many invaluable details about TH1 can be found via the doc links above.

The Th1_Eval_xxx() family of functions evaluate "pure" script code, whereas the Th1_Render_xxx() family of functions evaluate code wrapped in TH1 tags in text documents.

The Th1_Vtab class shown above holds the "virtual" operations of the interpreter. This includes:

  • Memory de/re/allocation. It uses a realloc(3)-style interface, rather than a collection of malloc/free functions.
  • A generic output interface for use by script routines which want to generate output through a common mechanism. This allows, e.g., integrating output buffering features transparently to code which generates output. The function Th1_Output() sends all of its data via this output mechanism, so script-bound functions which generate output are encouraged to use Th1_Output() to do so.

The Vtab class might be expanded/changed as the engine is tweaked.

Client code must pass a Vtab instance when creating an interpreter, and can use the convenience object Th1_Vtab_basic to copy an instance which uses the C-standard memory management routines and sends its output to stdout by default (set vtab.out.pState to a FILE pointer to direct the ouput there).