DisplayControllers:
CEDAR
DEFINITIONS = {
REFTEXT: TYPE = REF TEXT;
ROPE: TYPE = Rope.ROPE;
CharDisplay: TYPE = CharDisplays.CharDisplay;
BoolDefaultsFalse: TYPE = CharDisplays.BoolDefaultsFalse;
DisplayController: TYPE = REF DisplayControllerRep;
DisplayControllerRep:
TYPE =
RECORD [
cd: CharDisplay,
cp: ControlProgram,
cps: ControlProgramState,
toDisplay, fromDisplay:
IO.
STREAM,
Destruction of the display, and hence the controller, closes these streams.
driver:
IO.
STREAM ←
NIL
Here for only one purpose: driver.CharsAvail[] tells whether more coming soon.
];
Create: PROC [cd: CharDisplay, cp: ControlProgram] RETURNS [dc: DisplayController];
SetDriver: PROC [dc: DisplayController, driver: IO.STREAM];
ControlProgram: TYPE = REF ControlProgramRep;
ControlProgramRep:
TYPE =
RECORD [
bits: [7 .. 8],
start: Vertex,
Init: PROC [dc: DisplayController],
clientData: REF ANY
];
Vertex: TYPE = REF VertexRep;
VertexRep:
TYPE =
RECORD [
repStyle: VertexRepStyle,
t: Transition ← [[NIL, NIL], NIL],
edgeList: EdgeList ← NIL,
edgeArray: TransitionArray ← NIL];
VertexRepStyle: TYPE = {epsilon, list, array};
TransitionArray: TYPE = REF TransitionArrayRep;
TransitionArrayRep: TYPE = ARRAY CHAR OF Transition;
EdgeList: TYPE = LIST OF Edge;
Edge:
TYPE =
RECORD [
char: CHAR,
transition: Transition
];
Transition:
TYPE =
RECORD [
action: Action,
newVertex: Vertex];
Action: TYPE = RECORD [proc: ActionProc, clientData: REF ANY ← NIL, overrideable: BOOL ← FALSE];
ActionProc: TYPE = PROC [dc: DisplayController, clientData: REF ANY];
ControlProgramState: TYPE = REF ControlProgramStateRep;
ControlProgramStateRep:
TYPE =
RECORD [
curVertex: Vertex ← NIL,
regs: ARRAY RegID OF INTEGER ← ALL[0],
modes: Modes ← ALL[FALSE],
chars--since last in start state--: REFTEXT,
clientData: REF ANY ← NIL
];
RegID: TYPE = {line, col, aux1, aux2, aux3, aux4};
Mode: TYPE = {insert, delete};
Modes: TYPE = ARRAY Mode OF BoolDefaultsFalse;
NewControlProgram: PROC [Init: PROC [dc: DisplayController] ← NIL, clientData: REF ANY ← NIL, bits: [7 .. 8] ← 8] RETURNS [cp: ControlProgram];
AddInstruction: PROC [cp: ControlProgram, steps: StepList, final: Action];
StepList: TYPE = LIST OF Step;
Step: TYPE = REF ANY --actually UNION [ROPE, REFTEXT, Decode]--;
Decode: TYPE = REF DecodeRep;
DecodeRep:
TYPE =
RECORD [
reg: RegID,
base: NAT ← 10,
org: CHAR ← '0,
offset: INT ← 0,
xor: INTEGER ← 0,
len: NAT ← 0 --=0 means variable length, #0 means fixed--];
decodes ((char XOR xor) - org) by base, then adds offset
NumChars: NAT = (LAST[CHAR] - FIRST[CHAR]) + 1;
Naught: ActionProc;
Print: ActionProc;
}.