-- MobConnectionMXCode.mesa DIRECTORY Atom, MobConnection, Rope, Scheme; MobConnectionMXCode: CEDAR PROGRAM IMPORTS Atom, MobConnection, Scheme = BEGIN OPEN Scheme; SymbolFromRope: PROC [rope: Rope.ROPE] RETURNS [Symbol] ~ {RETURN[Atom.MakeAtom[rope]]}; RopeFromSymbol: PROC [Symbol] RETURNS [Rope.ROPE] ~ Atom.GetPName; TheSymbol: PROC [a: Any] RETURNS [Scheme.Symbol] = { WITH a SELECT FROM a: Scheme.Symbol => RETURN [a]; ENDCASE => Complain[a, "not a Scheme.Symbol"]; }; SymbolForFilterItem: REF ARRAY MobConnection.FilterItem OF Symbol = InitSymbolForFilterItem[]; InitSymbolForFilterItem: PROC RETURNS [a: REF ARRAY MobConnection.FilterItem OF Symbol] = { a ← NEW[ARRAY MobConnection.FilterItem OF Symbol]; a[versions] ← $versions; a[directory] ← $directory; a[using] ← $using; a[imports] ← $imports; a[importedItems] ← Atom.MakeAtom["imported-items"]; a[exports] ← $exports; a[typeExports] ← Atom.MakeAtom["type-exports"]; a[exportedItems] ← Atom.MakeAtom["exported-items"]; a[modules] ← $modules; a[configurations] ← $configurations; }; TheFilterItem: PROC [a: Any] RETURNS [MobConnection.FilterItem] = { FOR k: MobConnection.FilterItem IN MobConnection.FilterItem DO IF a=SymbolForFilterItem[k] THEN RETURN [k]; ENDLOOP; ERROR Complain[a, "is not a MobConnection.FilterItem"]; }; MobConnectionPrim: PROC [SELF: Primitive, ARG1,ARG2,ARG3: Any, REST: ProperList] RETURNS [result: Any ← unspecified] = { INNER: PROC = { POP: PROC RETURNS [a: Any ← undefined] = { IF REST#NIL THEN {a ← REST.car; REST ← NARROW[REST.cdr]}}; DATA: Pair ~ NARROW[SELF.data]; env: Environment ~ NARROW[DATA.cdr]; SELECT NAT[NARROW[DATA.car, REF INT]↑] FROM 0 => { filename: Any ← ARG1; filter: Any ← ARG2; stack: LIST OF Appender ← NIL; Begin: PROC [id: Symbol] = { head: Pair = Cons[id, NIL]; stack ← CONS[[head, head], stack]; }; End: PROC = { a: Any ← stack.first.head; stack ← stack.rest; IF stack = NIL THEN result ← a ELSE Put[a]; }; Put: PROC [a: Any] = { stack.first.last ← stack.first.last.cdr ← Cons[a, NIL] }; PutATOM: PROC [a: Symbol] = {Put[a]}; PutROPE: PROC [a: Rope.ROPE] = {Put[StringFromRope[a]]}; PutINT: PROC [a: INT] = {Put[MakeFixnum[a]]}; PutBOOL: PROC [a: BOOL] = {Put[IF a THEN true ELSE false]}; PutModuleID: PROC [a: MobConnection.ModuleID] = { Begin[$id]; PutATOM[a.identifier]; PutATOM[a.version]; End[] }; f: MobConnection.Filter ← ALL[FALSE]; IF filter = undefined THEN f ← ALL[TRUE] ELSE { FOR tail: Any ← filter, Cdr[tail] UNTIL tail = NIL DO f[TheFilterItem[Car[tail]]] ← TRUE; ENDLOOP; }; MobConnection.DecodeMob[fileName: RopeFromString[TheString[filename]], begin: Begin, end: End, putATOM: PutATOM, putROPE: PutROPE, putINT: PutINT, putBOOL: PutBOOL, putModuleID: PutModuleID, filter: f]; IF stack # NIL THEN ERROR; }; ENDCASE => ERROR }; INNER[! MobConnection.Error => Complain[culprit, msg]; ]; }; MobConnectionInit: PROC [env: Environment] = { DefinePrimitive[name: "decode-mob", nArgs: 2, proc: MobConnectionPrim, doc: "(filename [ filter ]) Extract useful information from a mob file", env: env, optional: 1, dotted: FALSE, data: Cons[MakeFixnum[0], env]]; }; Appender: TYPE = RECORD [head, last: Pair]; RegisterInit[MobConnectionInit]; END.