DIRECTORY Ascii, CardTab, C2CBasics, C2CNames, C2CTarget, IntCodeDefs, IntCodeUtils, IO, RefText, Rope, SymTab; C2CNamesImpl: CEDAR PROGRAM IMPORTS Ascii, CardTab, C2CBasics, C2CTarget, IntCodeUtils, IO, RefText, Rope, SymTab EXPORTS C2CNames = BEGIN OPEN C2CBasics, IntCodeDefs; ROPE: TYPE = Rope.ROPE; caseForReservedWords: BOOL = FALSE; caseForIdentifiers: BOOL = TRUE; reservedWords: SymTab.Ref ¬ SymTab.Create[case: caseForReservedWords]; warningTheProgramNameWillBeWrong: SIGNAL = CODE; prefixForNamedProc: ROPE ¬ "P"; <> prefixForMentionedProc: ROPE ¬ "Q"; <> prefixForUnNamedProc: ROPE ¬ "L"; <> prefixForNamedVar: ROPE ¬ "v"; <> prefixForMentionedVar: ROPE ¬ "w"; <> prefixForUnNamedVar: ROPE ¬ "c"; <> Environment: TYPE = REF EnvRep; EnvRep: TYPE = RECORD [ table: SymTab.Ref, fiddleCnt: INT ¬ 0, localCnt: INT ¬ 0, externProcTab: IntCodeUtils.IdTab, labIdToNameTable: IntCodeUtils.IdTab ¬ NIL, varIdToNameTable: IntCodeUtils.IdTab ¬ NIL, macroNames: SymTab.Ref ¬ NIL, programName: ROPE ¬ NIL ]; environment: Environment; AssociateNames: PUBLIC PROC [names, labels: CardTab.Ref, externProcs: SymTab.Ref] = { env: Environment ¬ environment; EachLabel: CardTab.EachPairAction = { WITH val SELECT FROM r: ROPE => { IF key=0 THEN NameThisProgram[r]; IF externProcs#NIL THEN { name: ROPE ¬ NARROW[SymTab.Fetch[externProcs, r].val]; IF name#NIL THEN { NameThisExternalProcedure[LOOPHOLE[key], name]; [] ¬ IntCodeUtils.Store[env.externProcTab, LOOPHOLE[key], name]; RETURN; }; }; NameThisProcedure[env, LOOPHOLE[key], r]; }; ENDCASE => {}; }; EachName: CardTab.EachPairAction = { WITH val SELECT FROM r: ROPE => NameThisVariable[env, LOOPHOLE[key], r]; ENDCASE => {}; }; PreprocessMachineCodes: PROC [machineCodeNode: MachineCodeNode] = { IF Rope.Length[machineCodeNode.bytes]>0 AND Rope.Fetch[machineCodeNode.bytes, 0]='^ THEN { IF Rope.Equal["^ExternalNames", Rope.Substr[machineCodeNode.bytes, 0, 14], FALSE] THEN { line: REF TEXT ¬ RefText.ObtainScratch[200]; stream: IO.STREAM ¬ IO.RIS[machineCodeNode.bytes]; WhiteText: PROC [t: REF TEXT] RETURNS [BOOL] = { IF t=NIL THEN RETURN [TRUE]; RETURN [RefText.SkipOver[line, 0, " \l\r"]>=t.length]; }; ScanOneLine: PROC [line: REF TEXT] = { ENABLE { IO.Error => GOTO syntaxError; IO.EndOfStream => GOTO eof; }; cedarName, cName: Rope.ROPE; lineStream: IO.STREAM ¬ IO.TIS[line]; cedarName ¬ IO.GetID[lineStream]; [cName, ] ¬ IO.GetTokenRope[lineStream, BreakCName ! IO.EndOfStream => CONTINUE]; IF Rope.IsEmpty[cName] THEN cName ¬ cedarName; [] ¬ SymTab.Insert[externProcs, cedarName, cName]; EXITS syntaxError => C2CBasics.FatalError["^ExternalNames machine code"]; eof => NULL; }; IF externProcs=NIL THEN externProcs ¬ SymTab.Create[]; IF handledMachineCodes=NIL THEN handledMachineCodes ¬ SymTab.Create[]; IF ~SymTab.Insert[handledMachineCodes, machineCodeNode.bytes, $x] THEN { C2CBasics.FatalError["^ExternalNames machine code used twice"]; }; [] ¬ IO.GetLine[stream, line]; DO line ¬ IO.GetLine[stream, line ! IO.EndOfStream => {RefText.ReleaseScratch[line]; GOTO done}]; IF ~WhiteText[line] THEN ScanOneLine[line]; ENDLOOP; EXITS done => {} }; } }; FindNamesMachineCodes: IntCodeUtils.Visitor = { WITH node SELECT FROM machineCodeNode: MachineCodeNode => { PreprocessMachineCodes[machineCodeNode]; }; ENDCASE => {}; IntCodeUtils.MapNode[node, FindNamesMachineCodes]; RETURN [node]; }; handledMachineCodes: SymTab.Ref ¬ NIL; [] ¬ FindNamesMachineCodes[C2CBasics.rootNode]; IF labels#NIL THEN [] ¬ CardTab.Pairs[labels, EachLabel]; IF names#NIL THEN [] ¬ CardTab.Pairs[names, EachName]; }; BreakCName: IO.BreakProc = { RETURN [SELECT char FROM Ascii.SP, Ascii.TAB, ',, ':, '; => sepr, ENDCASE => other] }; ScanExterns: PUBLIC PROC [stream: IO.STREAM] RETURNS [externs: SymTab.Ref] = { error: BOOL ¬ FALSE; initialized: BOOL ¬ FALSE; line, buffer: REF TEXT; lineNo: INT ¬ 0; ScanLine: PROC [line: REF TEXT] = { ENABLE { IO.Error => GOTO oops; IO.EndOfStream => GOTO eof; }; name1, name2: Rope.ROPE; token: REF TEXT ¬ NIL; st: IO.STREAM ¬ IO.TIS[line]; [] ¬ IO.SkipWhitespace[st]; SELECT IO.PeekChar[st] FROM '- => RETURN; --comment line IN ['a..'z], IN ['A..'Z] => name1 ¬ IO.GetID[st]; ENDCASE => {GOTO oops}; --error [token, ] ¬ IO.GetToken[st, BreakCName, buffer ! IO.EndOfStream => CONTINUE]; name2 ¬ Rope.FromRefText[token]; IF Rope.IsEmpty[name2] THEN name2 ¬ name1; IF initialized THEN { [] ¬ SymTab.Insert[externs, name1, name2]; } ELSE { IF Rope.Equal[name1, "extern", FALSE] AND Rope.Equal[name2, "procs", FALSE] THEN initialized ¬ TRUE ELSE C2CBasics.FatalError["externProcs file missing header"] }; EXITS oops => C2CBasics.FatalError[IO.PutFR1["externProcs file error on line %g", IO.int[lineNo]]]; eof => NULL; }; IF stream#NIL THEN { line ¬ RefText.ObtainScratch[100]; buffer ¬ RefText.ObtainScratch[100]; externs ¬ SymTab.Create[5]; DO lineNo ¬ lineNo+1; line ¬ IO.GetLine[stream, line ! IO.EndOfStream => { RefText.ReleaseScratch[line]; RefText.ReleaseScratch[buffer]; GOTO done } ]; ScanLine[line]; ENDLOOP; }; EXITS done => NULL; }; IsExtern: PUBLIC PROC [id: LogicalId] RETURNS [BOOL] = { IF IntCodeUtils.Fetch[environment.externProcTab, id]#NIL THEN RETURN [TRUE]; RETURN [FALSE]; }; Include: PROC [proposal: ROPE, env: Environment] RETURNS [done: BOOL] = INLINE { IF SymTab.Fetch[reservedWords, proposal].found THEN RETURN [FALSE]; done ¬ SymTab.Insert[env.table, proposal, $included] }; TryName: PUBLIC PROC [try: ROPE] RETURNS [ROPE] = { RETURN [FinishUpName[environment, try, FALSE]]; }; InternalName: PUBLIC PROC [class: ROPE] RETURNS [ROPE] = { env: Environment ¬ environment; IF Rope.IsEmpty[class] THEN class ¬ "x"; DO try: ROPE ¬ IO.PutFR["%g%g", IO.rope[class], IO.int[env.localCnt ¬ env.localCnt+1]]; try ¬ Rope.Flatten[try]; IF Include[try, env] THEN RETURN [try] ENDLOOP; }; FinishUpName: PROC [env: Environment, base: ROPE, fiddled: BOOL] RETURNS [ROPE] = { base ¬ Rope.Flatten[base]; IF ~fiddled AND Include[base, env] THEN RETURN [base]; DO try: ROPE ¬ IO.PutFR["%g_ff%g", IO.rope[base], IO.int[env.fiddleCnt ¬ env.fiddleCnt+1]]; try ¬ Rope.Flatten[try]; IF Include[try, env] THEN RETURN [try] ENDLOOP; }; Name: PROC [number: INT, prefix: ROPE, base: ROPE¬NIL] RETURNS [name: ROPE] = { name ¬ IF number<0 THEN IO.PutFR["%g0%g", IO.rope[prefix], IO.int[-number]] ELSE IO.PutFR["%g%g", IO.rope[prefix], IO.int[number]]; IF base#NIL THEN name ¬ Rope.Cat[base, "_", name]; }; NameThisVariable: PROC [env: Environment, id: VariableId, name: ROPE] = { fiddled: BOOL ¬ FALSE; prefix: ROPE; IF id=nullVariableId THEN CantHappen; WITH IntCodeUtils.Fetch[env.varIdToNameTable, id] SELECT FROM r: ROPE => CantHappen; ENDCASE => NULL; IF Rope.IsEmpty[name] THEN { prefix ¬ prefixForMentionedVar; name ¬ "noName"; } ELSE { prefix ¬ prefixForNamedVar; [name, fiddled] ¬ Identifier[name]; }; name ¬ FinishUpName[env, Name[id, prefix, name], fiddled]; [] ¬ IntCodeUtils.Store[env.varIdToNameTable, id, name]; }; NameThisProcedure: PROC [env: Environment, id: LogicalId, name: ROPE] = { fiddled: BOOL ¬ FALSE; prefix: ROPE; IF id=nullLogicalId THEN CantHappen; WITH IntCodeUtils.Fetch[env.labIdToNameTable, id] SELECT FROM r: ROPE => CantHappen; ENDCASE => NULL; IF Rope.IsEmpty[name] THEN { prefix ¬ prefixForMentionedProc; name ¬ "NoName"; } ELSE { prefix ¬ prefixForNamedProc; [name, fiddled] ¬ Identifier[name]; }; name ¬ FinishUpName[env, Name[id, prefix, name], fiddled]; [] ¬ IntCodeUtils.Store[env.labIdToNameTable, id, name]; }; NameThisProgram: PROC [proposal: ROPE ¬ NIL] = { env: Environment ¬ environment; fiddled: BOOL; IF env.programName#NIL THEN CantHappen; IF proposal=NIL THEN proposal ¬ "module"; [env.programName, fiddled] ¬ Identifier[proposal]; IF fiddled THEN { SIGNAL warningTheProgramNameWillBeWrong }; }; NameThisExternalProcedure: PROC [id: LogicalId, name: ROPE] = { same: ROPE; env: Environment ¬ environment; IF id=nullLogicalId THEN CantHappen; WITH IntCodeUtils.Fetch[env.labIdToNameTable, id] SELECT FROM r: ROPE => C2CBasics.FatalError[Rope.Concat["failed to name external proc ", name]]; ENDCASE => NULL; IF Rope.IsEmpty[name] THEN C2CBasics.FatalError["external proc with empty name"]; same ¬ TryName[name]; IF NOT Rope.Equal[name, same] THEN C2CBasics.FatalError[Rope.Cat["external proc ", name, " used for multiple procedures"]]; [] ¬ IntCodeUtils.Insert[env.labIdToNameTable, id, name]; }; VarName: PUBLIC PROC [id: VariableId, class: ROPE] RETURNS [ROPE] = { env: Environment ¬ environment; IF id=nullVariableId THEN CantHappen; WITH IntCodeUtils.Fetch[env.varIdToNameTable, id] SELECT FROM r: ROPE => RETURN [r]; ENDCASE => NULL; BEGIN name: ROPE; IF Rope.IsEmpty[class] THEN class ¬ "noName"; name ¬ FinishUpName[env, Name[id, prefixForUnNamedVar, class], FALSE]; [] ¬ IntCodeUtils.Store[env.varIdToNameTable, id, name]; RETURN [name] END; }; LabName: PUBLIC PROC [id: LogicalId, class: ROPE] RETURNS [ROPE] = { env: Environment ¬ environment; IF id=nullLogicalId THEN CantHappen; WITH IntCodeUtils.Fetch[env.labIdToNameTable, id] SELECT FROM r: ROPE => RETURN [r]; ENDCASE => NULL; BEGIN name: ROPE; IF Rope.IsEmpty[class] THEN class ¬ "NoName"; name ¬ FinishUpName[env, Name[id, prefixForUnNamedProc, class], FALSE]; [] ¬ IntCodeUtils.Store[env.labIdToNameTable, id, name]; RETURN [name]; END; }; ProgramName: PUBLIC PROC [] RETURNS [name: ROPE] = { env: Environment ¬ environment; IF env.programName#NIL THEN RETURN [env.programName]; env.programName ¬ name ¬ TryName["module"]; }; maxLeng: INT ¬ C2CTarget.idMaxLength-12; --Offset for UnderScore+number+UnderScore+number Identifier: PROC [r: ROPE] RETURNS [id: ROPE, fiddled: BOOL¬FALSE] = { first: BOOL ¬ TRUE; Trans: Rope.TranslatorType = { retVal: CHAR; SELECT TRUE FROM Ascii.Letter[old] => retVal ¬ old; Ascii.Digit[old] AND ~first => retVal ¬ old; old='_ => retVal ¬ old; ENDCASE => {retVal ¬ 'x; fiddled¬TRUE}; first ¬ FALSE; RETURN[retVal]; }; IF Rope.Length[r]>maxLeng THEN { fiddled ¬ TRUE; r ¬ Rope.Substr[base: r, len: maxLeng]; }; id ¬ Rope.Translate[base: r, translator: Trans]; IF Rope.IsEmpty[id] THEN id ¬ "x"; }; PreDeclare: PUBLIC PROC [id: ROPE¬NIL] = { env: Environment ¬ environment; [] ¬ SymTab.Store[env.table, id, $x]; }; Reserve: PUBLIC PROC [r: ROPE] RETURNS [sameRope: ROPE] = { IF ~SymTab.Insert[reservedWords, r, r] THEN { SIGNAL C2CBasics.NotYetImpl; --keyword reserved repeatedly }; sameRope ¬ r; }; NewModule: PROC = { environment ¬ NEW[EnvRep ¬ [ table: SymTab.Create[case: caseForIdentifiers], externProcTab: IntCodeUtils.NewIdTab[], labIdToNameTable: IntCodeUtils.NewIdTab[], varIdToNameTable: IntCodeUtils.NewIdTab[], macroNames: SymTab.Create[] ]] }; C2CBasics.CallbackWhenC2CIsCalled[NewModule]; END. š C2CNamesImpl.mesa Copyright Σ 1988, 1989, 1990, 1991, 1992 by Xerox Corporation. All rights reserved. Christian Jacobi, February 23, 1988 10:03:41 am PST Christian Jacobi, October 5, 1990 10:35:35 am PDT Willie-s, September 24, 1991 6:08 pm PDT --read id number --Tries to register a name proposal for this environment --Returns done: succeeded registering exactly this name. --class is made up by c2c; no checking necessary --Guarantees uniqueness of name. Declares and returns the name --base is already short enough and a legal identifier. --fiddled: base is already fiddled --Fiddles more if necessary --concatenates a name from a number, a prefiz and a base --no registration yet The program name is not used unmodifyed as a c identifier. Since it is prepended with XR_Install_ or similar prefix, it is not reserved or checked for uniqueness. The procedure containing the program gets also a standard name like any other procedure. --no syntax checking on name... --it does NOT have a programmer defined name --it does NOT have a programmer defined name --No underscore. Removes funny characters, cut to maximum length. --fiddled if r#id for whatever reason Κ@–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ΟeœH™TKšœ4™4Kšœ2™2K™(—K˜šΟk ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšžœ˜Kšœ˜Kšœ˜Kšœ˜—K˜šΟn œžœž˜Kšžœ5žœ˜UKšžœ ˜—Kšž˜Kšžœ˜K˜Kšžœžœžœ˜Kšœžœžœ˜#Kšœžœžœ˜ KšœF˜FKšœ"žœžœ˜0K˜Kšœžœ)˜AKšœžœ6˜RKšœžœ1˜KKšœžœ˜-Kšœžœ˜1Kšœžœ˜0K˜Kšœ žœžœ˜šœžœžœ˜Kšœ˜Kšœ žœ˜Kšœ žœ˜Kšœ"˜"Kšœ'žœ˜+Kšœ'žœ˜+Kšœžœ˜Kšœ žœž˜K˜—K˜Kšœ˜K˜šŸœžœžœ:˜UKšœ˜šŸ œ˜%šžœžœž˜šœžœ˜ Kšžœžœ˜!šžœ žœžœ˜Kšœžœžœ#˜6šžœžœžœ˜Kšœžœ ˜/Kšœ+žœ ˜@Kšžœ˜K˜—K˜—Kšœžœ ˜)K˜—Kšžœ˜—Kšœ˜—šŸœ˜$šžœžœž˜Kšœžœžœ ˜3Kšžœ˜—Kšœ˜—šŸœžœ'˜Cšžœ&žœ)žœ˜ZšžœIžœžœ˜XKšœžœžœ˜,Kš œžœžœžœžœ˜2š Ÿ œžœžœžœžœžœ˜0Kš žœžœžœžœžœ˜Kšžœ0˜6K˜—šŸ œžœžœžœ˜&šžœ˜Kšžœ žœ ˜Kšžœžœ˜K˜—Kšœžœ˜Kš œ žœžœžœžœ˜%Kšœ žœ˜!Kšœ žœ'žœžœ˜QKšžœžœ˜.Kšœ2˜2šžœ˜KšœC˜CKšœžœ˜ —K˜—Kšžœ žœžœ˜6Kšžœžœžœ'˜Fšžœ@žœ˜HKšœ?˜?K˜—Kšœžœ˜šž˜Kšœžœžœ/žœ˜^Kšžœžœ˜+Kšžœ˜—Kšžœ ˜K˜—K˜—Kšœ˜—šŸœ˜/šžœžœž˜šœ%˜%Kšœ(˜(Kšœ˜—Kšžœ˜—Kšœ2˜2Kšžœ˜K˜—Kšœ"žœ˜&Kšœ/˜/Kšžœžœžœ'˜9Kšžœžœžœ%˜6Kšœ˜—K˜šŸ œžœ˜šžœžœž˜Kšœžœžœ˜)Kšžœ ˜—Kšœ˜K˜—š Ÿ œžœžœ žœžœžœ˜NKšœžœžœ˜Kšœ žœžœ˜Kšœžœžœ˜Kšœžœ˜K˜šŸœžœžœžœ˜#šžœ˜Kšžœ žœ˜Kšžœžœ˜K˜—Kšœžœ žœž œ˜/Kš œžœžœžœžœ˜KšΟc™Kšœžœ˜šžœžœž˜Kšœžœ ˜Kšžœ žœžœ ˜2Kšžœžœ ˜—Kšœ žœ#žœžœ˜MKšœ ˜ Kšžœžœ˜*šžœ ˜šžœ˜Kšœ*˜*K˜—šžœ˜šžœžœžœžœ˜LKšžœž˜Kšžœ8˜<—K˜——šžœ˜Kšœžœ-žœ˜]Kšœžœ˜ —K˜K˜—šžœžœžœ˜Kšœ"˜"Kšœ$˜$Kšœ˜šž˜Kšœ˜šœžœ˜šœžœ˜Kšœ>˜>Kšžœ˜ Kšœ˜—Kšœ˜—Kšœ˜Kšžœ˜—K˜—Kšžœ žœ˜K˜—K˜šŸœž œžœžœ˜8Kš žœ3žœžœžœžœ˜MKšžœžœ˜K˜—K˜š Ÿœžœ žœžœžœžœ˜PKš œ ™8Kš  œ *™8Kšžœ-žœžœžœ˜CKšœ4˜4K˜K˜—š Ÿœžœžœžœžœžœ˜3Kšžœ!žœ˜/Kšœ˜J™—š Ÿ œž œ žœžœžœ˜:Kš 0™0Kšœ˜Kšžœžœ ˜(šž˜Kš œžœžœžœžœ%˜TKšœ˜Kšžœžœžœ˜&Kšžœ˜—K˜—K˜š Ÿ œžœžœ žœžœžœ˜SKšœ" ™>Kš 6™6Kš #™#Kš ™Kšœ˜Kšžœ žœžœžœ˜6šž˜Kš œžœžœžœ žœ'˜XKšœ˜Kšžœžœžœ˜&Kšžœ˜—K˜K˜—šŸœžœ žœ žœžœžœžœ˜OKš 8™8Kš ™šœžœ ˜Kšžœžœžœžœ˜8Kšžœžœžœžœ˜7—Kšžœžœžœ"˜2K˜—K˜šŸœžœ*žœ˜IKšœ žœžœ žœ˜$Kšžœžœ ˜%šžœ.žœž˜=Kšœžœ˜Kšžœžœ˜—šžœ˜šžœ˜Kšœ˜Kšœ˜K˜—šžœ˜Kšœ˜Kšœ#˜#Kšœ˜——Kšœ:˜:Kšœ8˜8Kšœ˜K˜—šŸœžœ)žœ˜IKšœ žœžœ žœ˜$Kšžœžœ ˜$šžœ.žœž˜=Kšœžœ˜Kšžœžœ˜—šžœ˜šžœ˜Kšœ ˜ Kšœ˜Kšœ˜—šžœ˜Kšœ˜Kšœ#˜#Kšœ˜——Kšœ:˜:Kšœ8˜8Kšœ˜—K˜šŸœžœ ž œ˜0K™£K™XKšœ˜Kšœž˜Kšžœžœžœ ˜'Kšžœ žœžœ˜)Kšœ2˜2šžœ žœ˜Kšžœ!˜'K˜—K˜K˜—šŸœžœžœ˜?Kš ™Kšœžœ˜ Kšœ˜Kšžœžœ ˜$šžœ.žœž˜=KšœžœM˜TKšžœžœ˜—Kšžœžœ8˜RKšœ˜šžœžœžœ˜#KšœX˜X—Kšœ9˜9K˜K˜—š Ÿœžœžœžœžœžœ˜EKšœ˜Kšžœžœ ˜%šžœ.žœž˜=Kšœžœžœ˜Kšžœžœ˜—šž˜Kš ,™,Kšœž˜ Kšžœžœ˜-Kšœ?žœ˜FKšœ8˜8Kšžœ˜ Kšžœ˜—K˜—K˜š Ÿœžœžœžœžœžœ˜DKšœ˜Kšžœžœ ˜$šžœ.žœž˜=Kšœžœžœ˜Kšžœžœ˜—šž˜Kš ,™,Kšœž˜ Kšžœžœ˜-Kšœ@žœ˜GKšœ8˜8Kšžœ˜Kšžœ˜—K˜—K˜š Ÿ œžœžœžœžœ˜4Kšœ˜Kšžœžœžœžœ˜5Kšœ+˜+K˜K˜—Kšœ žœ 0˜YK˜š Ÿ œžœžœžœžœ ž œ˜FKš B™BKš œ#™%Kšœžœžœ˜šΠbnœ˜Kšœžœ˜ šžœžœž˜Kšœ"˜"Kšœžœ˜,Kšœ˜Kšžœžœ˜'—Kšœžœ˜Kšžœ ˜Kšœ˜—šžœžœ˜ Kšœ žœ˜Kšœ'˜'Kšœ˜—Kšœ0˜0Kšžœžœ ˜"Kšœ˜—K˜šŸ œžœžœžœ˜*Kšœ˜Kšœ%˜%K˜—K˜š Ÿœžœžœžœžœ žœ˜;šžœ%žœ˜-Kšžœ ˜:K˜—Kšœ ˜ K˜—K˜šŸ œžœ˜šœžœ ˜Kšœ/˜/Kšœ'˜'Kšœ*˜*Kšœ*˜*Kšœ˜Kšœ˜—Kšœ˜—K˜Kšœ-˜-Kšžœ˜K˜K˜—…—*<?