<> <> DIRECTORY AMTypes, Asserting, IO, OpPrecParse, OrderedSymbolTableRef, Rope, RoseTranslateTypes, RoseTranslateInsides, SignalTypeRegistration, TextNode, TiogaStreams; RoseTranslateReduce: CEDAR PROGRAM IMPORTS Asserting, IO, RoseTranslateTypes, RoseTranslateInsides, SignalTypeRegistration, OpPrecParse, OrderedSymbolTableRef EXPORTS RoseTranslateInsides = BEGIN OPEN RoseTranslateTypes, RoseTranslateInsides; squareClass, applClass, rsClass, colonClass, arrowDClass, arrowVClass, fmtClass, dashClass, assertClass, commaClass, dotdotClass, catClass, equivClass, semiClass, directoryClass, importsClass, exportsClass, openClass, libClass: PUBLIC TokenClass; ReduceSquare: PUBLIC OpPrecParse.Reducer = BEGIN IF ErrCheck[args] THEN RETURN [error]; IF OpsCheck[context, sr, ops, LIST[squareClass, rsClass]] THEN RETURN [error]; IF args.first.arg = omitted THEN reduced _ NEW [SquareBracketedRep _ [sr, NIL]] ELSE WITH args.first.arg SELECT FROM iel: InterfaceEltList => reduced _ NEW [SquareBracketedRep _ [sr, iel]]; ie: InterfaceElt => {iel: InterfaceEltList _ LIST[ie]; reduced _ NEW[SquareBracketedRep _ [sr, iel]]}; bl: BindingList => reduced _ NEW [SquareBracketedRep _ [sr, bl]]; b: Binding => {bl: BindingList _ LIST[b]; reduced _ NEW[SquareBracketedRep _ [sr, bl]]}; as: Args => { FOR al: ArgList _ as.args, al.rest WHILE al # NIL DO IF NOT ValidNodeExpression[al.first] THEN RETURN [Complain[sr, context, "Not a valid NodeExpression: %g", IO.refAny[al.first]]]; ENDLOOP; reduced _ NEW [SquareBracketedRep _ [sr, as]]; }; ENDCASE => reduced _ Complain[sr, context, "Surroundfix square brackets are used only to construct Interfaces, Parameter lists, or Node Arrays... applying them to %g is garbage", IO.refAny[args.first.arg]]; END; ReduceAppl: OpPrecParse.Reducer = BEGIN --making either signal type or cellFn invocation, cell instance, or subscription subject: REF ANY; subjectIsID: BOOL _ FALSE; subjectAsID: ID; asAny: REF ANY; job: Job _ NARROW[context]; parms: REF ANY; IF ErrCheck[args] THEN RETURN [error]; subject _ args.first.arg; WITH subject SELECT FROM id: ID => subjectIsID _ TRUE; a: Application => NULL; ENDCASE => RETURN [Complain[sr, context, "Must Apply %g to an Application or a simple ID, not %g", IO.refAny[args.rest.first.arg], IO.refAny[args.first.arg]]]; IF args.rest.first.arg = omitted THEN parms _ NEW [ArgsRep _ [sr, NIL]] ELSE WITH args.rest.first.arg SELECT FROM ri: Int => parms _ NEW [ArgsRep _ [sr, LIST[ri]]]; rr: Reel => parms _ NEW [ArgsRep _ [sr, LIST[rr]]]; dd: Dotdot => parms _ NEW [ArgsRep _ [sr, LIST[dd]]]; a: Application => parms _ NEW [ArgsRep _ [sr, LIST[a]]]; q: Quoted => parms _ NEW [ArgsRep _ [sr, LIST[q]]]; id: ID => parms _ NEW [ArgsRep _ [sr, LIST[id]]]; a: Args => parms _ a; b: Binding => {bl: BindingList _ LIST[b]; parms _ bl}; bl: BindingList => parms _ bl; ENDCASE => RETURN [Complain[sr, context, "Must apply to %g a BindingList or ArgList, not %g", IO.refAny[subject], IO.refAny[args.rest.first.arg]]]; IF subjectIsID THEN { subjectAsID _ NARROW[subject]; asAny _ SignalTypeRegistration.signalTypes.Lookup[subjectAsID.rope]; IF asAny # NIL THEN RETURN [InstantiateSignalType[context, subjectAsID.rope, parms]]; }; reduced _ NEW [ApplicationRep _ [sr, subject, parms]]; END; ReduceBinding: PUBLIC OpPrecParse.Reducer = BEGIN b: Binding _ NEW [BindingRep _ [sr]]; IF ErrCheck[args] THEN RETURN [error]; WITH args.first.arg SELECT FROM x: ID => b.name _ x.rope; ENDCASE => RETURN [Complain[sr, context, "Can't Bind %g", IO.refAny[args.first.arg]]]; WITH args.rest.first.arg SELECT FROM r: ID => NULL; x: SignalTypeInvocation => NULL; x: Application => NULL; x: CellFn => NULL; x: Int => NULL; x: Reel => NULL; x: Quoted => NULL; x: CedarExpression => NULL; ENDCASE => RETURN [Complain[sr, context, "Can't Bind %g to %g", IO.refAny[b.name], IO.refAny[args.rest.first.arg]]]; b.value _ args.rest.first.arg; reduced _ b; END; ReduceArrowD: PUBLIC OpPrecParse.Reducer = BEGIN b: Binding; IF ErrCheck[args] THEN RETURN [error]; WITH args.first.arg SELECT FROM x: Binding => b _ x; ENDCASE => RETURN [Complain[sr, context, "Can't Initialize something (%g) other than a Binding", IO.refAny[args.first.arg]]]; WITH args.rest.first.arg SELECT FROM fc: CedarExpression => b.initialData _ fc; ENDCASE => RETURN [Complain[sr, context, "Must initialize with a Cedar literal, not %g", IO.refAny[args.rest.first.arg]]]; b.sr _ sr; reduced _ b; END; ReduceArrowV: PUBLIC OpPrecParse.Reducer = BEGIN b: Binding; IF ErrCheck[args] THEN RETURN [error]; WITH args.first.arg SELECT FROM x: Binding => b _ x; ENDCASE => RETURN [Complain[sr, context, "Can't Initialize something (%g) other than a Binding", IO.refAny[args.first.arg]]]; WITH args.rest.first.arg SELECT FROM q: Quoted => b.initialValue _ CedarFromQuoted[q]; ce: CedarExpression => b.initialValue _ ce; f: Formatted => b.initialValue _ f; ENDCASE => RETURN [Complain[sr, context, "Can not initialize with %g", IO.refAny[args.rest.first.arg]]]; b.sr _ sr; reduced _ b; END; ReduceFmt: PUBLIC OpPrecParse.Reducer = BEGIN f: Formatted _ NEW [FormattedRep _ [sr: sr, value: NIL, format: NIL]]; IF ErrCheck[args] THEN RETURN [error]; WITH args.first.arg SELECT FROM q: Quoted => f.value _ CedarFromQuoted[q]; fc: CedarExpression => f.value _ fc; ENDCASE => RETURN [Complain[sr, context, "Can't format something (%g) other than a rope literal or cedar literal", IO.refAny[args.first.arg]]]; WITH args.rest.first.arg SELECT FROM q: Quoted => f.format _ q; ENDCASE => RETURN [Complain[sr, context, "Format must be a rope literal, not %g", IO.refAny[args.rest.first.arg]]]; reduced _ f; END; ReduceDash: PUBLIC OpPrecParse.Reducer = BEGIN assertion: Asserting.Assertion; IF ErrCheck[args] THEN RETURN [error]; WITH args.rest.first.arg SELECT FROM ral: RefAnyList => assertion _ Asserting.Cons[ral.l.first, ral.l.rest]; ENDCASE => RETURN [Complain[sr, context, "Must assert a list, not %g", IO.refAny[args.rest.first.arg]]]; WITH args.first.arg SELECT FROM ie: InterfaceElt => {ie.assertions _ CONS[assertion, ie.assertions]; ie.sr _ sr}; b: Binding => {b.assertions _ CONS[assertion, b.assertions]; b.sr _ sr}; ENDCASE => RETURN [Complain[sr, context, "Can't assert on something (%g) other than an Interface Element or Binding", IO.refAny[args.first.arg]]]; reduced _ args.first.arg; END; ReduceAssert: PUBLIC OpPrecParse.Reducer = BEGIN sofar: CellDef; IF ErrCheck[args] THEN RETURN [error]; IF (reduced _ sofar _ Sofar[sr, context, args.first.arg]) = NIL THEN RETURN [error]; WITH args.rest.first.arg SELECT FROM ral: RefAnyList => { FOR ll: LORA _ ral.l, ll.rest WHILE ll # NIL DO IF ll.first # NIL THEN WITH ll.first SELECT FROM l: LORA => {sofar.assertions _ CONS[Asserting.Cons[l.first, l.rest], sofar.assertions]; LOOP}; ENDCASE; Whimper[ral.sr, context, "Assertion list element must be an assertion, not %g", IO.refAny[ll.first]]; ENDLOOP; }; ENDCASE => RETURN [Complain[args.rest.first.sr, context, "Must assert a list of assertions, not %g", IO.refAny[args.rest.first.arg]]]; END; ReduceComma: PUBLIC OpPrecParse.Reducer = BEGIN rest: REF ANY; IF ErrCheck[args] THEN RETURN [error]; WITH args.rest.first.arg SELECT FROM b: Binding => {bl: BindingList _ LIST[b]; rest _ bl}; ie: InterfaceElt => {i: InterfaceEltList _ LIST[ie]; rest _ i}; id: ID => rest _ NEW[ArgsRep _ [sr, LIST[id]]]; q: Quoted => rest _ NEW[ArgsRep _ [sr, LIST[q]]]; ri: Int => rest _ NEW [ArgsRep _ [sr, LIST[ri]]]; rr: Reel => rest _ NEW [ArgsRep _ [sr, LIST[rr]]]; a: Application => rest _ NEW [ArgsRep _ [sr, LIST[a]]]; cat: Cat => rest _ NEW [ArgsRep _ [sr, LIST[cat]]]; sb: SquareBracketed => rest _ NEW [ArgsRep _ [sr, LIST[sb]]]; x: BindingList => rest _ x; x: InterfaceEltList => rest _ x; x: Args => rest _ x; ENDCASE => RETURN [Complain[sr, context, "Can't catenate %g to %g", IO.refAny[args.first.arg], IO.refAny[args.rest.first.arg]]]; WITH rest SELECT FROM bl: BindingList => WITH args.first.arg SELECT FROM b: Binding => {bl _ CONS[b, bl]; reduced _ bl}; id: ID => {bl _ CONS[NEW[BindingRep _ bl.first^], bl]; bl.first.sr _ sr; bl.first.name _ id.rope; reduced _ bl}; ENDCASE => reduced _ Complain[sr, context, "Cant prepend %g to BindingList %g", IO.refAny[args.first.arg], IO.refAny[args.rest.first.arg]]; i: InterfaceEltList => WITH args.first.arg SELECT FROM ie: InterfaceElt => {i _ CONS[ie, i]; reduced _ i}; id: ID => {i _ CONS[NEW[InterfaceEltRep _ i.first^], i]; i.first.sr _ sr; i.first.name _ id.rope; reduced _ i}; ENDCASE => reduced _ Complain[sr, context, "Can't prepend %g to Interface %g", IO.refAny[args.first.arg], IO.refAny[args.rest.first.arg]]; as: Args => { as.sr _ sr; WITH args.first.arg SELECT FROM id: ID => {as.args _ CONS[id, as.args]; reduced _ as}; q: Quoted => {as.args _ CONS[q, as.args]; reduced _ as}; ri: Int => {as.args _ CONS[ri, as.args]; reduced _ as}; rr: Reel => {as.args _ CONS[rr, as.args]; reduced _ as}; a: Application => {as.args _ CONS[a, as.args]; reduced _ as}; cat: Cat => {as.args _ CONS[cat, as.args]; reduced _ as}; sb: SquareBracketed => {as.args _ CONS[sb, as.args]; reduced _ as}; ENDCASE => reduced _ Complain[sr, context, "Can't prepend %g to Args %g", IO.refAny[args.first.arg], IO.refAny[args.rest]]; }; ENDCASE => ERROR; END; ReduceDotdot: PUBLIC OpPrecParse.Reducer = BEGIN first, last: INT; IF ErrCheck[args] THEN RETURN [error]; WITH args.first.arg SELECT FROM i: Int => first _ i.i; ENDCASE => RETURN [Complain[sr, context, "Can't make range %g .. %g", IO.refAny[args.first.arg], IO.refAny[args.rest.first.arg]]]; WITH args.rest.first.arg SELECT FROM i: Int => last _ i.i; ENDCASE => RETURN [Complain[sr, context, "Can't make range %g .. %g", IO.refAny[args.first.arg], IO.refAny[args.rest.first.arg]]]; reduced _ NEW [DotdotRep _ [sr, first, last]]; END; ReduceCat: PUBLIC OpPrecParse.Reducer = BEGIN head, tail: ArgList _ NIL; IF ErrCheck[args] THEN RETURN [error]; FOR al: OpPrecParse.ArgList _ args, al.rest WHILE al # NIL DO this: ArgList _ LIST[al.first.arg]; IF NOT ValidNodeExpression[al.first.arg] THEN RETURN [Complain[sr, context, "%g not a valid NodeExpression", IO.refAny[al.first.arg]]]; IF head = NIL THEN head _ this ELSE tail.rest _ this; tail _ this; ENDLOOP; reduced _ NEW [CatRep _ [sr, head]]; END; ValidNodeExpression: PROC [ra: REF ANY] RETURNS [valid: BOOL] = { valid _ TRUE; WITH ra SELECT FROM id: ID => NULL; a: Application => { WITH a.subject SELECT FROM id: ID => NULL; ENDCASE => valid _ FALSE; WITH a.args SELECT FROM as: Args => { IF as.args = NIL OR as.args.rest # NIL THEN valid _ FALSE ELSE WITH as.args.first SELECT FROM dd: Dotdot => NULL; i: Int => NULL; ENDCASE => valid _ FALSE; }; ENDCASE => valid _ FALSE; }; sb: SquareBracketed => { WITH sb.subject SELECT FROM as: Args => NULL --valid by construction--; ENDCASE => valid _ FALSE; }; cat: Cat => NULL --valid by construction--; ENDCASE => valid _ FALSE; }; ReduceEquiv: OpPrecParse.Reducer = BEGIN a, b: Arg _ NIL; ok: BOOL _ TRUE; IF ErrCheck[args] THEN RETURN [error]; WITH args.first.arg SELECT FROM as: Args => { ok _ as.args # NIL AND as.args.rest # NIL AND as.args.rest.rest = NIL AND ValidNodeExpression[a _ as.args.first] AND ValidNodeExpression[b _ as.args.rest.first]; }; ENDCASE => ok _ FALSE; IF NOT ok THEN RETURN [Complain[sr, context, "Must Equivalence a pair of NodeExpressions, not", IO.refAny[args.first.arg]]]; reduced _ NEW [EquivalenceRep _ [sr, a, b]]; END; ReduceSemi: OpPrecParse.Reducer = BEGIN firstRef, secondRef: BOOLEAN _ FALSE; a: LORA _ LIST[args.first.arg, args.rest.first.arg]; IF ErrCheck[args] THEN RETURN [error]; WITH args.first.arg SELECT FROM x: Binding => NULL; y: BindingList => NULL; cs: CedarChildren => NULL; cd: CellDef => NULL; wr: WasRef => {firstRef _ TRUE; a _ a.rest}; e: Equivalence => NULL; ENDCASE => RETURN [Complain[sr, context, "%g not a valid statement", IO.refAny[args.first.arg]]]; WITH args.rest.first.arg SELECT FROM stmts: Statements => { IF NOT firstRef THEN stmts.statements _ CONS[args.first.arg, stmts.statements]; secondRef _ stmts.hasRefs; stmts.hasRefs _ stmts.hasRefs OR firstRef; stmts.sr _ sr; reduced _ stmts}; x: Binding => reduced _ NEW [StatementsRep _ [sr, a]]; y: BindingList => reduced _ NEW [StatementsRep _ [sr, a]]; fc: CedarChildren => reduced _ NEW [StatementsRep _ [sr, a]]; cd: CellDef => reduced _ NEW [StatementsRep _ [sr, a]]; wr: WasRef => reduced _ NEW [StatementsRep _ [ sr: sr, statements: (IF firstRef THEN NIL ELSE LIST[args.first.arg]), hasRefs: secondRef _ TRUE]]; e: Equivalence => reduced _ NEW [StatementsRep _ [sr, a]]; ENDCASE => RETURN [Complain[sr, context, "%g not a valid statement", IO.refAny[args.rest.first.arg]]]; IF secondRef AND NOT firstRef THEN Whimper[sr, context, "Should have module reference statements before others"]; END; ReduceDirectory: OpPrecParse.Reducer = BEGIN job: Job _ NARROW[context]; reduced _ wasRef; WITH args.first.arg SELECT FROM a: Args => FOR l: ArgList _ a.args, l.rest WHILE l # NIL DO WITH l.first SELECT FROM id: ID => AddDirectory[job, id.rope]; ENDCASE => RETURN [Complain[sr, context, "DIRECTORY only takes IDs, not %g", IO.refAny[l.first]]]; ENDLOOP; id: ID => AddDirectory[job, id.rope]; ENDCASE => reduced _ Complain[sr, context, "DIRECTORY must be given an ID or IDList, not %g", IO.refAny[args.first.arg]]; END; ReduceImports: OpPrecParse.Reducer = BEGIN job: Job _ NARROW[context]; reduced _ wasRef; WITH args.first.arg SELECT FROM a: Args => FOR l: ArgList _ a.args, l.rest WHILE l # NIL DO WITH l.first SELECT FROM id: ID => AddImport[job, id.rope]; ENDCASE => RETURN [Complain[sr, context, "IMPORTS only takes IDs, not %g", IO.refAny[l.first]]]; ENDLOOP; id: ID => AddImport[job, id.rope]; ENDCASE => reduced _ Complain[sr, context, "IMPORTS must be given an ID or IDList, not %g", IO.refAny[args.first.arg]]; END; ReduceExports: OpPrecParse.Reducer = BEGIN job: Job _ NARROW[context]; reduced _ wasRef; WITH args.first.arg SELECT FROM a: Args => FOR l: ArgList _ a.args, l.rest WHILE l # NIL DO WITH l.first SELECT FROM id: ID => AddExport[job, id.rope]; ENDCASE => RETURN [Complain[sr, context, "EXPORTS only takes IDs, not %g", IO.refAny[l.first]]]; ENDLOOP; id: ID => AddExport[job, id.rope]; ENDCASE => reduced _ Complain[sr, context, "EXPORTS must be given an ID or IDList, not %g", IO.refAny[args.first.arg]]; END; ReduceOpen: OpPrecParse.Reducer = BEGIN job: Job _ NARROW[context]; reduced _ wasRef; WITH args.first.arg SELECT FROM a: Args => FOR l: ArgList _ a.args, l.rest WHILE l # NIL DO WITH l.first SELECT FROM id: ID => AddOpen[job, id.rope]; ENDCASE => RETURN [Complain[sr, context, "OPEN only takes IDs, not %g", IO.refAny[l.first]]]; ENDLOOP; id: ID => AddOpen[job, id.rope]; ENDCASE => reduced _ Complain[sr, context, "OPEN must be given an ID or IDList, not %g", IO.refAny[args.first.arg]]; END; ReduceLibrary: OpPrecParse.Reducer = BEGIN job: Job _ NARROW[context]; reduced _ wasRef; WITH args.first.arg SELECT FROM a: Args => FOR l: ArgList _ a.args, l.rest WHILE l # NIL DO WITH l.first SELECT FROM id: ID => AddSymbols[job, id.rope]; ENDCASE => RETURN [Complain[sr, context, "LIBRARY only takes IDs, not %g", IO.refAny[l.first]]]; ENDLOOP; id: ID => AddSymbols[job, id.rope]; ENDCASE => reduced _ Complain[sr, context, "LIBRARY must be given an ID or IDList, not %g", IO.refAny[args.first.arg]]; END; Start: PROC = BEGIN argClass: OpPrecParse.TokenClass = OpPrecParse.argClass; squareClass _ NEW[TokenClassRep _ [000, 200, ReduceSquare]]; applClass _ NEW[TokenClassRep _ [1000, 200, ReduceAppl]]; rsClass _ NEW[TokenClassRep _ [200, 000, NIL, [nullSR, argClass, omitted]]]; colonClass _ NEW[TokenClassRep _ [410, 400, ReduceBinding]]; arrowDClass _ NEW[TokenClassRep _ [350, 360, ReduceArrowD]]; arrowVClass _ NEW[TokenClassRep _ [350, 360, ReduceArrowV]]; fmtClass _ NEW[TokenClassRep _ [410, 400, ReduceFmt]]; dashClass _ NEW[TokenClassRep _ [350, 360, ReduceDash]]; assertClass _ NEW[TokenClassRep _ [080, 090, ReduceAssert]]; commaClass _ NEW[TokenClassRep _ [310, 300, ReduceComma, [nullSR, argClass, omitted]]]; dotdotClass _ NEW[TokenClassRep _ [910, 900, ReduceDotdot]]; catClass _ NEW[TokenClassRep _ [450, 450, ReduceCat]]; equivClass _ NEW[TokenClassRep _ [000, 250, ReduceEquiv]]; semiClass _ NEW[TokenClassRep _ [110, 100, ReduceSemi]]; directoryClass _ NEW[TokenClassRep _ [000, 275, ReduceDirectory]]; importsClass _ NEW[TokenClassRep _ [000, 275, ReduceImports]]; exportsClass _ NEW[TokenClassRep _ [000, 275, ReduceExports]]; openClass _ NEW[TokenClassRep _ [000, 275, ReduceOpen]]; libClass _ NEW[TokenClassRep _ [000, 275, ReduceLibrary]]; ops.Insert[NEW[OpRep _ ["[", [applClass, squareClass]]]]; ops.Insert[NEW[OpRep _ ["]", [rsClass, rsClass]]]]; ops.Insert[NEW[OpRep _ [":", [colonClass, NIL]]]]; ops.Insert[NEW[OpRep _ ["_d", [arrowDClass, NIL]]]]; ops.Insert[NEW[OpRep _ ["_v", [arrowVClass, NIL]]]]; ops.Insert[NEW[OpRep _ ["fmt", [fmtClass, NIL]]]]; ops.Insert[NEW[OpRep _ ["-", [dashClass, NIL]]]]; ops.Insert[NEW[OpRep _ ["Assert", [assertClass, NIL]]]]; ops.Insert[NEW[OpRep _ [",", [commaClass, commaClass]]]]; ops.Insert[NEW[OpRep _ ["..", [dotdotClass, NIL]]]]; ops.Insert[NEW[OpRep _ ["cat", [catClass, NIL]]]]; ops.Insert[NEW[OpRep _ ["Equivalence", [NIL, equivClass]]]]; ops.Insert[NEW[OpRep _ [";", [semiClass, NIL]]]]; ops.Insert[NEW[OpRep _ ["Directory", [NIL, directoryClass]]]]; ops.Insert[NEW[OpRep _ ["Imports", [NIL, importsClass]]]]; ops.Insert[NEW[OpRep _ ["Exports", [NIL, exportsClass]]]]; ops.Insert[NEW[OpRep _ ["Open", [NIL, openClass]]]]; ops.Insert[NEW[OpRep _ ["Library", [NIL, libClass]]]]; END; Start[]; END.