<> DIRECTORY AMBridge USING [GetWorld, IsRemote, OctalRead, RefFromTV, SomeRefFromTV, TVForReferent, TVToCardinal, TVToLC], AMTypes USING [IndexToTV, NameToIndex, IsNil, IsRope, Referent, TVToName, TVType], Atom USING [TypePutProp, MakeAtom, PropList], BasicUserExec USING [CorrectionProc, Interface], BBInterp USING [Tree], ConvertUnsafe USING [AppendRope], Heap USING [systemMDSZone], IO USING [atom, AttachRefPrintProc, AttachTVPrintProc, card, char, CR, Flush, LookupData, NewLine, Put, PutChar, PutF, PutRope, RefPrintProc, ROPE, rope, SP, STREAM, string, time, tv, TVPrintProc, type], PilotSwitches USING [switches], PrintTV USING [PutProc, PutClosure], PPUtil USING [PrettyPrint], PPTree USING [Handle], PPLeaves USING [HTIndex, LTIndex], Rope USING [Flatten, IsEmpty, Length, ROPE, Text, ToRefText], RTBasic USING [TV, Type], RTTypesPrivate USING [TypedVariableRec], RTTypesRemotePrivate USING [RemoteTypeToLocal], System USING [GreenwichMeanTime, gmtEpoch], UnsafeStorage USING [GetSystemUZone], UserExec USING [GetStreams, HistoryList, ExecHandle], UserExecExtras USING [], ViewerClasses USING [Viewer] ; BasicUserExecImpl: CEDAR MONITOR IMPORTS AMBridge, AMTypes, Atom, ConvertUnsafe, Heap, IO, PilotSwitches, PPUtil, Rope, RTTypesRemotePrivate, UnsafeStorage, UserExec EXPORTS BasicUserExec, UserExecExtras SHARES Atom, IO <> <> = BEGIN OPEN IO, BasicUserExec; TV: TYPE = RTBasic.TV; Type: TYPE = RTBasic.Type; <> StringPrintProc: TVPrintProc = TRUSTED {-- AMBridge -- IF AMBridge.IsRemote[tv] THEN TVStringPut[tv, stream, width * depth + 16]; -- the algorithm used for printing ropes in PrintTVImpl <> <> <> <<};>> }; -- of StringPrintProc LongStringPrintProc: TVPrintProc = TRUSTED {-- AMBridge IF AMBridge.IsRemote[tv] THEN TVStringPut[tv, stream, width * depth + 16] -- the algorithm used for printing ropes in PrintTVImpl ELSE { s: LONG STRING _ LOOPHOLE[AMBridge.TVToLC[tv], LONG STRING]; stream.Put[char['"], string[s], char['"]]; }; }; -- of LongStringPrintProc TVStringPut: PROC [strTV: TV, out: STREAM, limit: CARDINAL] = { IF AMTypes.IsNil[strTV] THEN out.PutRope["NIL"] ELSE TVTextPut[AMTypes.Referent[strTV], out, limit]; -- strTV is a pointer to TEXT. must use the referent to describe actual storage }; TVTextPut: PROC [tv: TV, out: STREAM, limit: CARDINAL] = TRUSTED { len: CARDINAL _ AMBridge.OctalRead[tv, 0]; -- the length of the string max: CARDINAL _ AMBridge.OctalRead[tv, 1]; -- the maxLength of the string limit _ MIN[len, limit]; out.PutChar['"]; FOR i: CARDINAL IN [0..limit) DO wordIndex: CARDINAL _ i/2+2; word: PACKED ARRAY [0..1] OF CHAR _ LOOPHOLE[AMBridge.OctalRead[tv, wordIndex]]; out.PutChar[word[i MOD 2]]; -- should do more to output funny characters ENDLOOP; IF limit < len THEN out.PutRope["..."]; out.PutChar['"]; }; RefTextPrintProc: TVPrintProc = TRUSTED { TVTextPut[AMTypes.Referent[tv], stream, width * depth + 16]; -- the algorithm used for printing ropes in PrintTVImpl }; <> <> <<};>> TextPrintProc: TVPrintProc = { TVTextPut[tv, stream, width * depth + 16]; -- the algorithm used for printing ropes in PrintTVImpl }; <> NatPrintProc: TVPrintProc = TRUSTED { -- AMBridge stream.Put[card[AMBridge.TVToLC[tv]]]; }; TypePrintProc: TVPrintProc = TRUSTED { -- AMBridge t: RTBasic.Type; IF AMBridge.IsRemote[tv] THEN t _ RTTypesRemotePrivate.RemoteTypeToLocal[world: AMBridge.GetWorld[tv], remoteType: LOOPHOLE[AMBridge.TVToCardinal[tv]]] ELSE t _ LOOPHOLE[AMBridge.TVToCardinal[tv]]; stream.Put[type[t]]; }; TimePrintProc: TVPrintProc = TRUSTED { -- AMBridge t: System.GreenwichMeanTime; IF AMBridge.IsRemote[tv] THEN ERROR; -- shouldnt be called. TVPrintProc says can't handle remote. t _ LOOPHOLE[AMBridge.TVToLC[tv]]; IF t = System.gmtEpoch THEN stream.PutRope["{current time}"] ELSE stream.Put[time[t]]; }; tvPrintProc: RefPrintProc = TRUSTED { stream.PutF["{tv for: %g}", tv[LOOPHOLE[ref]]]; }; <> InterfacePrintProc: RefPrintProc = { r: BasicUserExec.Interface = NARROW[ref]; stream.PutF["{Interface: %g}", rope[r^]]; }; TreePrintProc: RefPrintProc = TRUSTED { stream.PutRope["{tree for: "]; PPUtil.PrettyPrint[ root: LOOPHOLE[ref, BBInterp.Tree], put: PrintTV.PutClosure[proc: TreePrintPutProc, data: NEW[TreePrintRecord _ [stream]]] ]; stream.PutChar['}]; }; TreePrintRecord: TYPE = RECORD[stream: IO.STREAM, skipSpaces: BOOLEAN _ FALSE]; TreePrintPutProc: PrintTV.PutProc -- [data: REF, c: CHAR] -- = { r: REF TreePrintRecord = NARROW[data]; SELECT c FROM -- skips CR and any leading spaces following it. i.e. flattens out the prettyprinting. CR => {r.skipSpaces _ TRUE; r.stream.PutChar[SP]}; SP => IF ~r.skipSpaces THEN r.stream.PutChar[c]; ENDCASE => {r.stream.PutChar[c]; r.skipSpaces _ FALSE}; }; STREAMPrintProc: TVPrintProc = TRUSTED { IF AMBridge.IsRemote[tv] THEN { -- differences: does not look up name on property list of stream, prints streamprocs.name with "'s around it. RemoteSTREAMPrintProc[tv, stream]; } ELSE { h: IO.STREAM = NARROW[AMBridge.RefFromTV[AMTypes.Referent[tv]]]; name: Rope.ROPE = NARROW[IO.LookupData[self: h, key: $Name]]; stream.PutF["{%bB - %g Stream", card[LOOPHOLE[h, LONG CARDINAL]], rope[h.streamProcs.name]]; IF NOT Rope.IsEmpty[name] THEN stream.PutF[" on %g", rope[name]]; stream.PutChar['}]; }; }; RemoteSTREAMPrintProc: PROC[tv: RTBasic.TV, stream: IO.STREAM] = TRUSTED { address: LONG CARDINAL = AMBridge.TVToLC[tv]; tv _ AMTypes.Referent[tv]; tv _ AMTypes.IndexToTV[tv, AMTypes.NameToIndex[AMTypes.TVType[tv], "streamProcs"]]; -- tv for REF streamProcs tv _ AMTypes.Referent[tv]; tv _ AMTypes.IndexToTV[tv, AMTypes.NameToIndex[AMTypes.TVType[tv], "name"]]; -- tv for the name field stream.PutF["{%bB - %g Stream", card[address], IO.tv[tv]]; <> stream.PutChar['}]; }; HistoryPrintProc: RefPrintProc = { stream.PutRope["{history list}"]; }; ViewerPrintProc: TVPrintProc = TRUSTED { IF AMBridge.IsRemote[tv] THEN { -- differences: does not look up name on property list of stream, prints streamprocs.name with "'s around it. RemoteViewerPrintProc[tv, stream]; } ELSE { viewer: ViewerClasses.Viewer = NARROW[AMBridge.RefFromTV[AMTypes.Referent[tv]]]; stream.PutF["{Viewer - class: %g, name: %g}", atom[viewer.class.flavor], rope[IF Rope.Length[viewer.name] # 0 THEN viewer.name ELSE "(no name)"]]; }; }; RemoteViewerPrintProc: PROC[tv: RTBasic.TV, stream: IO.STREAM] = TRUSTED { name, flavor: TV; tv _ AMTypes.Referent[tv]; name _ AMTypes.IndexToTV[tv, AMTypes.NameToIndex[AMTypes.TVType[tv], "name"]]; -- tv for the name field tv _ AMTypes.IndexToTV[tv, AMTypes.NameToIndex[AMTypes.TVType[tv], "class"]]; -- tv for the class field tv _ AMTypes.Referent[tv]; flavor _ AMTypes.IndexToTV[tv, AMTypes.NameToIndex[AMTypes.TVType[tv], "flavor"]]; -- tv for the class field stream.PutF["{Viewer - class: %g, name: %g}", IO.tv[flavor], IF AMTypes.IsNil[name] THEN rope["(no name)"] ELSE IO.tv[name]]; }; ExecHandlePrintProc: TVPrintProc = TRUSTED { id: TV; tv _ AMTypes.Referent[tv]; tv _ AMTypes.IndexToTV[tv, AMTypes.NameToIndex[AMTypes.TVType[tv], "privateStuff"]]; -- tv for the privateStuff field tv _ AMTypes.Referent[tv]; id _ AMTypes.IndexToTV[tv, AMTypes.NameToIndex[AMTypes.TVType[tv], "id"]]; -- tv for the id field stream.PutF["{UserExecHandle: %g}", IO.tv[id]]; }; <> AttachDefaultArgVal: PUBLIC PROCEDURE [type: Type, default: TV] = { Atom.TypePutProp[type, $DefaultValue, default]; }; -- of AttachDefaultArgVal AttachTypeCorrectionProc: PUBLIC PROCEDURE [type: Type, proc: CorrectionProc] = { -- associates a correctionProc with a type. Atom.TypePutProp[type, $WrongTypeProc, NEW[CorrectionProc _ proc]]; }; -- of AttachTypeCorrectionProc CorrectToAtom: CorrectionProc = TRUSTED { -- AMBridge OPEN IO; out: STREAM = UserExec.GetStreams[exec].out; out.NewLine[]; out.PutF["*%g -> $%g\n", rope[undefinedId], rope[undefinedId]]; out.Flush[]; RETURN[TRUE, AMBridge.TVForReferent[NEW[ATOM _ Atom.MakeAtom[undefinedId]]]]; }; -- of CorrectAtom CorrectToRefAny: CorrectionProc -- [targetType: Type, undefinedId: ROPE _ NIL, wrongValue: TV _ NIL, exec: ExecHandle] RETURNS[flag: BOOLEAN _ FALSE, shouldBe: TV _ NIL] -- = TRUSTED { -- AMBridge OPEN IO; IF undefinedId # NIL THEN {UserExec.GetStreams[exec].out.PutF["*n%g -> $%g\n", rope[undefinedId], rope[undefinedId] ]; RETURN[TRUE, AMBridge.TVForReferent[NEW[ATOM _ Atom.MakeAtom[undefinedId]]]]; } ELSE IF NOT AMBridge.IsRemote[wrongValue] THEN RETURN[TRUE, AMBridge.TVForReferent[NEW[REF ANY _ AMBridge.SomeRefFromTV[wrongValue]]]] ; }; -- of CorrectToRefAny CorrectToString: CorrectionProc -- [targetType: Type, undefinedId: ROPE _ NIL, wrongValue: TV _ NIL] RETURNS[flag: BOOLEAN _ FALSE, shouldBe: TV _ NIL] -- = TRUSTED { -- AMBridge type: Type ; IF undefinedId # NIL THEN RETURN; type _ AMTypes.TVType[wrongValue]; IF AMTypes.IsRope[wrongValue] THEN -- rope typed in. {r: ROPE = AMTypes.TVToName[wrongValue]; s: STRING = Heap.systemMDSZone.NEW[StringBody[Rope.Length[r]]]; ConvertUnsafe.AppendRope[to: s, from: r]; RETURN[TRUE, AMBridge.TVForReferent[NEW[STRING _ s]]]; }; }; -- of CorrectToString CorrectToLongString: CorrectionProc -- [targetType: Type, undefinedId: ROPE _ NIL, wrongValue: TV _ NIL] RETURNS[flag: BOOLEAN _ FALSE, shouldBe: TV _ NIL] -- = TRUSTED { -- AMBridge type: Type ; IF undefinedId # NIL THEN RETURN; type _ AMTypes.TVType[wrongValue]; IF AMTypes.IsRope[wrongValue] THEN -- rope typed in, LONG STRING . {r: ROPE = AMTypes.TVToName[wrongValue]; s: LONG STRING = UnsafeStorage.GetSystemUZone[].NEW[StringBody[Rope.Length[r]]]; ConvertUnsafe.AppendRope[to: s, from: r]; RETURN[TRUE, AMBridge.TVForReferent[NEW[LONG STRING _ s]]]; }; }; -- of CorrectToLongString CorrectToRefText: CorrectionProc -- [targetType: Type, undefinedId: ROPE _ NIL, wrongValue: TV _ NIL] RETURNS[flag: BOOLEAN _ FALSE, shouldBe: TV _ NIL] -- = TRUSTED { -- AMBridge type: Type ; IF undefinedId # NIL THEN RETURN; type _ AMTypes.TVType[wrongValue]; IF AMTypes.IsRope[wrongValue] THEN -- rope typed in, REF TEXT wanted. {r: ROPE = AMTypes.TVToName[wrongValue]; t: REF TEXT = Rope.ToRefText[r]; RETURN[TRUE, AMBridge.TVForReferent[NEW[REF TEXT _ t]]]; }; }; -- of CorrectToRefText CorrectToRefReadOnlyText: CorrectionProc -- [targetType: Type, undefinedId: ROPE _ NIL, wrongValue: TV _ NIL] RETURNS[flag: BOOLEAN _ FALSE, shouldBe: TV _ NIL] -- = TRUSTED { -- AMBridge type: Type; IF undefinedId # NIL THEN RETURN; type _ AMTypes.TVType[wrongValue]; IF AMTypes.IsRope[wrongValue] THEN -- rope typed in, REF TEXT wanted. {r: ROPE = AMTypes.TVToName[wrongValue]; t: REF TEXT = Rope.ToRefText[r]; RETURN[TRUE, AMBridge.TVForReferent[NEW[REF READONLY TEXT _ t]]]; }; }; -- of CorrectToRefReadOnlyText CorrectToRopeText: CorrectionProc -- [targetType: Type, undefinedId: ROPE _ NIL, wrongValue: TV _ NIL] RETURNS[flag: BOOLEAN _ FALSE, shouldBe: TV _ NIL] -- = TRUSTED { -- AMBridge type: Type; IF undefinedId # NIL THEN RETURN; type _ AMTypes.TVType[wrongValue]; IF AMTypes.IsRope[wrongValue] THEN -- rope typed in, Rope.Text wanted. {r: ROPE = AMTypes.TVToName[wrongValue]; t: Rope.Text = Rope.Flatten[r]; RETURN[TRUE, AMBridge.TVForReferent[NEW[Rope.Text _ t]]]; }; }; -- of CorrectToRopeText CorrectToProcAnyAny: CorrectionProc -- [targetType: Type, undefinedId: ROPE _ NIL, wrongValue: TV _ NIL] RETURNS[flag: BOOLEAN _ FALSE, shouldBe: TV _ NIL] -- = { IF undefinedId # NIL THEN RETURN; }; -- of CorrectProcAnyAny Init: PUBLIC PROC = { ENABLE ANY => CONTINUE; -- SHOULD GO TO ERROR LOG AttachRefPrintProc[refType: CODE[PPTree.Handle], refPrintProc: TreePrintProc ! ANY => CONTINUE]; AttachRefPrintProc[refType: CODE[PPLeaves.HTIndex], refPrintProc: TreePrintProc ! ANY => CONTINUE]; AttachRefPrintProc[refType: CODE[PPLeaves.LTIndex], refPrintProc: TreePrintProc ! ANY => CONTINUE]; <> AttachRefPrintProc[refType: CODE[UserExec.HistoryList], refPrintProc: HistoryPrintProc ! ANY => CONTINUE]; <> AttachRefPrintProc[refType: CODE[BasicUserExec.Interface], refPrintProc: InterfacePrintProc ! ANY => CONTINUE]; AttachRefPrintProc[refType: CODE[REF RTTypesPrivate.TypedVariableRec], refPrintProc: tvPrintProc ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[ViewerClasses.Viewer], tvPrintProc: ViewerPrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[STREAM], tvPrintProc: STREAMPrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[UserExec.ExecHandle], tvPrintProc: ExecHandlePrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[REF TEXT], tvPrintProc: RefTextPrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[REF READONLY TEXT], tvPrintProc: RefTextPrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[TEXT], tvPrintProc: TextPrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[STRING], tvPrintProc: StringPrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[LONG STRING], tvPrintProc: LongStringPrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[NAT], tvPrintProc: NatPrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[Type], tvPrintProc: TypePrintProc, canHandleRemote: TRUE ! ANY => CONTINUE]; AttachTVPrintProc[type: CODE[System.GreenwichMeanTime], tvPrintProc: TimePrintProc, canHandleRemote: FALSE ! ANY => CONTINUE]; AttachTypeCorrectionProc[type: CODE[ATOM], proc: CorrectToAtom ! ANY => CONTINUE]; AttachTypeCorrectionProc[type: CODE[REF ANY], proc: CorrectToRefAny ! ANY => CONTINUE]; AttachTypeCorrectionProc[type: CODE[STRING], proc: CorrectToString ! ANY => CONTINUE]; AttachTypeCorrectionProc[type: CODE[LONG STRING], proc: CorrectToLongString ! ANY => CONTINUE]; AttachTypeCorrectionProc[type: CODE[REF TEXT], proc: CorrectToRefText ! ANY => CONTINUE]; AttachTypeCorrectionProc[type: CODE[REF READONLY TEXT], proc: CorrectToRefReadOnlyText ! ANY => CONTINUE]; AttachTypeCorrectionProc[type: CODE[Rope.Text], proc: CorrectToRopeText ! ANY => CONTINUE]; AttachTypeCorrectionProc[type: CODE[PROC ANY RETURNS ANY], proc: CorrectToProcAnyAny ! ANY => CONTINUE]; AttachDefaultArgVal[type: CODE[PROC ANY RETURNS ANY], default: NIL]; TRUSTED { AttachDefaultArgVal[type: CODE[PROCESS], default: AMBridge.TVForReferent[NEW[PROCESS _ NIL]]]; AttachDefaultArgVal[type: CODE[UNSAFE PROCESS], default: AMBridge.TVForReferent[NEW[UNSAFE PROCESS _ NIL]]]; }; }; IF PilotSwitches.switches.n#down THEN Init[]; END. -- of BasicUserExecImpl <> <> <> <> <> << >> <<>> <<>>