JunoParseSyntaxImpl.mesa (was OldJunoParserEtcImpl.mesa)
Coded December 7, 1982 4:18 pm
Last Edited by: Gnelson, January 19, 1984 1:35 pm
Last Edited by: Stolfi June 13, 1984 3:42:31 am PDT

DIRECTORY

Rope USING [ROPE],
JunoParseUnparse USING [],
JunoExpression,
Atom;

JunoParseSyntaxImpl: PROGRAM

IMPORTS

JunoParseUnparse,
JunoExpression

EXPORTS

JunoParseSyntax =

BEGIN

OPEN

Rope,
JunoExpression,
Parse: JunoParseUnparse;

- - - - THE JUNO PARSING TABLE

junoParseTable: PUBLIC Parse.Table ← Parse.NewTable[];

- - - - PROCEDURES FOR TABLE INITIALIZATION

SetCharTypes: PROC [op: ATOM] =

BEGIN OPEN junoSyntaxTable;

name: ROPE = Atom.GetPName[op];
c1, c2: CHAR;
IF name.Length # 2 THEN RETURN;
c1 ← name.Fetch[0];
c1 ← name.Fetch[1];
IF chType[c1] = letter AND (chType[c2] = letter OR chType[c2] = digit) THEN RETURN;
IF chType[c1] # op OR chType[c2] # op THEN ERROR;
Parse.EnterTwoCharOp[junoSyntaxTable, c1, c2]

END;

OperatorType: TYPE = {infix, subMatchfix, matchfix, prefix, inPrefix, closefix};

AddOp: PROC
[op: ATOM, alias: ATOM,
bp: Parse.BindingPower, type: OperatorType, closer: ATOM, u: UnparseType ← zero] =

BEGIN

p: Parse.Props;
IF alias # NIL THEN Parse.EnterAlias[table: junoParseTable, alias: alias, standard: op];
p.bindingPower ← bp;
p.closer ← closer;
p.unparseType ← u;
SELECT f FROM
infix => p.infix ← TRUE;
subMatchfix => p.subfix ← p.matchfix ← TRUE;
matchfix => p.matchfix ← TRUE;
prefix => p.prefix ← TRUE;
infPrefix => p.infix ← p.prefix ← TRUE;
closefix => p.closefix ← TRUE
ENDCASE => ERROR;
EnterAtomProps[table: junoParseTable, atom: op, props: p];
IF alias # NIL THEN SetCharTypes[alias];
SetCharTypes[op]

END;

- - - - TABLE INITIALIZATION
rightPren: ATOM.MakeAtom[")"];

AddOp[$fi, NIL, 0, closefix, NIL];
AddOp[$od, NIL, 0, closefix, NIL];
AddOp[rightPren, NIL, 0, closefix, NIL];

AddOp[obox, $elseif, 1, infix, NIL, infixB];
AddOp[lambda, $mapsto, 1, infix, NIL, infixB];
AddOp[rightArrow, $then, 2, infix, NIL, infixB];
AddOp[assign, $gets, 4, infix, NIL, infixB];
AddOp[leftPren, NIL, 5, subfixMatchfix, rightPren, matchB];
AddOp[comma, NIL, 5, infix, NIL, infixD];
AddOp[hor, NIL, 5, prefix, NIL, prefix];
AddOp[ver, NIL, 5, prefix, NIL, prefix];
AddOp[ccw, NIL, 5, prefix, NIL, prefix];
AddOp[cong, NIL, 5, infix, NIL, infixB];
AddOp[para, NIL, 5, infix, NIL, infixB];
AddOp[perp, NIL, 5, infix, NIL, infixB];
AddOp[at, NIL, 5, infix, NIL, infixB];
AddOp[draw, NIL, 4, prefix, NIL, prefix];
AddOp[stroke, NIL, 4, prefix, NIL, prefix];
AddOp[fill, NIL, 4, prefix, NIL, prefix];
AddOp[paint, NIL, 3, infix, NIL, infixE];
AddOp[ends, NIL, 3, infix, NIL, infixE];
AddOp[width, NIL, 3, infix, NIL, infixE];
AddOp[face, NIL, 3, infix, NIL, infixE];
AddOp[font, NIL, 3, infix, NIL, infixE];
AddOp[justified, NIL, 3, infix, NIL, infixE];
AddOp[suchThat, $st, 3, infix, NIL, infixB];
AddOp[semicolon, NIL, 3, infix, NIL, infixD];
AddOp[colon, NIL, 2, infix, NIL, infixD];
AddOp[plus, NIL, 7, infix, NIL, infixB];
AddOp[times, NIL, 8, infix, NIL, infixB];
AddOp[div, NIL, 8, infix, NIL, infixB];
AddOp[and, NIL, 4, infix, NIL, infixB];
AddOp[dist, NIL, 4, infix, NIL, infixB];
AddOp[cons, NIL, 4, infix, NIL, infixB];

AddOp[if, NIL, 0, matchfix, $fi, matchA];
AddOp[do, NIL, 0, matchfix, $od, matchA];

AddOp[rel, NIL, 6, infix, NIL, infixB];

