-- file SakuraDriver.Mesa -- last modified by Satterthwaite, January 13, 1981 9:29 AM -- last edit by Russ Atkinson, 9-Jul-81 14:50:32 -- last edited by Suzuki, 7-Mar-82 21:36:56 DIRECTORY Convert: TYPE USING [MapValue, Value], ConvertUnsafe: TYPE USING [ToRope], IOStream: TYPE USING [Handle, Close, CreateFileStream, SetLength], PPLeaves: TYPE USING [ISEIndex, HTIndex, LTIndex], -- PPP1 USING [OpenTest, CloseTest], PPRopeFile: TYPE USING [Create], Rope: TYPE USING [Concat, Equal, Flatten, Index, Map, Ref, Size, Substr, Text], SafeStorage: TYPE USING [ReclaimCollectibleObjects, SetCollectionInterval], SakuraCommon, SakuraOps: TYPE USING [ParseStream, SetLog], SakuraRewrite: TYPE USING [PutChoiceDecl, Rewrite], SakuraTree: TYPE USING [Handle, Link], SakuraTreeOps: TYPE USING [Initialize, Finalize], SakuraUtil: TYPE USING [PrettyPrint], TTY: TYPE USING [Create, Destroy, GetLine, Handle, PutChar, PutCR]; SakuraDriver: MONITOR IMPORTS Convert, ConvertUnsafe, IOStream, SakuraOps, SakuraRewrite, SakuraTreeOps, SakuraUtil, PPRopeFile, Rope, SafeStorage, TTY EXPORTS SakuraCommon = BEGIN OPEN Tree: SakuraTree, SakuraTreeOps, PPLeaves, TTY; -- main loop CR: CHARACTER = 15C; Unimplemented: SIGNAL = CODE; tty: PUBLIC Handle _ Create["Sakura"]; CharAction: PROC [c: CHARACTER] RETURNS [BOOLEAN] = { PutChar[tty, c]; RETURN [FALSE]}; Char1: PROC [c: CHARACTER] = {PutChar[tty, c]}; PutRope: PROC [r: Rope.Ref, newLine: BOOLEAN _ FALSE] = { [] _ Rope.Map[base: r, action: CharAction]; IF newLine THEN PutChar[tty, CR]; }; GetFileName: PROC [prompt,suffix,last: Rope.Ref] RETURNS [Rope.Text] = { line: STRING _ [80]; pos: LONG INTEGER _ 0; name: Rope.Ref _ NIL; PutRope[prompt]; GetLine[tty, line]; IF line.length=0 THEN RETURN[NIL]; name _ ConvertUnsafe.ToRope[line]; IF name.Equal["$"] THEN name _ last.Substr[0, last.Index[0, "."]]; pos _ name.Index[0, "."]; IF pos = name.Size[] THEN { name _ name.Concat[suffix]}; RETURN [name.Flatten[]]; }; GetInfo: PROC [t: Tree.Link] RETURNS [info: LONG INTEGER] = { DO WITH t SELECT FROM hti: HTIndex => info _ hti.index; lti: LTIndex => info _ lti.index; x: Tree.Handle => {info _ x.info; IF info = 0 THEN FOR i: NAT IN [1..x.sonLimit) WHILE info = 0 DO info _ GetInfo[x[i]] ENDLOOP}; ENDCASE => info _ 0; EXIT ENDLOOP}; GetAttrs: PROC [t: Tree.Link] RETURNS [a1: BOOLEAN, a2: BOOLEAN, a3: BOOLEAN] = { WITH t SELECT FROM x: Tree.Handle => RETURN [x.attr[1], x.attr[2], x.attr[3]]; ENDCASE => a1 _ a2 _ a3 _ FALSE}; SetExtension: PROC [name: STRING, ext: STRING] = { IF name = NIL OR ext = NIL OR name.length = 0 OR ext.length = 0 THEN RETURN; FOR i: NAT IN [0..name.length) DO IF name[i] = '. THEN RETURN; ENDLOOP; FOR i: NAT IN [0..ext.length) DO name[name.length] _ ext[i]; name.length _ name.length + 1; ENDLOOP; }; TreeComp: PROC [out: IOStream.Handle, t1,t2: Tree.Link] RETURNS [BOOLEAN] = { oops: LONG INTEGER _ 0; IF t1 = t2 THEN RETURN [TRUE]; WITH t1 SELECT FROM hti1: HTIndex => { WITH t2 SELECT FROM hti2: HTIndex => IF Rope.Equal[hti1.name, hti2.name] THEN RETURN [TRUE]; ise: ISEIndex => IF Rope.Equal[hti1.name, ise] THEN RETURN [TRUE]; ENDCASE; oops _ hti1.index}; lti1: LTIndex => { WITH t2 SELECT FROM lti2: LTIndex => IF Rope.Equal[lti1.literal, lti2.literal] THEN RETURN [TRUE]; ENDCASE; oops _ lti1.index}; x1: Tree.Handle => { WITH t2 SELECT FROM x2: Tree.Handle => { same: BOOLEAN _ x1.name = x2.name AND x1.sonLimit = x2.sonLimit AND x1.attr = x2.attr; FOR i: NAT IN [1..x1.sonLimit) WHILE same DO same _ TreeComp[out, x1[i], x2[i]]; ENDLOOP; IF same THEN RETURN [TRUE]}; ENDCASE; oops _ GetInfo[t1]}; ise1: ISEIndex => { WITH t2 SELECT FROM hti2: HTIndex => IF Rope.Equal[ise1, hti2.name] THEN RETURN [TRUE]; ise2: ISEIndex => IF Rope.Equal[ise1, ise2] THEN RETURN [TRUE]; ENDCASE; PutRope["Atomic difference, no index"]; PutCR[tty]}; ENDCASE => ERROR; PutRope["Difference found near source index "]; Convert.MapValue[Char1, [signed[oops]]]; PutCR[tty]; RETURN [FALSE]; }; croaker: PROC = {[] _ SafeStorage.ReclaimCollectibleObjects[]}; oldTree: Tree.Link _ NIL; newTree: Tree.Link _ NIL; Main: PUBLIC ENTRY PROC = { DO -- just keep processing the files in, out: IOStream.Handle _ NIL; source, name, tree, check: Rope.Ref _ NIL; oldTree _ newTree _ NIL; PutCR[tty]; name _ GetFileName["Input file: ", ".sak", NIL ! ANY => EXIT]; IF name=NIL THEN EXIT; in _ IOStream.CreateFileStream[name, read ! ANY => {PutRope["Can't open '"]; PutRope[LOOPHOLE[name]]; PutChar[tty, '']; PutCR[tty]; LOOP}]; tree _ GetFileName["Output file: ", ".mesa", name ! ANY => LOOP]; out _ IOStream.CreateFileStream[tree, write]; IOStream.SetLength[out, 0]; source _ PPRopeFile.Create[in, 4096, 4, TRUE].rope; -- PPP1.OpenTest[]; oldTree _ SakuraOps.ParseStream[source, out, FALSE]; -- PPP1.CloseTest[]; SakuraTreeOps.Initialize[]; oldTree _ SakuraRewrite.Rewrite[oldTree]; oldTree _ SakuraRewrite.PutChoiceDecl[oldTree]; SakuraOps.SetLog[out]; SakuraUtil.PrettyPrint[oldTree]; SakuraOps.SetLog[NIL]; SakuraTreeOps.Finalize[]; IOStream.Close[in]; IOStream.Close[out]; ENDLOOP; TTY.Destroy[tty]}; [] _ SafeStorage.SetCollectionInterval[1000000]; END.