TBL - Table Building Language

R. Freiburghouse
9/1974 - Revised 5/2000

TBL is designed to be easily compiled into a table of integers that can be used to implement an abstract machine. Examples of its use include Finite State Machines used as lexical analyzers or parsers. Top down recursive decent parsers, semantic analyzers, and code generators can also be implemented using table driven abstract machines.

The Syntax of TBL

<tbl>::= <name-definition>... 
<name-definition>::= LET<name> = 
<action>::= <label>:<body> | 
<label>::= <name>
<body>::= <function>; |
IF <function> THEN {<group>} |
IF <function> THEN {<group>} ELSE 
<group>::= <action>...
<function>::= <fname> | 
<fname>::= <name> | *... 
<argument-list>::= <argument> | <argument>, 
<argument>::= <name> | 
<integer>::= <digit>...
<digit>::= 0|1|2|3|4|5|6|7|8|9
<name>::= <letter> | <letter> 
<char>::= <letter> | <digit> | _
Blanks are delimiters.
/* causes the remainder of its containing line to be ignored.
[ and ] were used in older versions of the language because not all keyboards had { and }.

Semantics of TBL

Every <name> must be defined in a <name-definition> or as a <label> and a given <name> cannot be defined more than once. The name GOTO must also be defined in a <name-definition> and is used to implement the IF statement.

Asterisks used as prefixes on a function name have no intrinsic meaning, but can be used to document side effects of functions. For example, a single asterisk may indicate that the function backs up the input scanner by one token.

Compiling TBL Tables

The TBL compiler simply replaces each <name> used as an <action> or <argument> with the integer value defined for that name. It recognizes <name>s used as <label>s and generates named constant definitions so that those names can be used as indexes into the array of integers output by the compiler.

IF statements are compiled into a sequence of integers that represent the function to be invoked, the arguments to be passed, and the label (array index) to use for false. A GOTO is compiled at the end of the THEN group so that interpretation can continue following the ELSE group. For this reason the <name> GOTO must be defined by a <name-definition>.

For example, IF TEST(A,B,C) THEN {EMIT(X)} ELSE {EMIT(Y)} will translate into the sequence of integers values represented by these names: TEST, A, B, C, L1, EMIT, X, GOTO , L2, EMIT, Y. In this example, L1 is the index of the second EMIT and L2 is the index of the element immediately following the Y. The TEST function must resume interpretation using index L1 if its result is false and the GOTO function must resume interpretation using index L2.

The output of the TBL compiler is a one dimensional array of integers ordered exactly as their <name>s appear in the TBL source program. That array is written on a file and can be read or loaded with the interpreter that will read it. Additional output is an include file containing declarative statements that define named constants for all <label>s used within the TBL program. The named constants define the index value within the array represented by each label used in the TBL program.