AddOp[approx, NIL, 12, infix, NIL, infixB];

AddOp[minus, NIL, 15, prefix, NIL, prefix];
AddOp[dec, NIL, 15, prefix, NIL, prefix];
AddOp[inc, NIL, 15, prefix, NIL, prefix];
AddOp[floor, NIL, 15, prefix, NIL, prefix];
AddOp[xcoord, NIL, 15, prefix, NIL, prefix];
AddOp[ycoord, NIL, 15, prefix, NIL, prefix];
AddOp[first, NIL, 15, prefix, NIL, prefix];
AddOp[rest, NIL, 15, prefix, NIL, prefix];


END.

- - - - JUNK

junoA: PUBLIC PW.Handle;

Parse: PUBLIC PROC = {PW.ParseViewer[junoA]};

Se: TYPE = REF ANY; -- Se = "symbolic expression"

Sp: TYPE = PW.SyntacticPredicate;

leftPren: ATOM = Atom.MakeAtom["("];
colon: ATOM = Atom.MakeAtom[":"];
semicolon: ATOM = Atom.MakeAtom[";"];
comma: ATOM = Atom.MakeAtom[","];
assign: ATOM = Atom.MakeAtom[":="];
approx: ATOM = Atom.MakeAtom["=="];
minus: ATOM = Atom.MakeAtom["-"];
rightarrow: ATOM = Atom.MakeAtom["->"];
suchthat: ATOM = Atom.MakeAtom["|"];

Definition: Sp = {RETURN [PW.HasForm[f, colon, Application, Command]]};

Application: Sp = {RETURN [PW.HasForm[f, leftPren, Var, VarList]]};

VarList: Sp = {RETURN [PW.Or[Var[f], PW.HasForm[f, comma, Var, VarList]]]};

Var: Sp = {IF ISTYPE[NARROW[Car[NARROW[f]], REF ANY], ATOM]
THEN RETURN [[Yes, NIL]]
ELSE RETURN [[OfCourseNot, f]]};

Command: Sp = {RETURN [PW.Or[AtomicCommand[f],
PW.Or[Alternation[f],
PW.Or[Iteration[f],
PW.Or[PushState[f],
Composition[f]]]]]]};

AtomicCommand: Sp = {RETURN [PW.Or[Draw[f], PW.Or[Print[f], PW.Or[Call[f], Assignment[f]]]]]};

Draw: Sp = {RETURN [PW.Or[PW.HasForm[f, $stroke, DrawList, NIL],
      PW.Or[PW.HasForm[f, $fill, DrawList, NIL],
      PW.HasForm[f, $draw, DrawList, NIL]]]]};

DrawList: Sp = {RETURN [PW.Or[DrawListElem[f], PW.HasForm[f, comma, DrawListElem, DrawList]]]};

DrawListElem: Sp = {RETURN [PW.HasForm[f, leftPren, DLE2, NIL]]};

DLE2: Sp = {RETURN [PW.Or[TwoVars[f], PW.HasForm[f, comma, Var, ThreeVars]]]};

ThreeVars: Sp = {RETURN [PW.HasForm[f, comma, Var, TwoVars]]};

TwoVars: Sp = {RETURN[PW.HasForm[f, comma, Var, Var]]};

Print: Sp = {RETURN [PW.HasForm[f, leftPren, PrintAtom, PrintList]]};

PrintAtom: Sp = {IF Car[f] = $print
THEN RETURN [[Yes, NIL]]
ELSE RETURN [[OfCourseNot, f]]};

PrintList: Sp = {RETURN [PW.HasForm[f, comma, RopeLiteral, PL2]]};

PL2: Sp = {RETURN [PW.HasForm[f, comma, Var, PL3]]};

PL3: Sp = {RETURN [PW.HasForm[f, comma, Var, PL4]]};

PL4: Sp = {RETURN [PW.HasForm[f, comma, IntLiteral, IntLiteral]]};

RopeLiteral: Sp = {IF ISTYPE[NARROW[Car[f], REF ANY], Rope.ROPE]
   THEN RETURN [[Yes, NIL]]
   ELSE RETURN [[OfCourseNot, f]]};

IntLiteral: Sp = {IF ISTYPE[NARROW[Car[f], REF ANY], REF INT]
   THEN RETURN [[Yes, NIL]]
   ELSE RETURN [[OfCourseNot, f]]};

Call: Sp = {RETURN [PW.HasForm[f, leftPren, Var, VarList]]};

Assignment: Sp = {aw: PW.VerdictAndCulprit ← PW.HasForm[f, assign, VarList, VarList];
      IF aw.verdict = Yes AND
      InfixLength[Cadr[NARROW[Car[NARROW[f]]]]]
      # InfixLength[Caddr[NARROW[Car[NARROW[f]]]]]
      THEN RETURN [[No, f]]
      ELSE RETURN [aw]};

Alternation: Sp = {RETURN[PW.HasForm[f, $if, Gcl, NIL]]};

Iteration: Sp = {RETURN[PW.HasForm[f, $do, Gcl, NIL]]};

