<> <<>> <> <> <> DIRECTORY Basics USING [LowByte, LowHalf], FS USING [Error, StreamOpen, OpenFile, Open], IO USING [Close, EndOf, GetChar, int, Put, PutChar, PutRope, real, refAny], JaM USING [AGet, Any, Array, AtomToRope, Command, Dict, Error, ExecuteRope, Mark, Op, Pop, PopBool, PopInt, PopStream, PopRope, PushBool, PushInt, PushStream, ROPE, RopeToAtom, State, Stop, STREAM, TryToLoad], JaMPrimitives USING [], Loader USING [Error, Instantiate, Start], PrincOps USING [ControlModule], FileNames USING [FileWithSearchRules], RopeIO USING [FromFile]; JaMIOImpl: CEDAR PROGRAM IMPORTS Basics, FS, IO, JaM, RopeIO, FileNames, Loader EXPORTS JaMPrimitives = BEGIN OPEN JaM; BYTE: TYPE = [0..256); IntToChar: PROC[i: INT] RETURNS[CHAR] = INLINE { RETURN[LOOPHOLE[Basics.LowByte[Basics.LowHalf[i]]]] }; CharToInt: PROC[c: CHAR] RETURNS[INT] = INLINE { RETURN[LOOPHOLE[c, BYTE]] }; NotFound: SIGNAL = CODE; FullName: PROC [name, extension: ROPE, self: State] RETURNS [fullName: ROPE] = { rules: REF ANY; found: BOOLEAN; [found, rules] _ TryToLoad[self, RopeToAtom[".searchrules"]]; IF ~found THEN rules _ NIL; [fullName,] _ FileNames.FileWithSearchRules[root: name, defaultExtension: extension, requireExtension: FALSE, requireExact: TRUE, searchRules: rules]; IF fullName=NIL THEN SIGNAL NotFound ELSE RETURN[fullName]; }; OpenStream: PROC[name: ROPE, write: BOOL _ FALSE] RETURNS[STREAM] = { msg: ROPE; stream: STREAM = FS.StreamOpen[ fileName: name, accessOptions: (IF write THEN $create ELSE $read) ! FS.Error => IF error.group = user THEN msg _ error.explanation]; IF msg=NIL THEN RETURN[stream] ELSE ERROR Error[OpenFailed, msg]; }; <> ApplyRun: PUBLIC PROC[self: State] = { file: ROPE = PopRope[self]; rope: ROPE = RopeIO.FromFile[FullName[file, ".jam", self ! NotFound => GOTO NotFound]]; ExecuteRope[self, rope ! Stop => CONTINUE]; EXITS NotFound => ERROR Error[OpenFailed, "file not found"]; }; ApplyLoadBCD: PUBLIC PROC[self: State] = { filename: ROPE _ PopRope[self]; msg: ROPE; TRUSTED { --extra block for TRUSTED and EXITS file: FS.OpenFile; prog: PrincOps.ControlModule; filename _ FullName[filename, ".bcd", self ! NotFound => GOTO NotFound]; file _ FS.Open[filename ! FS.Error => {IF error.group = user THEN msg _ error.explanation; GOTO FSError}]; [prog,] _ Loader.Instantiate[file: file ! Loader.Error => {msg _ message; GOTO LoadFailed}]; Loader.Start[prog]; EXITS NotFound => ERROR Error[OpenFailed, "file not found"]; FSError => ERROR Error[OpenFailed, msg]; LoadFailed => ERROR Error[LoadFailed, msg]; }; }; ApplyStream: PUBLIC PROC[self: State] = { write: BOOL = PopBool[self]; name: ROPE = PopRope[self]; stream: STREAM = OpenStream[FullName[name, NIL, self ! NotFound => GOTO NotFound], write]; PushStream[self, stream]; EXITS NotFound => ERROR Error[OpenFailed, "file not found"]; }; ApplyReadItem: PUBLIC PROC[self: State] = { stream: STREAM = PopStream[self]; ok: BOOLEAN _ NOT stream.EndOf[]; IF ok THEN PushInt[self, CharToInt[stream.GetChar[]]] ELSE stream.Close[]; PushBool[self, ok]; }; ApplyWriteItem: PUBLIC PROC[self: State] = { item: INT = PopInt[self]; stream: STREAM = PopStream[self]; stream.PutChar[IntToChar[item]]; }; <> <> <> <> <> <> <<{ ENABLE UNWIND => TextFree[@line];>> <> <> <> <> <> <> <<};>> <> <> <> <<};>> <<>> ApplyWriteBytes: PUBLIC PROC[self: State] = { string: ROPE = PopRope[self]; stream: STREAM = PopStream[self]; stream.PutRope[string]; }; ApplyKillStream: PUBLIC PROC[self: State] = { stream: STREAM = PopStream[self]; stream.Close[]; }; Print: PROC[self: State, x: Any] = { out: STREAM = self.out; WITH x SELECT FROM x: REF INT => out.Put[IO.int[x^]]; x: REF REAL => out.Put[IO.real[x^]]; x: ROPE => out.PutRope[x]; x: ATOM => out.PutRope[AtomToRope[x]]; x: STREAM => out.PutRope[""]; x: Command => out.PutRope[""]; x: Op => out.PutRope[""]; x: Array => PrintArray[self, x]; x: Dict => out.PutRope[""]; x: Mark => out.PutRope[""]; x: LIST OF REF ANY => PrintList[self, x]; x: LIST OF ROPE => LoopholePrintList[self, x]; x: LIST OF REF INT => LoopholePrintList[self, x]; x: LIST OF REF REAL => LoopholePrintList[self, x]; x: LIST OF LIST OF ATOM => LoopholePrintList[self, x]; ENDCASE => out.Put[IO.refAny[x]]; }; PrintArray: PROC[self: State, array: Array] = { out: STREAM = self.out; out.PutRope["{ "]; FOR i: INT IN[0..array.length) DO Print[self, AGet[array, i]]; out.PutRope[" "]; ENDLOOP; out.PutRope["}"]; }; LoopholePrintList: PROC[self: State, list: REF ANY] = TRUSTED { --to force "general" lists PrintList[self: self, list: LOOPHOLE[list]]; }; PrintList: PROC[self: State, list: LIST OF REF ANY] = { x: Any = Pop[self]; self.out.PutRope["LIST["]; FOR each: LIST OF REF ANY _ list, each.rest WHILE each #NIL DO Print[self, each.first]; IF each.rest#NIL THEN self.out.PutRope[ ", "]; ENDLOOP; self.out.PutRope["]"]; }; ApplyPrint: PUBLIC PROC[self: State] = { x: Any = Pop[self]; Print[self, x]; }; END.