IPMiscImpl.mesa
Last edited by:
Doug Wyatt, April 28, 1983 6:26 pm
DIRECTORY
FileIO USING [Open],
IO,
IPBasic USING [Rational],
IPEncoding,
IPMisc USING [],
Rope,
RopeIO,
RopeReader;
IPMiscImpl: CEDAR PROGRAM
IMPORTS FileIO, IO, IPEncoding, Rope, RopeIO, RopeReader
EXPORTS IPMisc
= BEGIN OPEN IPEncoding;
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
Rational: TYPE = IPBasic.Rational;
BodyOp: PROC[token: Token] RETURNS[BOOL] = {
RETURN[SELECT token.op FROM
makesimpleco, makeco, makecompiledimage, dosavesimplebody, dobody, dosavebody, dosaveallbody, if, ifelse, ifcopy, loop, correct => TRUE, ENDCASE => FALSE];
};
InhibitNewLine: PROC[token: Token] RETURNS[BOOL] = {
SELECT token.op FROM
scale, scale2, rotate, translate, makevec, makeveclu => RETURN[TRUE];
makesimpleco, makeco, makecompiledimage, dosavesimplebody, dobody, dosavebody, dosaveallbody, if, ifelse, ifcopy, loop, correct => RETURN[TRUE];
ENDCASE => RETURN[FALSE];
};
ToWritten: PUBLIC PROC[from: ROPE, to: ROPE, tick: PROCNIL] = {
reader: Reader = OpenReader[from];
writer: Writer = OpenWriter[to, "Written"];
writer.stream.PutRope["-- "];
writer.stream.PutRope[from];
writer.stream.PutRope[" -> "];
writer.stream.PutRope[to];
writer.stream.PutRope[" -- \n"];
WriteWritten[reader, writer, tick];
CloseReader[reader];
CloseWriter[writer];
};
WriteWritten: PROC[reader: Reader, writer: Writer, tick: PROC] = {
token: Token ← nullToken;
prevToken: Token ← nullToken;
nest: INT ← 0;
page: INT ← 0;
FOR index: INT ← reader.GetStartingIndex[], token.next DO
token ← reader.GetToken[index];
IF token.type=eof THEN EXIT;
IF (token.op=iget OR token.op=iset) AND prevToken.type=number THEN {
writer.stream.PutRope["--"];
writer.stream.PutRope[SELECT prevToken.number FROM
0 => "DCScpx", 1 => "DCScpy", 2 => "correctMX", 3 => "correctMY",
4 => "T", 5 => "priorityImportant", 6 => "mediumXSize", 7 => "mediumYSize",
8 => "fieldXMin", 9 => "fieldYMin", 10 => "fieldXMax", 11 => "fieldYMax",
12 => "showVec", 13 => "color", 14 => "noImage", 15 => "strokeWidth",
16 => "strokeEnd", 17 => "underlineStart", 18 => "amplifySpace",
19 => "correctPass", 20 => "correctShrink", 21 => "correctTX", 22 => "correctTY",
ENDCASE => "???"];
writer.stream.PutRope["-- "];
};
[] ← EncodeToken[reader, writer, token];
SELECT token.op FROM
beginBody => {
IF nest=0 THEN {
IF tick#NIL THEN tick[];
IF page=0 THEN writer.stream.PutRope["-- Preamble -- "]
ELSE writer.stream.Put[IO.rope["-- Page "], IO.int[page], IO.rope[" -- "]];
};
nest ← nest+1;
};
endBody => {
nest ← nest-1;
IF nest=0 THEN page ← page+1;
};
ENDCASE;
IF token.type=op AND NOT InhibitNewLine[token] THEN {
writer.stream.PutChar['\n];
THROUGH [0..nest) DO writer.stream.PutRope[" "] ENDLOOP;
};
IF token.type=rational THEN {
r: Rational = reader.GetRational[token];
n: REAL = r.num; d: REAL = r.den;
writer.stream.PutRope["--("];
IF d#0 THEN writer.stream.Put[IO.real[n/d]]
ELSE writer.stream.PutRope["???"];
writer.stream.PutRope[")-- "];
};
prevToken ← token;
ENDLOOP;
};
ToEncoded: PUBLIC PROC[from: ROPE, to: ROPE, tick: PROCNIL] = {
reader: Reader = OpenReader[from];
writer: Writer = OpenWriter[to, "Xerox"];
WriteEncoded[reader, writer, tick];
CloseReader[reader];
CloseWriter[writer];
};
WriteEncoded: PROC[reader: Reader, writer: Writer, tick: PROCNIL] = {
index: INT ← reader.GetStartingIndex[];
DO token: Token = reader.GetToken[index];
SELECT token.type FROM
op => SELECT token.op FROM
beginBlock, endBlock => index ← EncodeToken[reader, writer, token];
beginBody => { index ← EncodeBody[reader, writer, token];
IF tick#NIL THEN tick[] };
ENDCASE => ERROR;
comment, insertFile => index ← EncodeToken[reader, writer, token];
eof => EXIT;
ENDCASE => ERROR;
ENDLOOP;
};
ReaderForWritten: PROC[file: ROPE] RETURNS[Reader] = {
rope: ROPE = RopeIO.FromFile[file];
rr: RopeReader.Ref = RopeReader.Create[];
RopeReader.SetPosition[rr, rope, 0];
RETURN[CreateReader["Written", rr]];
};
ReaderForRope: PROC[rope: ROPE] RETURNS[Reader] = {
rr: RopeReader.Ref = RopeReader.Create[];
RopeReader.SetPosition[rr, rope, 0];
RETURN[CreateReader["Written", rr]];
};
RopeToMaster: PUBLIC PROC[rope: ROPE, masterName: ROPE] = {
reader: Reader = ReaderForRope[rope];
writer: Writer = OpenWriter[masterName, "Xerox"];
WriteEncoded[reader, writer];
CloseReader[reader];
CloseWriter[writer];
};
EncodeToken: PROC[reader: Reader, writer: Writer, token: Token] RETURNS[INT] = {
SELECT token.type FROM
op => writer.PutOp[token.op];
number => writer.PutInt[token.number];
int => { i: INT = reader.GetInt[token]; writer.PutInt[i] };
rational => { r: Rational = reader.GetRational[token]; writer.PutRational[r] };
real => { r: REAL = reader.GetReal[token]; writer.PutReal[r] };
identifier, string, comment, insertFile, largeVec => {
rope: ROPE = reader.GetRope[token]; writer.PutRope[token.type, rope] };
ENDCASE => ERROR;
RETURN[token.next];
};
SkipToken: PROC[reader: Reader, token: Token] RETURNS[INT] = {
IF token.type=eof THEN ERROR
ELSE RETURN[token.next];
};
EncodeBody: PROC[reader: Reader, writer: Writer, begin: Token] RETURNS[INT] = {
index: INT ← begin.next;
IF begin.op#beginBody THEN ERROR;
writer.PutOp[beginBody];
DO token: Token = reader.GetToken[index];
SELECT token.op FROM
beginBody => index ← EncodeBodyAndOp[reader, writer, token];
endBody => { index ← token.next; EXIT };
beginVec => index ← EncodeVec[reader, writer, token];
endVec => ERROR;
ENDCASE => IF BodyOp[token]
THEN index ← EncodeOpAndBody[reader, writer, token]
ELSE index ← EncodeToken[reader, writer, token];
ENDLOOP;
writer.PutOp[endBody];
RETURN[index];
};
EncodeVec: PROC[reader: Reader, writer: Writer, begin: Token] RETURNS[INT] = {
index: INT ← begin.next;
k: INT ← 0; -- number of elements
IF begin.op#beginVec THEN ERROR;
DO token: Token = reader.GetToken[index];
SELECT token.op FROM
beginBody => index ← EncodeBodyAndOp[reader, writer, token];
endBody => ERROR;
beginVec => index ← EncodeVec[reader, writer, token];
comma => { index ← token.next; k ← k+1 };
endVec => { index ← token.next; EXIT };
ENDCASE => IF BodyOp[token]
THEN index ← EncodeOpAndBody[reader, writer, token]
ELSE index ← EncodeToken[reader, writer, token];
IF k=0 AND token.type#comment THEN k ← 1;
ENDLOOP;
writer.PutInt[k];
writer.PutOp[makevec];
RETURN[index];
};
EncodeBodyAndOp: PROC[reader: Reader, writer: Writer, begin: Token] RETURNS[INT] = {
after: INT = SkipBody[reader, begin];
token: Token = reader.GetToken[after];
IF BodyOp[token] THEN {
writer.PutOp[token.op];
IF EncodeBody[reader, writer, begin]#after THEN ERROR;
RETURN[token.next];
}
ELSE ERROR;
};
EncodeOpAndBody: PROC[reader: Reader, writer: Writer, begin: Token] RETURNS[INT] = {
IF BodyOp[begin] THEN {
token: Token = reader.GetToken[begin.next];
writer.PutOp[begin.op];
RETURN[EncodeBody[reader, writer, token]];
}
ELSE ERROR;
};
SkipBody: PROC[reader: Reader, begin: Token] RETURNS[INT] = {
index: INT ← begin.next;
IF begin.op#beginBody THEN ERROR;
DO token: Token = reader.GetToken[index];
IF token.type=eof THEN ERROR;
SELECT token.op FROM
beginBody => index ← SkipBody[reader, token];
endBody => RETURN[token.next];
beginVec => index ← SkipVec[reader, token];
comma => ERROR;
endVec => ERROR;
ENDCASE => index ← SkipToken[reader, token];
ENDLOOP;
};
SkipVec: PROC[reader: Reader, begin: Token] RETURNS[INT] = {
index: INT ← begin.next;
IF begin.op#beginVec THEN ERROR;
DO token: Token = reader.GetToken[index];
IF token.type=eof THEN ERROR;
SELECT token.op FROM
beginBody => index ← SkipBody[reader, token];
endBody => ERROR;
beginVec => index ← SkipVec[reader, token];
endVec => RETURN[token.next];
ENDCASE => index ← SkipToken[reader, token];
ENDLOOP;
};
ReplaceExtension: PROC[name, newExtension: ROPE] RETURNS[ROPE] = {
length: INT = name.Length[];
lastDot: INT ← length;
FOR i: INT DECREASING IN[0..length) DO
IF name.Fetch[i]='. THEN { lastDot ← i; EXIT };
REPEAT FINISHED => ERROR;
ENDLOOP;
RETURN[name.Replace[start: lastDot+1, with: newExtension]];
};
ToDecimal: PROC[fromName: ROPE] = {
toName: ROPE = ReplaceExtension[fromName, "Decimal"];
in: STREAM = FileIO.Open[fromName];
out: STREAM = FileIO.Open[toName, overwrite];
UNTIL in.EndOf[] DO
c: CHAR = in.GetChar[];
out.Put[IO.int[LOOPHOLE[c, CARDINAL]], IO.char[' ]];
ENDLOOP;
in.Close[]; out.Close[];
};
ToOctal: PROC[fromName: ROPE] = {
toName: ROPE = ReplaceExtension[fromName, "Octal"];
in: STREAM = FileIO.Open[fromName];
out: STREAM = FileIO.Open[toName, overwrite];
UNTIL in.EndOf[] DO
c: CHAR = in.GetChar[];
out.PutF["%03b ", IO.int[LOOPHOLE[c, CARDINAL]]];
ENDLOOP;
in.Close[]; out.Close[];
};
END.