PushState: Sp = {RETURN[PW.Or[PW.HasForm[f, $width, TwoVars, Command],
        PW.Or[PW.HasForm[f, $width, Num, Command],
        PW.Or[PW.HasForm[f, $paint, Var, Command],
          PW.HasForm[f, $ends, Var, Command]]]]]};

Gcl: Sp = GuardedCommand;

GuardedCommand: Sp = {RETURN[PW.HasForm[f, rightarrow, Predicate, Command]]};

Predicate: Sp = {RETURN[PW.HasForm[f, suchthat, LocalList, CList]]};

LocalList: Sp = {RETURN[PW.Or[Local[f], PW.HasForm[f, comma, Local, LocalList]]]};

Local: Sp = {RETURN[PW.Or[Var[f], PW.HasForm[f, approx, Var, Rel]]]};

Rel: Sp = {RETURN [PW.HasForm[f, $rel, NumPair, Rellist]]};

NumPair: Sp = {RETURN [PW.HasForm[f, leftPren, NumPair2, NIL]]};

NumPair2: Sp = {RETURN [PW.HasForm[f, comma, Num, Num]]};

Num: Sp = {RETURN [PW.Or[Num2[f], PW.HasForm[f, minus, Num2, NIL]]]};

Num2: Sp = {IF ISTYPE[Car[f], REF INT] OR ISTYPE[Car[f], REF REAL]
THEN RETURN [[Yes, NIL]]
ELSE RETURN [[OfCourseNot, f]]};

Rellist: Sp = {RETURN[PW.HasForm[f, leftPren, Rellist2, NIL]]};

Rellist2: Sp = {RETURN[PW.Or[Var[f], PW.Or[TwoVars[f], ThreeVars[f]]]]};

CList: Sp = {RETURN[PW.Or[Constraint[f], PW.HasForm[f, $and, Constraint, CList]]]};

Constraint: Sp = {RETURN[PW.Or[T[f], PW.Or[Cong[f], PW.Or[Para[f], PW.Or[Hor[f], Ver[f]]]]]]};

T: Sp = {IF Car[NARROW[f]] = $T
THEN RETURN [[Yes, NIL]]
ELSE RETURN [[OfCourseNot, f]]};

Cong: Sp = {RETURN[PW.HasForm[f, $cong, PrenTwoVars, PrenTwoVars]]};

Para: Sp = {RETURN[PW.HasForm[f, $para, PrenTwoVars, PrenTwoVars]]};

Hor: Sp = {RETURN[PW.HasForm[f, $hor, PrenTwoVars, NIL]]};

Ver: Sp = {RETURN[PW.HasForm[f, $ver, PrenTwoVars, NIL]]};

PrenThreeVars: Sp = {RETURN[PW.HasForm[f, leftPren, ThreeVars, NIL]]};

PrenTwoVars: Sp = {RETURN[PW.HasForm[f, leftPren, TwoVars, NIL]]};

Composition: Sp = {RETURN[PW.HasForm[f, semicolon, Command, Command]]};

InfixLength: PROC[l: Se] RETURNS [INT] =
{IF ISTYPE[NARROW[l, REF ANY], ATOM]
THEN RETURN[1]
ELSE RETURN[1 + InfixLength[Caddr[NARROW[l]]]]};

WellFormed: PUBLIC PROC [f: Se] RETURNS [PW.VerdictAndCulprit] =
{RETURN[Definition[f]]};

Car: PROC [r: Se] RETURNS [Se] = {RETURN[NARROW[r, LIST OF REF ANY].first]};

Cdr: PROC [r: Se] RETURNS [Se] = {RETURN[NARROW[r, LIST OF REF ANY].rest]};

Cadr: PROC [r: Se] RETURNS [Se] = {RETURN[Car[Cdr[r]]]};

Caddr: PROC [r: Se] RETURNS [Se] = {RETURN[Car[Cdr[Cdr[r]]]]};

Cddr: PROC [r: Se] RETURNS [Se] = {RETURN[Cdr[Cdr[r]]]};

Caar: PROC [r: Se] RETURNS [Se] = {RETURN[Car[Car[r]]]};

Cadar: PROC [l: Se] RETURNS [Se] =
{ RETURN[ Car[ Cdr[ Car[ l ] ] ] ] };

Caddar: PROC [l: Se] RETURNS [Se] =
{ RETURN[ Car[ Cdr[ Cdr[ Car[ l ] ] ] ] ] };

Cadddar: PROC [l: Se] RETURNS [Se] =
{ RETURN[ Car[ Cdr[ Cdr[ Cdr[ Car[ l ] ] ] ] ] ] };

Cadddr: PROC [l: Se] RETURNS [Se] =
{ RETURN[ Car[ Cdr[ Cdr[ Cdr[ l ] ] ] ] ] };

Caddddar: PROC [l: Se] RETURNS [Se] =
{ RETURN[ Car[ Cdr[ Cdr[ Cdr[ Cdr[ Car[ l ] ] ] ] ] ] ] };

Cddar: PROC [l: Se] RETURNS [Se] =
{ RETURN[ Cdr[ Cdr[ Car[ l ] ] ] ] };