DIRECTORY Alloc: TYPE USING [Bounds], Ascii: TYPE USING [ControlZ], ComData: TYPE USING [ bodyIndex, nErrors, nWarnings, switches, table, textIndex], CompilerUtil: TYPE USING [ AcquireStream, AcquireTable, ReleaseStream, ReleaseTable], ConvertUnsafe: TYPE USING [SubString, SubStringToRope], ErrorTable: TYPE USING [CSRptr], IO: TYPE USING [card, char, CR, GetChar, EndOf, int, Put, PutChar, PutF, PutRope, rope, SetIndex, SP, STREAM], LiteralOps: TYPE USING [Value, StringValue, WordIndex], Log: TYPE USING [ErrorCode], Rope: TYPE USING [ROPE], Symbols: TYPE USING [seType, bodyType, Name, ISEIndex, nullName, ISENull, BTNull], SymbolOps: TYPE USING [SubStringForName], Tree: TYPE USING [Base, Index, Link, NodeName, Scan, Null, treeType], TreeOps: TYPE USING [ScanList]; LogPack: PROGRAM IMPORTS Alloc, CompilerUtil, ConvertUnsafe, IO, LiteralOps, SymbolOps, TreeOps, dataPtr: ComData EXPORTS Log = { OPEN Symbols; ErrorCode: TYPE = Log.ErrorCode; FileByteIndex: TYPE = INT; Error: PUBLIC PROC [code: ErrorCode] = { Enter[]; ErrorLog[code, TRUE]; Exit[]}; ErrorHti: PUBLIC PROC [code: ErrorCode, name: Name] = { ErrorTree[code, [hash[name]]]}; ErrorN: PUBLIC PROC [code: ErrorCode, n: INTEGER] = { Enter[]; IO.Put[errorStream, IO.int[n]]; IO.PutChar[errorStream, ' ]; ErrorLog[code, TRUE]; Exit[]}; ErrorNode: PUBLIC PROC [code: ErrorCode, node: Tree.Index] = { ErrorTree[code, [subtree[node]]]}; ErrorSei: PUBLIC PROC [code: ErrorCode, sei: ISEIndex] = { ErrorTree[code, [symbol[sei]]]}; ErrorTree: PUBLIC PROC [code: ErrorCode, t: Tree.Link] = { Enter[]; PrintOperand[t, 0, 0]; IO.PutRope[errorStream, " "]; ErrorLog[code, TRUE]; Exit[]}; Warning: PUBLIC PROC [code: ErrorCode] = { IF dataPtr.switches['w] THEN { Enter[]; IO.PutRope[errorStream, "warning: "]; ErrorLog[code, FALSE]; Exit[]}}; WarningNode: PUBLIC PROC [code: ErrorCode, node: Tree.Index] = { WarningTree[code, [subtree[node]]]}; WarningSei: PUBLIC PROC [code: ErrorCode, sei: ISEIndex] = { WarningTree[code, [symbol[sei]]]}; WarningSubString: PUBLIC PROC [code: ErrorCode, s: ConvertUnsafe.SubString] = { IF dataPtr.switches['w] THEN { Enter[]; IO.Put[errorStream, IO.rope[ConvertUnsafe.SubStringToRope[s]], IO.char[' ]]; ErrorLog[code, FALSE]; Exit[]}}; WarningRope: PUBLIC PROC [code: ErrorCode, s: Rope.ROPE] = { IF dataPtr.switches['w] THEN { Enter[]; IO.Put[errorStream, IO.rope[s], IO.char[' ]]; ErrorLog[code, FALSE]; Exit[]}}; WarningTree: PUBLIC PROC [code: ErrorCode, t: Tree.Link] = { IF dataPtr.switches['w] THEN { Enter[]; IO.PutRope[errorStream, "warning: "]; PrintOperand[t, 0, 0]; IO.PutRope[errorStream, " "]; ErrorLog[code, FALSE]; Exit[]}}; PrintTextLine: PROC [i: CARDINAL] = { start, lineIndex: FileByteIndex; char: CHAR; n: [1..100]; sourceStream: IO.STREAM _ CompilerUtil.AcquireStream[source]; start _ lineIndex _ i; FOR n IN [1..100] UNTIL lineIndex = 0 DO lineIndex _ lineIndex - 1; IO.SetIndex[sourceStream, lineIndex]; IF IO.GetChar[sourceStream] = IO.CR THEN EXIT; start _ lineIndex; ENDLOOP; IO.SetIndex[sourceStream, start]; FOR n IN [1..100] WHILE ~IO.EndOf[sourceStream] DO SELECT (char _ IO.GetChar[sourceStream]) FROM IO.CR, Ascii.ControlZ => EXIT; ENDCASE => IO.PutChar[errorStream, char]; ENDLOOP; NewLine[]; CompilerUtil.ReleaseStream[source]}; errorStream: IO.STREAM _ NIL; CSRp: ErrorTable.CSRptr; ss: ConvertUnsafe.SubString _ [NIL, 0, 0]; Enter: PROC = { errorStream _ CompilerUtil.AcquireStream[log]; CSRp _ CompilerUtil.AcquireTable[error]; ss.base _ @CSRp[CSRp.stringOffset]}; Exit: PROC = { CompilerUtil.ReleaseTable[error]; CompilerUtil.ReleaseStream[log]; errorStream _ NIL}; WriteErrorString: PROC [n: ErrorCode] = { ss.offset _ CSRp.ErrorMessages[n].offset; ss.length _ CSRp.ErrorMessages[n].length; IO.PutRope[errorStream, ConvertUnsafe.SubStringToRope[ss]]}; WriteName: PROC [name: Name] = { IF name = nullName THEN IO.PutRope[errorStream, "(anonymous)"] ELSE { s: ConvertUnsafe.SubString; s _ SymbolOps.SubStringForName[name]; IO.PutRope[errorStream, ConvertUnsafe.SubStringToRope[s]]}}; WriteSei: PROC [sei: ISEIndex] = { WriteName[IF sei = ISENull THEN nullName ELSE ((dataPtr.table).Bounds[seType].base)[sei].hash]}; WriteLti: PROC [t: Tree.Link.literal] = { WITH t.index SELECT FROM word => IO.Put[errorStream, IO.int[LiteralOps.Value[lti]]]; string => { s: LONG STRING = LiteralOps.StringValue[sti]; IO.PutChar[errorStream, '"]; FOR i: CARDINAL IN [0..s.length) DO IO.PutChar[errorStream, s[i]] ENDLOOP; IO.PutChar[errorStream, '"]}; ENDCASE}; WriteOpName: PROC[n: Tree.NodeName[assignx..uparrow]] = { ss.offset _ CSRp.OpName[n].offset; ss.length _ CSRp.OpName[n].length; IO.PutRope[errorStream, ConvertUnsafe.SubStringToRope[ss]]}; OpPrec: ARRAY Tree.NodeName[assignx..uparrow] OF CARDINAL = [ 1, 1, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 7, 10, 10, 10, 1, 4, 8, 9, 10]; WriteFnName: PROC[n: Tree.NodeName[min..nil]] = { ss.offset _ CSRp.FnName[n].offset; ss.length _ CSRp.FnName[n].length; IO.PutRope[errorStream, ConvertUnsafe.SubStringToRope[ss]]}; Cutoff: CARDINAL = 3; PrintOperand: PROC [t: Tree.Link, tPrec, depth: CARDINAL] = { IF t = Tree.Null THEN RETURN; WITH e: t SELECT FROM hash => WriteName[e.index]; symbol => WriteSei[e.index]; literal => WriteLti[e]; subtree => { node: Tree.Index = e.index; tb: Tree.Base _ (dataPtr.table).Bounds[Tree.treeType].base; op: Tree.NodeName = tb[node].name; IF depth > Cutoff THEN {IO.PutRope[errorStream, "..."]; RETURN}; SELECT op FROM syserror, syserrorx => IO.PutRope[errorStream, "ERROR"]; lengthen, --abs,-- IN [first..succ], IN [length..base], nil => { PrintOperand[tb[node].son[1], OpPrec[dot], depth+1]; IO.PutChar[errorStream, '.]; WriteFnName[op]}; ord => { -- pending reordering of node names PrintOperand[tb[node].son[1], OpPrec[dot], depth+1]; IO.PutRope[errorStream, ".ORD"]}; IN [call .. rowcons], stringinit, IN [min .. nil], val => { OPEN tb[node]; args: Tree.Link; SELECT op FROM IN [call .. rowcons], stringinit => { IF son[1] # Tree.Null THEN PrintOperand[son[1], 0, depth]; args _ son[2]}; IN [min .. nil] => {WriteFnName[op]; args _ son[1]}; val => {IO.PutRope[errorStream, "VAL"]; args _ son[1]}; -- until reordered ENDCASE; IF args # Tree.Null OR op # nil THEN { IO.PutChar[errorStream, '[]; IF depth = Cutoff AND args.tag = subtree THEN IO.PutRope[errorStream, "..."] ELSE PrintOperandList[args, depth+1]; IF op IN [call .. joinx] AND nSons > 2 THEN IO.PutRope[errorStream, " !..."]; IO.PutChar[errorStream, ']]}}; IN [assignx .. uparrow] => { OPEN tb[node]; prec: CARDINAL = OpPrec[op]; IF prec < tPrec THEN IO.PutChar[errorStream, '(]; SELECT op FROM IN [create .. addr] => {WriteOpName[op]; PrintOperand[son[1], prec, depth]}; IN [assignx .. dollar] => { PrintOperand[son[1], prec, depth+1]; WriteOpName[op]; PrintOperand[son[2], prec+1, depth+1]}; uparrow => { PrintOperand[son[1], prec, depth]; IO.PutChar[errorStream, '^]}; ENDCASE => IO.PutChar[errorStream, '?]; IF prec < tPrec THEN IO.PutChar[errorStream, ')]}; IN [intOO .. intCC] => { OPEN tb[node]; IO.PutChar[errorStream, IF op = intOO OR op = intOC THEN '( ELSE '[]; PrintOperand[son[1], 0, depth]; IO.PutRope[errorStream, ".."]; PrintOperand[son[2], 0, depth]; IO.PutChar[errorStream, IF op = intOO OR op = intCO THEN ') ELSE ']]}; clit => { c: CHAR = VAL[LiteralOps.Value[ LiteralOps.WordIndex[NARROW[tb[node].son[1], Tree.Link.literal].index]]]; IO.PutChar[errorStream, '']; IF c >= IO.SP THEN IO.PutChar[errorStream, c] ELSE {IO.PutF[errorStream, "\\%3b", IO.card[c.ORD]]}}; new, cons, listcons => { IF tb[node].son[1] # Tree.Null THEN { PrintOperand[tb[node].son[1], OpPrec[dot], depth+1]; IO.PutChar[errorStream, '.]}; IO.PutRope[errorStream, SELECT op FROM new => "NEW", cons => "CONS", ENDCASE => "LIST"]; IO.PutChar[errorStream, '[]; IF depth = Cutoff THEN IO.PutRope[errorStream, "..."] ELSE PrintOperandList[tb[node].son[2], depth+1]; IO.PutChar[errorStream, ']]}; atom => { IO.PutChar[errorStream, '$]; WITH e1: tb[node].son[1] SELECT FROM hash => WriteName[e1.index]; ENDCASE}; llit, IN [cast .. openx], thread => PrintOperand[tb[node].son[1], tPrec, depth]; item => PrintOperand[tb[node].son[2], tPrec, depth]; ENDCASE => IO.PutRope[errorStream, "..."]}; ENDCASE}; PrintOperandList: PROC [t: Tree.Link, depth: CARDINAL] = { firstSon: BOOL _ TRUE; PrintItem: Tree.Scan = { IF ~firstSon THEN IO.PutRope[errorStream, ", "]; firstSon _ FALSE; IF t # Tree.Null THEN PrintOperand[t, 0, depth]}; TreeOps.ScanList[t, PrintItem]}; NewLine: PROC = {IO.PutChar[errorStream, IO.CR]}; ErrorLog: PROC [code: ErrorCode, error: BOOL] = { bodyId: ISEIndex; index: CARDINAL = dataPtr.textIndex; WriteErrorString[code]; IF error THEN dataPtr.nErrors _ dataPtr.nErrors + 1 ELSE dataPtr.nWarnings _ dataPtr.nWarnings + 1; IO.PutRope[errorStream, ", at "]; IF dataPtr.bodyIndex # BTNull THEN { bodyId _ ((dataPtr.table).Bounds[Symbols.bodyType]).base[dataPtr.bodyIndex].id; IF bodyId # ISENull THEN WriteSei[bodyId]}; IF index # CARDINAL.LAST THEN IO.PutF[errorStream, "[%d]", IO.card[index]]; IO.PutChar[errorStream, ':]; NewLine[]; IF index # LAST[CARDINAL] THEN PrintTextLine[index] ELSE {IO.PutRope[errorStream, "(source from inline)"]; NewLine[]}; NewLine[]}; }. „file LogPack.Mesa last modified by Satterthwaite, February 17, 1983 5:09 pm Last Edited by: Maxwell, August 11, 1983 8:32 am public interface source printing errorStream, CSRp and desc.base are set by Enter tables used for printing trees OpName: ARRAY Tree.NodeName[assignx..uparrow] OF STRING _ [ "_", " OR ", " AND ", "=", "#", "<", ">=", ">", "<=", " IN ", " ~IN ", "+", "-", "*", "/", " MOD ", ".", ".", ".", " NEW ", "~", "-", "@", "^"]; FnName: ARRAY Tree.NodeName[min..loophole] OF STRING _ [ "MIN", "MAX", "LONG", "ABS", "ALL", "SIZE", "FIRST", "LAST", "DESCRIPTOR", "LENGTH", "BASE", "LOOPHOLE", "NIL"]; error-handling routines Ê G˜Jšœ™Jšœ9™9J™0J™šÏk ˜ Jšœœœ ˜Jšœœœ ˜šœ œœ˜J˜;—šœœœ˜J˜:—Jšœœœ˜7Jšœ œœ ˜ Jš œœœœDœœ˜nJšœ œœ!˜7Jšœœœ ˜Jšœœœœ˜Jšœ œœ?˜RJšœ œœ˜)Jšœœœ5˜EJšœ œœ ˜J˜—šœ ˜š˜Jšœ$œ!˜GJ˜—Jšœ˜Jšœ ˜ J˜Jšœ œ˜ Jšœœœ˜J˜Jšœ™˜šÏnœœœ˜(Jšœœ ˜'J˜—šžœœœ"˜7J˜J˜—šžœœœœ˜5J˜Jšœœ œ˜=Jšœœ˜J˜J˜—šž œœœ(˜>J˜"J˜—šžœœœ%˜:J˜ J˜—šž œœœ$˜:J˜Jšœ6˜6Jšœœ˜J˜J˜—šžœœœ˜*šœœ˜J˜Jšœ%˜%Jšœœ˜J˜ J˜——šž œœœ(˜@J˜$J˜—šž œœœ%˜