<> <> <> <> <<>> DIRECTORY Convert, GGBasicTypes, GGParseIn, Imager, ImagerColor, ImagerTransformation, IO, RefText, Rope; GGParseInImpl: CEDAR PROGRAM IMPORTS Convert, Imager, ImagerColor, ImagerTransformation, IO, RefText, Rope EXPORTS GGParseIn = BEGIN RopeNotOnTop: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE; Color: TYPE = Imager.Color; Point: TYPE = GGBasicTypes.Point; ReadBlank: PUBLIC PROC [f: IO.STREAM] = { <'s, 's, and 's until something else is encountered. Doesn't mind if no white space characters are found. Treats comments as white space.>> [] _ IO.SkipWhitespace[f, TRUE]; }; ReadWhiteSpace: PUBLIC PROC [f: IO.STREAM] = { <'s, 's, and 's until something else is encountered. Signals RopeNotOnTop if no white space characters are found.>> WhiteSpaceProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM IO.TAB => RETURN [other]; IO.CR =>RETURN [other]; IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; whiteSpace: Rope.ROPE; end: BOOL _ FALSE; [whiteSpace, ----] _ IO.GetTokenRope[f, WhiteSpaceProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR Rope.Size[whiteSpace] = 0 THEN SIGNAL RopeNotOnTop[IO.GetIndex[f], "null", ""]; }; ReadHorizontalBlank: PUBLIC PROC [f: IO.STREAM] RETURNS [good: BOOL] = { <'s, and 's until something else is encountered. Returns good = FALSE if a CR is encountered before anything else>> HorizontalBlankProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM IO.TAB, IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; whiteSpace: Rope.ROPE; c: CHAR; end: BOOL _ FALSE; good _ TRUE; [whiteSpace, ----] _ IO.GetTokenRope[f, HorizontalBlankProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; c _ Rope.Fetch[whiteSpace, 0]; SELECT c FROM IO.CR => {good _ FALSE; RETURN}; IO.TAB, IO.SP => {good _ TRUE; RETURN}; ENDCASE => {good _ TRUE; IO.Backup[f, c]; RETURN}; }; ReadWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { <> WordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.TAB => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ', => RETURN [break]; '] => RETURN [break]; ') => RETURN [break]; ENDCASE => RETURN [other]; }; [word, ----] _ IO.GetTokenRope[f, WordBreakProc !IO.EndOfStream => {word _ NIL; CONTINUE}]; }; ReadColorToken: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { <, or are encountered.>> ColorBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.TAB => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ENDCASE => RETURN [other]; }; [word, ----] _ IO.GetTokenRope[f, ColorBreakProc !IO.EndOfStream => {word _ NIL; CONTINUE}]; }; ReadBlankAndWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { <> ReadBlank[f]; word _ ReadWord[f]; }; ReadBlankAndColor: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { ReadBlank[f]; word _ ReadColorToken[f]; }; ReadRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { <> <> c: CHAR; endofstream: BOOL _ FALSE; FOR i: INT IN[1..Rope.Length[rope]] DO c _ IO.GetChar[f ! IO.EndOfStream => {endofstream _ TRUE; CONTINUE}]; IF endofstream THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], NIL, rope]; IF NOT c = Rope.Fetch[rope,i-1] THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], Rope.FromChar[c], rope]; ENDLOOP; }; ReadBlankAndRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { ReadBlank[f]; ReadRope[f, rope]; }; ReadNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { <, . Leaves these terminators on the stream.>> NATBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.SP, '., ',, ': => RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; intRope: Rope.ROPE; [intRope, ----] _ IO.GetTokenRope[f, NATBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {n _ 1; RETURN}; n _ Convert.IntFromRope[intRope]; }; ReadBlankAndNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { <> ReadBlank[f]; n _ ReadNAT[f]; }; ReadColor: PUBLIC PROC [f: IO.STREAM] RETURNS [color: Color] = { s: IO.STREAM; r, g, b: REAL; word: Rope.ROPE _ ReadBlankAndColor[f]; IF Rope.Equal[word, "none"] THEN RETURN[NIL]; s _ IO.RIS[word, colorStream]; ReadChar[s, '[]; r _ ReadBlankAndReal[s]; ReadChar[s, ',]; g _ ReadBlankAndReal[s]; ReadChar[s, ',]; b _ ReadBlankAndReal[s]; ReadChar[s, ']]; color _ ImagerColor.ColorFromRGB[[r, g, b]]; IF ImagerColor.GrayFromColor[NARROW[color]]=1.0 THEN color _ Imager.black; -- "process black" }; -- end of ReadColor ReadStrokeEnd: PUBLIC PROC [f: IO.STREAM] RETURNS [strokeEnd: Imager.StrokeEnd] = { endName: Rope.ROPE _ ReadBlankAndWord[f]; SELECT TRUE FROM Rope.Equal[endName, "square", TRUE] => strokeEnd _ square; Rope.Equal[endName, "butt", TRUE] => strokeEnd _ butt; Rope.Equal[endName, "round", TRUE] => strokeEnd _ round; ENDCASE => ERROR; }; ReadPoint: PUBLIC PROC [f: IO.STREAM] RETURNS [point: Point] = { <,]".>> ReadRope[f, "["]; point.x _ ReadBlankAndReal[f]; ReadRope[f, ","]; point.y _ ReadBlankAndReal[f]; ReadRope[f, "]"]; }; ReadChar: PUBLIC PROC [f: IO.STREAM, c: CHAR] = { streamC: CHAR _ IO.GetChar[f]; IF NOT c = streamC THEN SIGNAL RopeNotOnTop[IO.GetIndex[f], Rope.FromChar[streamC], Rope.FromChar[c]]; }; ReadKeyWord: PUBLIC PROC [f: IO.STREAM] RETURNS [keyWord: Rope.ROPE, good: BOOL] = { < are encountered. If CR is encountered first, then good is FALSE since ":" is expected after a keyword.>> KeyWordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ': => RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; nextChar: Rope.ROPE; [keyWord, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; keyWord _ NIL; RETURN}; [nextChar, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; good _ Rope.Equal[nextChar, ":", TRUE]; }; ReadLine: PUBLIC PROC [f: IO.STREAM] RETURNS [line: Rope.ROPE] = { < is encountered.>> LineBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; [line, ----] _ IO.GetTokenRope[f, LineBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {line _ NIL; RETURN}; [----, ----] _ IO.GetTokenRope[f, LineBreakProc]; -- remove }; ReadReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { <, or . Leaves these terminators on the stream.>> RealBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '), '], ', => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ENDCASE => RETURN [other]; }; realText, buffer: REF TEXT; end: BOOL _ FALSE; buffer _ RefText.ObtainScratch[50]; [realText, ----] _ IO.GetToken[f, RealBreakProc, buffer !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {r _ 0.0; RETURN}; IF RefText.Find[realText, ".", 0, FALSE] = -1 THEN realText _ RefText.Append[realText, ".0"]; r _ Convert.RealFromRope[RefText.TrustTextAsRope[realText]]; RefText.ReleaseScratch[buffer]; }; ReadBlankAndReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { <> ReadBlank[f]; r _ ReadReal[f]; }; ReadBOOL: PUBLIC PROC [f: IO.STREAM] RETURNS [truth: BOOL, good: BOOL] = { <> BoolBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.SP, '., ', => RETURN [break]; ENDCASE => RETURN [other]; }; end: BOOL _ FALSE; boolRope: Rope.ROPE; [boolRope, ----] _ IO.GetTokenRope[f, BoolBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; truth _ FALSE; RETURN}; good _ TRUE; IF Rope.Equal[boolRope, "TRUE", TRUE] THEN truth _ TRUE ELSE IF Rope.Equal[boolRope, "FALSE", TRUE] THEN truth _ FALSE ELSE {truth _ FALSE; good _ FALSE}; }; ReadListOfRope: PUBLIC PROC [f: IO.STREAM] RETURNS [ropeList: LIST OF Rope.ROPE] = { RopesOnOneLineOrParenProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR, ') =>RETURN [break]; IO.SP, IO.TAB, ', , '; => RETURN [sepr]; ENDCASE => RETURN [other]; }; rope: Rope.ROPE; end: BOOL _ FALSE; ropeList _ NIL; WHILE TRUE DO [rope, ----] _ IO.GetTokenRope[f, RopesOnOneLineOrParenProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR rope = NIL THEN RETURN; IF Rope.Equal[rope, Rope.FromChar[IO.CR]] THEN RETURN; IF Rope.Equal[rope, Rope.FromChar[')]] THEN { f.Backup[')]; RETURN; }; ropeList _ AppendRopeToRopeList[rope, ropeList]; ENDLOOP; }; ReadTransformation: PUBLIC PROC [f: IO.STREAM] RETURNS [transform: ImagerTransformation.Transformation] = { a, b, c, d, e, g: REAL; ReadBlankAndRope[f, "["]; a _ ReadBlankAndReal[f]; b _ ReadBlankAndReal[f]; c _ ReadBlankAndReal[f]; d _ ReadBlankAndReal[f]; e _ ReadBlankAndReal[f]; g _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "]"]; transform _ ImagerTransformation.Create[a, b, c, d, e, g]; }; AppendRopeToRopeList: PROC [rope: Rope.ROPE, list: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] = { <> z: LIST OF Rope.ROPE _ list; IF z = NIL THEN RETURN[CONS[rope,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[rope,NIL]; RETURN[list]; }; colorStream: IO.STREAM; <> Init: PROC [] = { <> colorStream _ IO.RIS["This string is longer than any color is likely to be."]; }; Init[]; END.