DIRECTORY AbstractTypesDef USING [ConstantNode, TypeNode], Convert USING [RopeFromCard, RopeFromInt], HashTable USING [Delete, Erase, Fetch, GetSize, Insert, Store, Value], IO USING [card, int, rope, PutF, PutFR, STREAM], ParserPrivateDef USING [], Rope USING [ROPE, Cat, Equal], RopeList USING [DAppend, Map, Cons], SiroccoPrivate USING [AquireState, CComponent, CComponentBody, CType, CTypeBody, DirectoryEntry, EndItAll, FunctionList, Handle, MakeUpName, TABLES, UnresolvedConstantTableEntry], ThreeC4Support USING [GetReportStream, GetSourceInfo], WartDef USING [Generic, identifierNode]; ParserPrivate2Impl: CEDAR PROGRAM IMPORTS Convert, HashTable, IO, Rope, RopeList, SiroccoPrivate, ThreeC4Support EXPORTS ParserPrivateDef ~ { OPEN SiroccoPrivate; ConstantNode: TYPE ~ AbstractTypesDef.ConstantNode; Generic: TYPE ~ WartDef.Generic; identifierNode: TYPE ~ WartDef.identifierNode; ROPE: TYPE ~ Rope.ROPE; TypeNode: TYPE ~ AbstractTypesDef.TypeNode; Value: TYPE ~ HashTable.Value; AddLocalConstantToRope: PUBLIC PROC [id: identifierNode, constantName: ROPE, constantType: ROPE, constantFunctions: LIST OF ROPE, inValue: ROPE, t1: TABLES] RETURNS [rope: ROPE, newConstantFunctions: LIST OF ROPE, t2: TABLES] ~ { info: REF DirectoryEntry; successful: BOOLEAN; temp: Value; [successful, temp] _ HashTable.Fetch[t1.localTable, id.text]; IF (NOT successful) THEN { rope _ Rope.Cat[inValue, id.text]; -- Enumeration Constant newConstantFunctions _ constantFunctions; t2 _ t1; RETURN; }; info _ NARROW[temp]; IF (NOT Rope.Equal[info.constant, ""]) THEN { rope _ Rope.Cat[inValue, info.constant]; newConstantFunctions _ AddFunctionList[info, constantFunctions]; [] _ AddFunctionToTable[info, constantFunctions, t1]; t2 _ t1; RETURN; }; [info.constant, info.functions, t1] _ NARROW[info.value, ConstantNode].procs.ConstantToRope[info.value, id.text, info.type, info.functions, info.constant, t1]; rope _ Rope.Cat[inValue, info.constant]; constantFunctions _ AddFunctionList[info, constantFunctions]; [] _ AddFunctionToTable[info, constantFunctions, t1]; RETURN[rope, constantFunctions, t1]; }; CanonicaliseLocalReferenceType: PUBLIC PROC [id: identifierNode, t1: TABLES] RETURNS [ cannonicalType: ROPE, typeTree: CType, t2: TABLES ] ~ { info: REF DirectoryEntry; overwrite: BOOLEAN; successful: BOOLEAN; temp: Value; type: CType; typeNode: TypeNode; h: SiroccoPrivate.Handle; ReturnCanonicalKey: PUBLIC PROC [id: identifierNode] RETURNS [key: ROPE] ~ { key _ Rope.Cat[h.programKey, id.text]; }; h _ SIGNAL SiroccoPrivate.AquireState[]; t2 _ t1; [successful, temp] _ HashTable.Fetch[t1.localTable, id.text]; IF (successful) THEN { info _ NARROW[temp]; [successful, temp] _ HashTable.Fetch[t1.typeTable, info.type]; IF (successful) THEN { type _ NARROW[temp]; cannonicalType _ info.type; typeTree _ type; RETURN; } ELSE [] _ SendError["Compiler Error"]; -- COMPILER ERROR } ELSE { [successful, temp] _ HashTable.Fetch[t1.unresolvedTypeTable, id.text]; IF (successful) THEN { typeNode _ NARROW[temp]; overwrite _ HashTable.Store[t1.unresolvedTypeTable, id.text, NIL]; IF (NOT overwrite) THEN { IF (typeNode = NIL) THEN [] _ SendError["Cyclic Dependency"] -- CYCLIC DEPENDENCY ELSE { [cannonicalType, typeTree, t1] _ typeNode.procs.CanonicaliseType[typeNode, t1]; IF (Rope.Equal[cannonicalType, "DEFAULT"]) THEN cannonicalType _ ReturnCanonicalKey[id]; successful _ HashTable.Insert[t1.typeTable, cannonicalType, typeTree]; info _ NEW[DirectoryEntry _ [type~cannonicalType, constant~"", functions~NIL, value~NIL]]; successful _ HashTable.Insert[t1.localTable, id.text, info]; IF (NOT successful) THEN [] _ SendError["Compiler Error"]; -- COMPILER ERROR (The Redeclaration should have been caught while entering stuff in the UnresolvedTypeTable) RETURN; } } ELSE [] _ SendError["Compiler Error"]; -- COMPILER ERROR } ELSE { [] _ SendError["Undeclared Identifier"] -- UNDECLARED ID; }; }; }; CheckIfEmpty: PUBLIC PROC [tables: TABLES] RETURNS [new: TABLES] ~ { IF (HashTable.GetSize[tables.workTable] # 0) THEN [] _ SendError["Missing Enumeration in Choice"]; new _ tables; }; ClearWorkTable: PUBLIC PROC [tables: TABLES] RETURNS [new: TABLES] ~ { HashTable.Erase[tables.workTable]; new _ tables; }; CompareClass: PUBLIC PROC [first: CType, second: Generic] RETURNS [comp: CComponent] ~ { IF (first.class # second) THEN [] _ SendError["Type Mismatch"]; comp _ first.children; }; Copy: PUBLIC PROC [t1: ROPE, t2: CType, t3: ConstantNode, t4: TABLES] RETURNS [ROPE, CType, ConstantNode, TABLES] ~ { RETURN[t1, t2, t3, t4]; }; CopyCComponent: PUBLIC PROC [in: CComponent] RETURNS [out: CComponent] ~ { out _ in; }; EnterNamesIntoWorkTable: PUBLIC PROC[type: CType, tables: TABLES] RETURNS [new: TABLES] ~ { list: CComponent _ type.children; HashTable.Erase[tables.workTable]; WHILE (list # NIL) DO IF (NOT HashTable.Insert[tables.workTable, list.name, ""]) THEN ERROR; -- Compiler ERROR list _ list.sibling; ENDLOOP; new _ tables; }; FetchFromTypeTable: PUBLIC PROC [t1: TABLES, key: ROPE] RETURNS [value: CType] ~ { successful: BOOLEAN; temp: Value; [successful, temp] _ HashTable.Fetch[t1.typeTable, key]; IF (NOT successful) THEN [] _ SendError["Compiler Error"]; --COMPILER ERROR value _ NARROW[temp]; }; FillWorkTable: PUBLIC PROC [type: CType, tables: TABLES] RETURNS [new: TABLES] ~ { list: CComponent _ type.children; length: INT _ -1; HashTable.Erase[tables.workTable]; WHILE (list # NIL) DO IF (NOT HashTable.Insert[tables.workTable, list.name, ""]) THEN ERROR; -- Compiler ERROR IF (NOT HashTable.Insert[tables.workTable, Convert.RopeFromInt[list.val],""]) THEN ERROR; -- Compiler ERROR list _ list.sibling; length _ length +1; ENDLOOP; WHILE (length >= 0) DO IF (NOT HashTable.Delete[tables.workTable, Convert.RopeFromInt[length]]) THEN [] _ SendError["Enumeration not Continous hence cannot be used as tag for Choice"]; length _ length - 1; ENDLOOP; new _ tables; }; GetConstantType: PUBLIC PROC [id: identifierNode, t1: TABLES] RETURNS [cannonicalType: ROPE, typeTree: CType, constant: ConstantNode, table : TABLES ] ~ { info: REF DirectoryEntry; successful, overwrite: BOOLEAN; temp: Value; value: REF UnresolvedConstantTableEntry; h: SiroccoPrivate.Handle; ReturnCanonicalKey: PUBLIC PROC [id: identifierNode] RETURNS [key: ROPE] ~ { key _ Rope.Cat[h.programKey, id.text]; }; h _ SIGNAL SiroccoPrivate.AquireState[]; table _ t1; [successful, temp] _ HashTable.Fetch[t1.localTable, id.text]; IF (successful) THEN { -- Already resolved info _ NARROW[temp]; [successful, temp] _ HashTable.Fetch[t1.typeTable, info.type]; IF (successful) THEN { -- Get Type cannonicalType _ info.type; typeTree _ NARROW[temp]; constant _ NARROW[info.value]; RETURN; } ELSE [] _ SendError["Compiler Error"]; -- COMPILER ERROR } ELSE { -- Unresolved [successful, temp] _ HashTable.Fetch[t1.unresolvedConstantTable, id.text]; IF (successful) THEN { -- Must be succesful if name was declared value _ NARROW[temp]; overwrite _ HashTable.Store[t1.unresolvedConstantTable, id.text, NIL]; IF (NOT overwrite) THEN { -- if new declaration IF (value = NIL) THEN [] _ SendError["Cyclic Dependancy"] -- already being processed: CYCLIC DEPENDANCY ELSE { [cannonicalType, typeTree, t1] _ NARROW[value.type, TypeNode].procs.CanonicaliseType[value.type, t1]; IF (Rope.Equal["DEFAULT", cannonicalType]) THEN cannonicalType _ ReturnCanonicalKey[id]; successful _ HashTable.Insert[t1.typeTable, cannonicalType, typeTree]; t1 _ NARROW[value.constant, ConstantNode].procs.Coerce[value.constant, typeTree, cannonicalType, t1]; info _ NEW[DirectoryEntry]; info.type _ cannonicalType; info.constant _ ""; info.functions _ NIL; [info.constant, info.functions, t1] _ NARROW[value.constant, ConstantNode].procs.ConstantToRope[value.constant, id.text, cannonicalType, info.functions, info.constant, t1]; info.value _ value.constant; constant _ NARROW[value.constant]; successful _ HashTable.Insert[t1.localTable, id.text, info]; RETURN; } } ELSE [] _ SendError["Compiler Error"]; -- COMPILER ERROR } ELSE { [] _ SendError["Undeclared Identifier"] -- UNDECLARED ID; }; }; }; GetCTypeFirstChild: PUBLIC PROC [first: CType] RETURNS [comp: CComponent] ~ { comp _ first.children; }; InsureErrorType: PUBLIC PROC [id: identifierNode, t: TABLES] RETURNS [new: TABLES] ~ { type: CType; cannonicalType: ROPE; constant: ConstantNode; [cannonicalType, type, constant, t] _ GetConstantType[id, t]; IF (type.class = error) THEN new _ t ELSE [] _ SendError["Identifier Not Decarled as an ERROR"]; -- Identifier should be a declared error new _ t; }; IntoUnresolvedTypeTable: PUBLIC PROC [t1: TABLES, key: ROPE, value: TypeNode] RETURNS [new: TABLES] ~ { IF (HashTable.Insert[t1.unresolvedTypeTable, key, value]) THEN new _ t1 ELSE [] _ SendError["Redeclared Identifier"]; -- Redeclared Identifier new _ t1; -- I'm not sure why this one is here... (bj) }; IntoUnresolvedConstantTable: PUBLIC PROC [t1: TABLES, key: ROPE, type: TypeNode, constant: ConstantNode] RETURNS [new: TABLES] ~ { value: REF UnresolvedConstantTableEntry; value _ NEW[UnresolvedConstantTableEntry]; value.type _ type; value.constant _ constant; IF HashTable.Insert[t1.unresolvedConstantTable, key, value] THEN new _ t1 ELSE [] _ SendError["Redeclared Identifier"]; -- Redeclared Identifier new _ t1; -- I'm not sure why this one is here... (bj) }; IsEnumerationConstant: PUBLIC PROC [type: CType, id: identifierNode] RETURNS [INT _ 0] ~ { notFound: BOOLEAN _ TRUE; sibling: CComponent _ type.children; WHILE ((sibling # NIL) AND notFound) DO IF Rope.Equal[sibling.name, id.text] THEN notFound _ FALSE ELSE sibling _ sibling.sibling; ENDLOOP; IF (sibling = NIL) THEN [] _ SendError["UnDeclared Enumeration"]; }; MkCComponent: PUBLIC PROC [name: ROPE, valBinding: INT, typeBinding: ROPE, sibling: CComponent] RETURNS [new: CComponent] ~ { new _ NEW[CComponentBody]; new.sibling _ sibling; new.name _ name; new.val _ valBinding; new.type _ typeBinding; }; MkCType: PUBLIC PROC [class: Generic, bound: INT, children: CComponent] RETURNS [new: CType] ~ { new _ NEW[CTypeBody]; new.class _ class; new.bound _ bound; new.children _ children; }; MkNILCComponent: PUBLIC PROC RETURNS [nil: CComponent] ~ { nil _ NIL; }; NotEnumeration: PUBLIC PROC[type: CType] RETURNS [result: BOOLEAN _ TRUE] ~ { result _ NOT (type.class = enumeration); }; Remove: PUBLIC PROC [id: identifierNode, tables: TABLES] RETURNS [new: TABLES] ~ { IF (NOT HashTable.Delete[tables.workTable, id.text]) THEN [] _ SendError["Undeclared or Redeclared Identifier"]; new _ tables; }; SeeIfDuplicated: PUBLIC PROC [tables: TABLES, id: identifierNode, constant: CARD] RETURNS [new: TABLES] ~ { IF (NOT HashTable.Insert[tables.workTable, id.text,""]) THEN [] _ SendError[Rope.Cat["Duplicates in Enumerated Type, ", id.text, " redeclared"]]; IF (NOT HashTable.Insert[tables.workTable, Convert.RopeFromCard[constant],""]) THEN [] _ SendError["Two identifiers have the same value in Enumerated Type"]; new _ tables; }; SeeIfInt: PUBLIC PROC[type: CType] RETURNS [yes: BOOLEAN _ TRUE] ~ { IF (type.class = integer) OR (type.class = longInteger) THEN NULL ELSE [] _ SendError["Type Mismatch, negative number not expected"]; }; SendError: PUBLIC PROC [errMsg: ROPE] RETURNS [c: CARD] ~ { length: INT; position: INT; outstream: IO.STREAM _ SIGNAL ThreeC4Support.GetReportStream; [position, length] _ SIGNAL ThreeC4Support.GetSourceInfo; IO.PutF[outstream, "\nError: %g at %g..%g\n", IO.rope[errMsg], IO.int[position], IO.int[position+length] ]; ERROR SiroccoPrivate.EndItAll; }; TryToCoerceNumber: PUBLIC PROC [first: CType, value: CARD] RETURNS [num: INT] ~ { SELECT first.class FROM procedure, cardinal, error, unspecified => { IF (value IN CARDINAL) THEN num _ 1 ELSE [] _ SendError["Wrong Number"]; }; integer => { IF (value IN [0..32768]) THEN num _ 1 ELSE [] _ SendError["Wrong Number"]; }; longInteger => { IF (value IN [0..2147483648]) THEN num _ 1 ELSE [] _ SendError["Wrong Number"]; }; longCardinal => { IF (value IN CARD) THEN num _ 1 ELSE [] _ SendError["Wrong Number"]; }; ENDCASE => { [] _ SendError["Wrong Number"]; num _ 0; }; }; ValueToConstant: PUBLIC PROC [value: Value] RETURNS [constant: ConstantNode] ~ { dir : REF DirectoryEntry; dir _ NARROW[value]; constant _ NARROW[dir.value]; }; ValueToRope: PUBLIC PROC [value: Value] RETURNS [rope: ROPE] ~ { dir: REF DirectoryEntry; dir _ NARROW[value]; rope _ dir.type; }; ValueToRopeConstant: PUBLIC PROC [value: Value, invalue: ROPE] RETURNS [rope: ROPE] ~ { dir: REF DirectoryEntry; dir _ NARROW[value]; rope _ Rope.Cat[invalue, dir.constant]; }; Array: PUBLIC PROC [constantType: ROPE, tables: TABLES] RETURNS [yes: BOOLEAN] ~ { successful: BOOLEAN; temp: Value; type: CType; [successful, temp] _ HashTable.Fetch[tables.typeTable, constantType]; IF (NOT successful) THEN ERROR; type _ NARROW [temp]; yes _ (type.class = array); }; GetObjectName: PUBLIC PROC [name: ROPE, tables: TABLES] RETURNS [objectName: ROPE] ~ { temp: Value; successful: BOOLEAN; [successful, temp] _ HashTable.Fetch[tables.madeUpNameTable, name]; IF successful THEN objectName _ NARROW [temp] ELSE objectName _ SiroccoPrivate.MakeUpName[name, "Object", tables]; }; IntoCondensedFunctionTable: PUBLIC PROC [functionName, function: ROPE, tables: TABLES] RETURNS [TABLES] ~ { [] _ HashTable.Insert[tables.condensedFunctionTable, functionName, function]; RETURN[tables]; }; MakeUpFunctionName: PUBLIC PROC RETURNS [madeUpName: ROPE] ~ { h: SiroccoPrivate.Handle _ SIGNAL SiroccoPrivate.AquireState; madeUpName _ IO.PutFR["P%gV%gFcn%g", IO.card[h.programNo], IO.card[h.versionNo], IO.card[h.uniqueNo] ]; h.uniqueNo _ h.uniqueNo + 1; }; AddFunctionList: PUBLIC PROC [value: Value, list: FunctionList] RETURNS [newList: FunctionList] ~{ entry: REF DirectoryEntry; entry _ NARROW[value]; newList _ RopeList.DAppend[list, entry.functions]; }; AddFunctionToTable: PUBLIC PROC [value: Value, list: FunctionList, tables: TABLES] RETURNS [newTables: TABLES] ~{ entry: REF DirectoryEntry; FromFunctionTableToCondensedFunctionTable: PROC [entry: ROPE] RETURNS [] ~ { value: Value; successful: BOOLEAN; [successful, value] _ HashTable.Fetch[tables.functionTable, entry]; successful _ HashTable.Insert[tables.condensedFunctionTable, entry, value]; }; entry _ NARROW[value]; RopeList.Map[entry.functions, FromFunctionTableToCondensedFunctionTable]; newTables _ tables; }; ConsFunctionList: PUBLIC PROC [list: FunctionList, newElement: ROPE] RETURNS [newList: FunctionList] ~ { newList _ list _ RopeList.Cons[list, newElement]; }; TypeOfSequence: PUBLIC PROC [sequenceName: ROPE, tables: TABLES] RETURNS [typeOf: ROPE] ~ { sucessful: BOOLEAN; value: HashTable.Value; type: CType; [sucessful, value] _ HashTable.Fetch[tables.typeTable, sequenceName]; type _ NARROW [value]; typeOf _ type.children.type }; GetTypeOfComponent: PUBLIC PROC [id: identifierNode, name: ROPE, tables: TABLES] RETURNS [typeOf: ROPE] ~ { sucessful: BOOLEAN; value: HashTable.Value; type: CType; list: CComponent; [sucessful, value] _ HashTable.Fetch[tables.typeTable, name]; type _ NARROW [value]; list _ type.children; WHILE ((NOT Rope.Equal[list.name, id.text]) AND (list # NIL)) DO list _ list.sibling; ENDLOOP; IF list = NIL THEN ERROR ELSE typeOf _ list.type; }; }. ^ParserPrivate2Impl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Bhargava, August 11, 1986 10:36:33 am PDT Bill Jackson (bj) August 18, 1986 10:09:52 pm PDT Copied Types Procs Should Sucessful always be true? No As in the case of Integers Should Sucessful always be true? I Think So. ERRORS HERE SHOULD BE RECOVERED FROM Κ<˜šœ™Icodešœ Οmœ1™˜>K˜šžœ ˜šžœ˜Kšœžœ˜Kšœ˜K˜Kšžœ˜K˜—Kšžœ# ˜8—Kšœ˜—šžœ˜KšœF˜FK˜šžœ ˜šžœ˜Kšœ žœ˜Kšœ>žœ˜Cšžœžœ ˜šžœ˜šžœ žœ˜Kšžœ% ˜=šžœ˜KšœO˜Ošžœ(˜*Kšžœ*˜.K˜—KšœF˜FKšœ>™>K˜Kšœžœ?žœžœ˜ZK˜Kšœ<˜˜>šžœ ˜šžœ  ˜Kšœ˜Kšœ žœ˜Kšœ žœ ˜Kšžœ˜K˜—Kšžœ# ˜8K˜—Kšœ˜—šžœ  ˜KšœJ˜Jšžœ ˜šžœ )˜0Kšœžœ˜KšœBžœ˜Gšžœžœ ˜šžœ ˜šžœ žœ˜Kšžœ% -˜Všžœ˜Kšœ!žœ>˜ešžœ(˜*Kšžœ*˜.K˜—KšœF˜FKšœžœZ˜eKšœžœ˜Kšœ˜Kšœ˜Kšœžœ˜Kšœ&žœ€˜¬Kšœ˜Kšœ žœ˜"Kšœ<˜Kšœžœ˜=šœ žœ˜$Kšžœ˜Kšžœ˜Kšžœ˜Kšœ˜—Kšœ˜Kšœ˜K˜—šŸœžœžœ$žœ˜bKšœžœ˜Kšœžœ˜Kšœ2˜2K˜K˜—š Ÿœžœžœ,žœžœ žœ˜qKšœžœ˜šŸ)œžœ žœžœ˜K˜K˜ Kšœ žœ˜KšœC˜CKšœK˜K—K˜—Kšœžœ˜KšœI˜IKšœ˜K˜—š Ÿœžœžœ"žœžœ˜hKšœ1˜1K˜K˜—šŸœžœžœžœ žœžœ žœ˜[Kšœ žœ˜Kšœ˜Kšœ ˜ K˜KšœE˜EKšœžœ ˜Kšœ˜K˜—šŸœžœžœžœ žœžœ žœ˜lKšœ žœ˜Kšœ˜Kšœ ˜ Kšœ˜K˜Kšœ=˜=Kšœžœ ˜Kšœ˜š žœžœ!žœ žœž˜@Kšœ˜Kšžœ˜ —Kš žœžœžœžœžœ˜1K˜——Jšœ˜J˜J˜J˜—…—;’P,