ParserImpl.mesa
Last Edited by: Arnon, July 19, 1985 2:54:46 pm PDT
DIRECTORY
Rope,
IO,
Convert,
MathDisplayExpr,
Parser;
ParserImpl: CEDAR PROGRAM
IMPORTS Convert, Rope
EXPORTS Parser
= BEGIN OPEN Parser;
Signals & Errors
parseError: PUBLIC ERROR = CODE;
Type Abbreviations From Imported Interfaces
ROPE: TYPE ~ Rope.ROPE;
DisplayExpr: TYPE ~ MathDisplayExpr.DisplayExpr;
Procs
LexChar: PUBLIC PROC[c: CHAR] RETURNS[LexType] ~ {
effects: Returns the lexical type of c
RETURN[
SELECT c FROM
IN ['0..'9] => digit,
IN ['a..'z] => lcAlpha,
IN ['A..'Z], '%, '$, '@, '\134 => ucAlpha,
'. => decimalPoint,
'? => templateDelimiter,
'[, '\005 => leftBracket,
'% => symbolDelimiter,
'+, '— , '-, '*, '/, '^, '←, '{, '(, '!, '$, '@, '&, '|, '~, '=, '>, '<, '#, '' => singleCharTemplate,
'\010 => backSpace,
ENDCASE => other
];
};
1/15/87 - Control characters typed by holding down the control key will be processed through the tip table, but hitting the backspace key should bring us through here
this pointless extra level of indirection proves that variants LOSE BIG TIME in Cedar
oh, what I'd give for CLU oneof's...
ParseKBChar: PUBLIC PROC[c: CHAR, inBuffer: KbBuffer, primaryActive, keyboardActive: BOOLFALSE] RETURNS [outBuffer: KbBuffer, action: ParseAction ← NIL] ~ {
modifies: kbBuffer, message window, $keyboard selection
effects: Parses c w.r.t contents of kbBuffer.
Updates kbBuffer, message window, and $keyboard selection (viewer & expr).
local declarations
lexC: LexType ← LexChar[c]; -- lexical type of character c
ropeC: Rope.ROPE ← Convert.RopeFromChar[c, FALSE]; -- rope equivalent of char c
kbBuffer: KbBuffer ← inBuffer;
SELECT lexC FROM
singleCharTemplate => {
wrapAround: ATOMIF primaryActive THEN $primary ELSE $keyboard;
SELECT c FROM
'+ => action ← NEW[WrapAction ← [wrap[wrapAround, $sum]]];
'— => action ← NEW[WrapAction ← [wrap[wrapAround, $negation]]];
'- => action ← NEW[WrapAction ← [wrap[wrapAround, $difference]]];
'* => action ← NEW[WrapAction ← [wrap[wrapAround, $product]]];
'/ => action ← NEW[WrapAction ← [wrap[wrapAround, $fraction]]];
'^ => action ← NEW[WrapAction ← [wrap[wrapAround, $pow]]];
'← => action ← NEW[WrapAction ← [wrap[wrapAround, $assign]]];
'' => action ← NEW[WrapAction ← [wrap[wrapAround, $quote]]];
'{ => action ← NEW[WrapAction ← [wrap[wrapAround, $curly]]];
'( => action ← NEW[WrapAction ← [wrap[wrapAround, $paren]]];
'[ => action ← NEW[WrapAction ← [wrap[wrapAround, $square]]];
'! => action ← NEW[WrapAction ← [wrap[wrapAround, $factorial]]];
'$ => action ← NEW[WrapAction ← [wrap[wrapAround, $exists]]];
'@ => action ← NEW[WrapAction ← [wrap[wrapAround, $forAll]]];
'& => action ← NEW[WrapAction ← [wrap[wrapAround, $and]]];
'| => action ← NEW[WrapAction ← [wrap[wrapAround, $or]]];
'~ => action ← NEW[WrapAction ← [wrap[wrapAround, $not]]];
'= => action ← NEW[WrapAction ← [wrap[wrapAround, $eqFormula]]];
'> => action ← NEW[WrapAction ← [wrap[wrapAround, $gtFormula]]];
'< => action ← NEW[WrapAction ← [wrap[wrapAround, $ltFormula]]];
'# => action ← NEW[WrapAction ← [wrap[wrapAround, $notEqFormula]]];
ENDCASE => ERROR; -- check consistency with defn of singleCharTemplate
kbBuffer ← [type: none, data: "", savedWrapArg: NIL]; -- reset kbBuffer
};
templateDelimiter => SELECT kbBuffer.type FROM
templateName => { -- finishing a multiChar templateName
name: Rope.ROPE ← kbBuffer.data;
class: ATOM ← Convert.AtomFromRope[ExpandAbbreviation[name]];
action ← NEW[FinishMultiCharTemplateAction ← [finishMultiCharTemplate[class]] ];
};
ENDCASE => { -- start multi-character templateName
wrapAround: ATOMIF primaryActive THEN $primary ELSE $keyboard;
action ← NEW[BeginMultiCharTemplateAction ← [beginMultiCharTemplate[wrapAround]] ];
};
backSpace => action ← NEW[UndoAction];
ENDCASE => SELECT keyboardActive FROM
FALSE => { -- newly active keyboard; should never be here with Templates
SELECT lexC FROM
digit => { -- replace $primary with keystroke digit
kbBuffer.type ← integer;
kbBuffer.data ← ropeC;
action ← NEW[ReplaceAction ← [replace[$primary, integer, kbBuffer.data, $keyboard]]];
};
lcAlpha, ucAlpha => { -- replace $primary with keystroke letter
kbBuffer.type ← variable;
kbBuffer.data ← ropeC;
action ← NEW[ReplaceAction ← [replace[$primary, variable, kbBuffer.data, $keyboard]]];
};
ENDCASE => action ← NEW[NoAction];
};
TRUE => { -- already active keyboard
SELECT kbBuffer.type FROM
integer => { -- extend the integer currently in KB buffer, or convert to real
SELECT lexC FROM
digit => {
kbBuffer.data ← kbBuffer.data.Cat[ropeC];
action ← NEW[ReplaceAction ←[replace[$keyboard, integer, kbBuffer.data, $keyboard]]];
};
decimalPoint => {
kbBuffer.type ← real;
kbBuffer.data ← kbBuffer.data.Cat[ropeC];
action ← NEW[ReplaceAction ← [replace[$keyboard, real, kbBuffer.data, $keyboard]]];
};
ENDCASE => action ← NEW[NoAction];
};
real => { -- extend the REAL currently in KB buffer
SELECT lexC FROM
digit => {
kbBuffer.data ← kbBuffer.data.Cat[ropeC];
action ← NEW[ReplaceAction ← [replace[$keyboard, real, kbBuffer.data, $keyboard]]];
};
ENDCASE => action ← NEW[NoAction];
};
variable => {
SELECT lexC FROM
ucAlpha, lcAlpha => { -- extend the var currently in KB buffer
kbBuffer.data ← kbBuffer.data.Cat[ropeC];
action ← NEW[ReplaceAction ← [replace[$keyboard, variable, kbBuffer.data, $keyboard]]];
};
leftBracket => { -- interpret the identifier currently in KB buffer as a (completed) templateName
name: Rope.ROPE ← ExpandAbbreviation[kbBuffer.data];
action ← NEW[ReplaceAction ← [replace[$keyboard, template, name, $primary]]];
kbBuffer ← [type: none, data: "", savedWrapArg: NIL]; -- reset kbBuffer
};
ENDCASE => action ← NEW[NoAction];
};
templateName => { -- extend the templateName currently in KB buffer
SELECT lexC FROM
ucAlpha, lcAlpha, digit => {
kbBuffer.data ← kbBuffer.data.Cat[ropeC];
action ← NEW[ReplaceAction ← [replace[$keyboard, templateName, kbBuffer.data, $keyboard]]];
};
ENDCASE => action ← NEW[NoAction];
};
ENDCASE => ERROR;
};
ENDCASE => ERROR;
RETURN[kbBuffer, action];
};
ExpandAbbreviation: PUBLIC PROC [name: ROPE] RETURNS [ROPE] ~ {
SELECT TRUE FROM -- check for recognized abbreviations
Rope.Equal[name, "nRad"] => RETURN["nRadical"];
Rope.Equal[name, "partialderiv"] => RETURN["partialDeriv"];
Rope.Equal[name, "indefint"] => RETURN["indefInt"];
Rope.Equal[name, "sigma"] => RETURN["summation"];
Rope.Equal[name, "Pow"] => RETURN["pow"];
Rope.Equal[name, "Mult"] => RETURN["product"];
Rope.Equal[name, "Div"] => RETURN["fraction"];
Rope.Equal[name, "Plus"] => RETURN["sum"];
Rope.Equal[name, "Minus"] => RETURN["negation"]; -- for SMP
Rope.Equal[name, "mult"] => RETURN["product"];
Rope.Equal[name, "div"] => RETURN["fraction"];
Rope.Equal[name, "plus"] => RETURN["sum"];
Rope.Equal[name, "minus"] => RETURN["negation"]; -- for SMP
Rope.Equal[name, "Difference"] => RETURN["difference"]; -- for SMP
ENDCASE;
RETURN[name];
};
END.