# Term interpreter construction

Emulation can now be fully customized using user settable and describable Interps.

Emulation is the process of accepting characters and converting them to screen operations. The supported operations are embodied in the Ops interface and implemented inside Term.

The most common way to achieve the conversion is through a state machine. Therefore some classes are available for the construction and programming of such state machines.

## Using the state machine

The main class used in the state machine is AbstractInterp.State. It contains a vector of transitions indexed by chars. Only characters up to 128 are dealt with by the vector, all other characters cause a transition as set by State.setRegular().

A transition is characterized by the new state and the action to perform. Transitions are assigned to the state table via State.setAction(char c, State new_state, Actor actor). The first two are obvious. The actor is a singleton subclass of Actor that overrides Actor.action() in order to preform a specific action.

The state machine is programmed by creating new States and assigning transitions for each relevant character.

This scheme lends itself to object oriented inheritance by having subclass Interp's re-use their superclasses' state tables and actions. They can also modify the state tables they've inherited.

Because of this you need not start each new Interp from scratch. For example InterpDumb has a bases state 'st_base' and defines some common actions like ...

    	act_err		to indicate a bad state transition
    	act_regular	a regular character
    	act_nop		no-op used for intermediate states
    	act_cr		carriage return
    	act_lf		line feed
    	...

'st_base' is enhanced further and is joined by other states in InterpANSI.

## Why use Actors?

Actors seem like an odd and heavy-weight way to implement actions. The following techniques were considered:

1. Numbers used for actions and a switch statement for the semantics of the actions. An "inheritance" scheme can be implemented by having the default for a switch to pass the interpretation of the action code to a superclass.
2. Use preinitialized Methods and invoke().
3. The current Actor scheme.
4. No tables, instead each State to have it's processChar() function and a switch statement on the incoming character.

Schemes 1, 2 and 3 were actually somewhat implemented and compared. #2 turned out to be the worst, about 3-4 times slower than all the other schemes. The Actor scheme allows for quick virtual dispatch and should be marginally faster than switch statements which need to check bounds before indexing into a table. In the performed experiments there was no measurable difference between #1 and #3. Despite this the Actor scheme was picked because ...

- The "inheritance" scheme used in #1 multiplies the number of times a switch has to be performed.
- It's more OO than switch statements. It frees us from having to assign numbers to action codes.

This decision was made with the cognizance that inner class proliferation is probably not the best thing.

## Terminal types and termcap/terminfo

The premiere terminal specification is ISO/IEC 6429:1992(E), (also know as ANSI X3.64-1979?). This is generically referred to as an ANSI terminal.

The termcap specification for "ansi" is very simplistic and hardly covers the full gamut of operations. Not only that but vi seems to not work very well with TERM=ansi, particulary when it deals with long lines.

However, there is no name in the termcap database that represents the full 6429 spec, so for those we're stuck with using historical implementation names like "vt220", "xterm" and "dtterm".

I've chosen "dtterm" as it is the newest, I believe matches the ANSI spec best and some of it's extra features, like glyph gutters, are already implemented in Term.

## odds and ends

- Maybe the name should be changed to Emulator?
- Action -> Transition?
- better way to capture control stream
- processChar to move to AbstractInterp?