19 (* ========================================================================= *
20 // Collected syntax ---
22 // SymFile = Header [String (falSy | truSy | <other attribute>)]
23 // {Import | Constant | Variable | Type | Procedure}
25 // -- optional String is external name.
26 // -- falSy ==> Java class
27 // -- truSy ==> Java interface
29 // Header = magic modSy Name.
30 // Import = impSy Name [String] Key.
31 // -- optional string is explicit external name of class
32 // Constant = conSy Name Literal.
33 // Variable = varSy Name TypeOrd.
34 // Type = typSy Name TypeOrd.
35 // Procedure = prcSy Name [String] FormalType.
36 // -- optional string is explicit external name of procedure
37 // Method = mthSy Name byte byte TypeOrd [String][Name] FormalType.
38 // -- optional string is explicit external name of method
39 // FormalType = [retSy TypeOrd] frmSy {parSy byte TypeOrd [String]} endFm.
40 // -- optional phrase is return type for proper procedures
42 // TypeHeader = tDefS Ord [fromS Ord Name].
43 // -- optional phrase occurs if:
44 // -- type not from this module, i.e. indirect export
45 // TypeList = start { Array | Record | Pointer | ProcType |
46 // NamedType | Enum | Vector } close.
47 // Array = TypeHeader arrSy TypeOrd (Byte | Number | <empty>) endAr.
48 // -- nullable phrase is array length for fixed length arrays
49 // Vector = TypeHeader arrSy basSy TypeOrd endAr.
50 // Pointer = TypeHeader ptrSy TypeOrd.
51 // Event = TypeHeader evtSy FormalType.
52 // ProcType = TypeHeader pTpSy FormalType.
53 // Record = TypeHeader recSy recAtt [truSy | falSy]
54 // [basSy TypeOrd] [iFcSy {basSy TypeOrd}]
55 // {Name TypeOrd} {Method} {Statics} endRc.
56 // -- truSy ==> is an extension of external interface
57 // -- falSy ==> is an extension of external class
58 // -- basSy option defines base type, if not ANY / j.l.Object
59 // NamedType = TypeHeader.
60 // Statics = ( Constant | Variable | Procedure ).
61 // Enum = TypeHeader eTpSy { Constant } endRc.
62 // Name = namSy byte UTFstring.
63 // Literal = Number | String | Set | Char | Real | falSy | truSy.
65 // String = strSy UTFstring.
66 // Number = numSy longint.
67 // Real = fltSy ieee-double.
68 // Set = setSy integer.
69 // Key = keySy integer..
70 // Char = chrSy unicode character.
72 // Notes on the syntax:
73 // All record types must have a Name field, even though this is often
74 // redundant. The issue is that every record type (including those that
75 // are anonymous in CP) corresponds to a IR class, and the definer
76 // and the user of the class _must_ agree on the IR name of the class.
77 // The same reasoning applies to procedure types, which must have equal
78 // interface names in all modules.
80 // Notes on the fine print about UTFstring --- November 2011 clarification.
81 // The character sequence in the symbol file is modified UTF-8, that is
82 // it may represent CHR(0), U+0000, by the bytes 0xC0, 0x80. String
83 // constants may thus contain embedded nulls.
85 // ======================================================================== *)
88 modSy
= ORD('H'
); namSy
= ORD('$'
); bytSy
= ORD('
\');
89 numSy
= ORD('
#'
); chrSy
= ORD('c'
); strSy
= ORD('s'
);
90 fltSy
= ORD('r'
); falSy
= ORD('
0'
); truSy
= ORD('
1'
);
91 impSy
= ORD('I'
); setSy
= ORD('S'
); keySy
= ORD('K'
);
92 conSy
= ORD('C'
); typSy
= ORD('T'
); tDefS
= ORD('t'
);
93 prcSy
= ORD('P'
); retSy
= ORD('R'
); mthSy
= ORD('M'
);
94 varSy
= ORD('V'
); parSy
= ORD('p'
); start
= ORD('
&'
);
95 close
= ORD('
!'
); recSy
= ORD('
{'
); endRc
= ORD('
}'
);
96 frmSy
= ORD('
('
); fromS
= ORD('@'
); endFm
= ORD('
)'
);
97 arrSy
= ORD('
['
); endAr
= ORD('
]'
); pTpSy
= ORD('%'
);
98 ptrSy
= ORD('^'
); basSy
= ORD('
+'
); eTpSy
= ORD('e'
);
99 iFcSy
= ORD('~'
); evtSy
= ORD('v'
); vecSy
= ORD('
*'
);
110 (* ============================================================ *)
113 CharOpen
= POINTER TO ARRAY OF CHAR;
115 (* ============================================================ *)
118 Desc
= POINTER TO ABSTRACT
RECORD
124 list
: POINTER TO ARRAY OF Desc
;
128 AbsValue
= POINTER TO ABSTRACT
RECORD
131 NumValue
= POINTER TO RECORD (AbsValue
)
135 SetValue
= POINTER TO RECORD (AbsValue
)
139 StrValue
= POINTER TO RECORD (AbsValue
)
143 FltValue
= POINTER TO RECORD (AbsValue
)
147 BoolValue
= POINTER TO RECORD (AbsValue
)
151 ChrValue
= POINTER TO RECORD (AbsValue
)
155 Type
= POINTER TO ABSTRACT
RECORD
157 importedFrom
: Module
;
158 importedName
: CharOpen
;
161 TypeList
= POINTER TO ARRAY OF Type
;
163 Named
= POINTER TO RECORD (Type
)
166 Basic
= POINTER TO EXTENSIBLE
RECORD (Type
)
170 Enum
= POINTER TO EXTENSIBLE
RECORD (Type
)
174 Pointer
= POINTER TO EXTENSIBLE
RECORD (Type
)
176 isAnonPointer
: BOOLEAN;
180 Record
= POINTER TO EXTENSIBLE
RECORD (Type
)
186 intrFaces
: DescList
;
192 Array
= POINTER TO EXTENSIBLE
RECORD (Type
)
195 elemTypeNum
: INTEGER;
198 Vector
= POINTER TO EXTENSIBLE
RECORD (Type
)
200 elemTypeNum
: INTEGER;
203 Par
= POINTER TO RECORD
206 opNm
: CharOpen
; (* Optional *)
211 list
: POINTER TO ARRAY OF Par
;
215 Proc
= POINTER TO EXTENSIBLE
RECORD (Type
)
218 retTypeNum
: INTEGER;
220 isConstructor
: BOOLEAN;
224 Event
= POINTER TO RECORD (Proc
) END;
226 Meth
= POINTER TO EXTENSIBLE
RECORD (Proc
)
228 recName
: CharOpen
; (* Optional *)
229 recTypeNum
: INTEGER;
235 ImportDesc
= POINTER TO RECORD (Desc
)
238 ConstDesc
= POINTER TO RECORD (Desc
)
242 TypeDesc
= POINTER TO EXTENSIBLE
RECORD (Desc
)
247 UserTypeDesc
= POINTER TO RECORD (TypeDesc
)
250 VarDesc
= POINTER TO RECORD (TypeDesc
)
253 ProcDesc
= POINTER TO RECORD (Desc
)
259 list
: POINTER TO ARRAY OF Module
;
262 Module
= POINTER TO RECORD
266 pathName
: GPFiles
.FileNameArray
;
275 strongNm
: POINTER TO ARRAY 6 OF INTEGER;
278 (* ============================================================ *)
282 Output
= POINTER TO EXTENSIBLE
RECORD
286 FileOutput
= POINTER TO EXTENSIBLE
RECORD (Output
)
287 file
: GPTextFiles
.FILE
;
290 HtmlOutput
= POINTER TO RECORD (FileOutput
)
293 (* ============================================================ *)
296 args
, argNo
: INTEGER;
297 fileName
, modName
: CharOpen
;
298 printFNames
, doAll
, verbatim
, verbose
, hexCon
, alpha
: BOOLEAN;
299 file
: GPBinFiles
.FILE
;
307 accArray
: ARRAY 4 OF CHAR;
308 outExt
: ARRAY 6 OF CHAR;
313 (* ============================================================ *)
314 (* ============================================================ *)
316 PROCEDURE QuickSortDescs(lo
, hi
: INTEGER; dLst
: DescList
);
320 (* -------------------------------------------------- *)
321 PROCEDURE canonLT(l
,r
: ARRAY OF CHAR) : BOOLEAN;
324 FOR i
:= 0 TO LEN(l
) - 1 DO l
[i
] := CAP(l
[i
]) END;
325 FOR i
:= 0 TO LEN(r
) - 1 DO r
[i
] := CAP(r
[i
]) END;
328 (* -------------------------------------------------- *)
329 (* -------------------------------------------------- *)
330 PROCEDURE canonGT(l
,r
: ARRAY OF CHAR) : BOOLEAN;
333 FOR i
:= 0 TO LEN(l
) - 1 DO l
[i
] := CAP(l
[i
]) END;
334 FOR i
:= 0 TO LEN(r
) - 1 DO r
[i
] := CAP(r
[i
]) END;
337 (* -------------------------------------------------- *)
340 dsc
:= dLst
.list
[(lo
+hi
) DIV 2];
343 * WHILE dLst.list[i].name < dsc.name DO INC(i) END;
344 * WHILE dLst.list[j].name > dsc.name DO DEC(j) END;
346 WHILE canonLT(dLst
.list
[i
].name$
, dsc
.name$
) DO INC(i
) END;
347 WHILE canonGT(dLst
.list
[j
].name$
, dsc
.name$
) DO DEC(j
) END;
349 tmp
:= dLst
.list
[i
]; dLst
.list
[i
] := dLst
.list
[j
]; dLst
.list
[j
] := tmp
;
353 IF lo
< j
THEN QuickSortDescs(lo
, j
, dLst
) END;
354 IF i
< hi
THEN QuickSortDescs(i
, hi
, dLst
) END;
357 (* ============================================================ *)
358 (* ============================================================ *)
360 PROCEDURE GetModule(name
: CharOpen
) : Module
;
363 tmp
: POINTER TO ARRAY OF Module
;
366 ASSERT(modList
.list
# NIL);
367 FOR i
:= 0 TO modList
.tide
-1 DO
368 IF modList
.list
[i
].name^
= name^
THEN RETURN modList
.list
[i
] END;
370 IF modList
.tide
>= LEN(modList
.list
) THEN
372 NEW(modList
.list
,modList
.tide
*2);
373 FOR i
:= 0 TO modList
.tide
-1 DO
374 modList
.list
[i
] := tmp
[i
];
378 mod
.systemMod
:= FALSE
;
379 mod
.progArg
:= FALSE
;
381 mod
.symName
:= BOX(name^
+ symExt
);
382 modList
.list
[modList
.tide
] := mod
;
387 PROCEDURE AddMod (VAR mList
: ModList
; m
: Module
);
389 tmp
: POINTER TO ARRAY OF Module
;
392 IF mList
.list
= NIL THEN
395 ELSIF mList
.tide
>= LEN(mList
.list
) THEN
397 NEW(mList
.list
,LEN(tmp
)*2);
398 FOR i
:= 0 TO mList
.tide
-1 DO
399 mList
.list
[i
] := tmp
[i
];
402 mList
.list
[mList
.tide
] := m
;
406 (* ============================================================ *)
408 PROCEDURE AddDesc (VAR dList
: DescList
; d
: Desc
);
410 tmp
: POINTER TO ARRAY OF Desc
;
413 IF dList
.list
= NIL THEN
416 ELSIF dList
.tide
>= LEN(dList
.list
) THEN
418 NEW(dList
.list
,LEN(tmp
)*2);
419 FOR i
:= 0 TO dList
.tide
-1 DO
420 dList
.list
[i
] := tmp
[i
];
423 dList
.list
[dList
.tide
] := d
;
427 PROCEDURE AddPar (VAR pList
: ParList
; p
: Par
);
429 tmp
: POINTER TO ARRAY OF Par
;
432 IF pList
.list
= NIL THEN
435 ELSIF pList
.tide
>= LEN(pList
.list
) THEN
437 NEW(pList
.list
,LEN(tmp
)*2);
438 FOR i
:= 0 TO pList
.tide
-1 DO
439 pList
.list
[i
] := tmp
[i
];
442 pList
.list
[pList
.tide
] := p
;
446 PROCEDURE AddType (VAR tList
: TypeList
; t
: Type
; pos
: INTEGER);
448 tmp
: POINTER TO ARRAY OF Type
;
452 IF pos
>= LEN(tList
) THEN
454 NEW(tList
,LEN(tmp
)*2);
455 FOR i
:= 0 TO LEN(tmp
)-1 DO
462 (* ============================================================ *)
463 (* ======== Various reading utility procedures ======= *)
464 (* ============================================================ *)
466 PROCEDURE read() : INTEGER;
468 RETURN GPBinFiles
.readByte(file
);
471 (* ======================================= *)
473 PROCEDURE readUTF() : CharOpen
;
475 bad
= "Bad UTF-8 string";
485 * bNm is the length in bytes of the UTF8 representation
487 len
:= read() * 256 + read(); (* max length 65k *)
489 * Worst case the number of chars will equal byte-number.
494 chr
:= read(); INC(idx
);
495 IF chr
<= 07FH
THEN (* [0xxxxxxx] *)
496 buff
[num
] := CHR(chr
); INC(num
);
497 ELSIF chr
DIV 32 = 06H
THEN (* [110xxxxx,10xxxxxx] *)
498 bNm
:= chr
MOD 32 * 64;
499 chr
:= read(); INC(idx
);
500 IF chr
DIV 64 = 02H
THEN
501 buff
[num
] := CHR(bNm
+ chr
MOD 64); INC(num
);
505 ELSIF chr
DIV 16 = 0EH
THEN (* [1110xxxx,10xxxxxx,10xxxxxxx] *)
506 bNm
:= chr
MOD 16 * 64;
507 chr
:= read(); INC(idx
);
508 IF chr
DIV 64 = 02H
THEN
509 bNm
:= (bNm
+ chr
MOD 64) * 64;
510 chr
:= read(); INC(idx
);
511 IF chr
DIV 64 = 02H
THEN
512 buff
[num
] := CHR(bNm
+ chr
MOD 64); INC(num
);
524 RETURN LitValue
.arrToCharOpen(buff
, num
);
527 (* ======================================= *)
529 PROCEDURE readChar() : CHAR;
531 RETURN CHR(read() * 256 + read());
534 (* ======================================= *)
536 PROCEDURE readInt() : INTEGER;
537 BEGIN [UNCHECKED_ARITHMETIC
]
538 (* overflow checking off here *)
539 RETURN ((read() * 256 + read()) * 256 + read()) * 256 + read();
542 (* ======================================= *)
544 PROCEDURE readLong() : LONGINT;
545 VAR result
: LONGINT;
547 BEGIN [UNCHECKED_ARITHMETIC
]
548 (* overflow checking off here *)
550 FOR index
:= 1 TO 7 DO
551 result
:= result
* 256 + read();
556 (* ======================================= *)
558 PROCEDURE readReal() : REAL;
559 VAR result
: LONGINT;
561 result
:= readLong();
562 RETURN RTS
.longBitsToReal(result
);
565 (* ======================================= *)
567 PROCEDURE readOrd() : INTEGER;
571 IF chr
<= 07FH
THEN RETURN chr
;
574 RETURN chr
+ read() * 128;
578 (* ============================================================ *)
579 (* ======== Symbol File Reader ======= *)
580 (* ============================================================ *)
582 PROCEDURE DiagnoseSymbol();
583 VAR arg : ARRAY 24 OF CHAR;
586 | ORD('H') : Console.WriteString("MODULE "); RETURN;
587 | ORD('0') : Console.WriteString("FALSE");
588 | ORD('1') : Console.WriteString("TRUE");
589 | ORD('I') : Console.WriteString("IMPORT "); RETURN;
590 | ORD('C') : Console.WriteString("CONST");
591 | ORD('T') : Console.WriteString("TYPE "); RETURN;
592 | ORD('P') : Console.WriteString("PROCEDURE "); RETURN;
593 | ORD('M') : Console.WriteString("MethodSymbol");
594 | ORD('V') : Console.WriteString("VAR "); RETURN;
595 | ORD('p') : Console.WriteString("ParamSymbol");
596 | ORD('&') : Console.WriteString("StartSymbol");
597 | ORD('!') : Console.WriteString("CloseSymbol");
598 | ORD('{') : Console.WriteString("StartRecord");
599 | ORD('}') : Console.WriteString("EndRecord");
600 | ORD('(') : Console.WriteString("StartFormals");
601 | ORD('@') : Console.WriteString("FROM "); RETURN;
602 | ORD(')') : Console.WriteString("EndFormals");
603 | ORD('[') : Console.WriteString("StartArray");
604 | ORD(']') : Console.WriteString("EndArray");
605 | ORD('%') : Console.WriteString("ProcType");
606 | ORD('^') : Console.WriteString("POINTER");
607 | ORD('e') : Console.WriteString("EnumType");
608 | ORD('~') : Console.WriteString("InterfaceType");
609 | ORD('v') : Console.WriteString("EventType");
610 | ORD('*') : Console.WriteString("VectorType");
611 | ORD('\') : Console.WriteString("BYTE "); Console.WriteInt(iAtt,1);
612 | ORD('c') : Console.WriteString("CHAR "); Console.Write(cAtt);
613 | ORD('S') : Console.WriteString("SetSymbol 0x"); Console.WriteHex(iAtt,1);
614 | ORD('K') : Console.WriteString("KeySymbol 0x"); Console.WriteHex(iAtt,1);
615 | ORD('t') : Console.WriteString("TypeDef t#"); Console.WriteInt(iAtt,1);
616 | ORD('+') : Console.WriteString("BaseType t#"); Console.WriteInt(iAtt,1);
617 | ORD('R') : Console.WriteString("RETURN t#"); Console.WriteInt(iAtt,1);
619 RTS.LongToStr(lAtt, arg);
620 Console.WriteString("Number ");
621 Console.WriteString(arg$);
623 Console.WriteString("NameSymbol #");
624 Console.WriteInt(iAtt,1);
626 Console.WriteString(sAtt);
628 Console.WriteString("String '");
629 Console.WriteString(sAtt);
632 RTS.RealToStrInvar(rAtt, arg);
633 Console.WriteString("Real ");
634 Console.WriteString(arg$);
636 Console.WriteString("Bad Symbol ");
637 Console.WriteInt(sSym, 1);
638 Console.WriteString(" in File");
643 (* ============================================================ *)
654 | retSy
, fromS
, tDefS
, basSy
:
666 ELSE (* nothing to do *)
668 (* DiagnoseSymbol(); *)
671 (* ======================================= *)
673 PROCEDURE ReadPast(sym
: INTEGER);
676 Console
.WriteString("Expected ");
677 Console
.Write(CHR(sym
));
678 Console
.WriteString(" got ");
679 Console
.Write(CHR(sSym
));
681 RTS
.Throw("Bad symbol file format");
686 (* ============================================ *)
688 PROCEDURE GetLiteral(VAR lit
: AbsValue
);
698 | truSy
: NEW(b
); b
.boolVal
:= TRUE
; lit
:= b
;
699 | falSy
: NEW(b
); b
.boolVal
:= FALSE
; lit
:= b
;
700 | numSy
: NEW(n
); n
.numVal
:= lAtt
; lit
:= n
;
701 | chrSy
: NEW(c
); c
.chrVal
:= cAtt
; lit
:= c
;
702 | fltSy
: NEW(f
); f
.fltVal
:= rAtt
; lit
:= f
;
703 | setSy
: NEW(s
); s
.setVal
:= BITS(iAtt
); lit
:= s
;
704 | strSy
: NEW(st
); st
.strVal
:= sAtt
; lit
:= st
;
706 GetSym(); (* read past value *)
709 (* ============================================ *)
711 PROCEDURE GetFormalType(p
: Proc
);
713 // FormalType = [retSy TypeOrd] frmSy {parSy byte TypeOrd} endFm.
714 // -- optional phrase is return type for proper procedures
722 p
.retTypeNum
:= iAtt
;
728 WHILE sSym
= parSy
DO
731 IF par
.mode
> 0 THEN p
.noModes
:= FALSE
; END;
732 par
.typeNum
:= readOrd();
743 (* ============================================ *)
745 PROCEDURE pointerType() : Pointer
;
746 (* Assert: the current symbol is ptrSy. *)
747 (* Pointer = TypeHeader ptrSy TypeOrd. *)
752 ptr
.baseNum
:= readOrd();
753 ptr
.isAnonPointer
:= FALSE
;
758 (* ============================================ *)
760 PROCEDURE eventType() : Proc
;
761 (* Assert: the current symbol is evtSy. *)
762 (* Event = TypeHeader evtSy FormalType. *)
766 GetSym(); (* read past evtSy *)
771 (* ============================================ *)
773 PROCEDURE procedureType() : Proc
;
774 (* Assert: the current symbol is pTpSy. *)
775 (* ProcType = TypeHeader pTpSy FormalType. *)
780 GetSym(); (* read past pTpSy *)
785 (* ============================================ *)
787 PROCEDURE^
GetConstant() : ConstDesc
;
789 PROCEDURE enumType() : Enum
;
790 (* Assert: the current symbol is eTpSy. *)
791 (* Enum = TypeHeader eTpSy { Constant } endRc. *)
797 WHILE (sSym
= conSy
) DO
798 AddDesc(e
.ids
,GetConstant());
804 (* ============================================ *)
806 PROCEDURE arrayType() : Type
;
807 (* Assert: at entry the current symbol is arrSy. *)
808 (* Array = TypeHeader arrSy TypeOrd (Byte | Number | ) endAr. *)
809 (* -- nullable phrase is array length for fixed length arrays *)
814 arr
.elemTypeNum
:= readOrd();
819 ELSIF sSym
= numSy
THEN
820 arr
.size
:= SHORT(lAtt
);
829 (* ============================================ *)
831 PROCEDURE vectorType() : Type
;
832 (* Assert: at entry the current symbol is vecSy. *)
833 (* Vector = TypeHeader vecSy TypeOrd endAr. *)
838 vec
.elemTypeNum
:= readOrd();
844 (* ============================================ *)
846 PROCEDURE^
GetProc() : ProcDesc
;
847 PROCEDURE^
GetVar() : VarDesc
;
849 PROCEDURE recordType(recNum
: INTEGER) : Record
;
850 (* Assert: at entry the current symbol is recSy. *)
851 (* Record = TypeHeader recSy recAtt [truSy | falSy | <others>] *)
852 (* [basSy TypeOrd] [iFcSy {basSy TypeOrd}] *)
853 (* {Name TypeOrd} {Method} {Statics} endRc. *)
862 rec
.recAtt
:= read();
863 rec
.isAnonRec
:= FALSE
;
864 GetSym(); (* Get past recSy rAtt *)
865 IF (sSym
= falSy
) OR (sSym
= truSy
) THEN
876 WHILE sSym
= basSy
DO
878 * * Console.WriteString("got interface $T");
879 * * Console.WriteInt(iAtt,1);
885 AddDesc(rec
.intrFaces
,t
);
888 WHILE sSym
= namSy
DO
892 f
.typeNum
:= readOrd();
894 AddDesc(rec
.fields
,f
);
896 (* Method = mthSy Name byte byte TypeOrd [String] FormalType. *)
897 WHILE sSym
= mthSy
DO
900 mth
.importedFrom
:= NIL;
901 mth
.isConstructor
:= FALSE
;
904 IF (sSym
# namSy
) THEN RTS
.Throw("Bad symbol file format"); END;
908 (* byte1 is the method attributes *)
910 (* byte2 is param form of receiver *)
911 mth
.recMode
:= read();
912 (* next 1 or 2 bytes are rcv-type *)
913 mth
.recTypeNum
:= readOrd();
926 AddDesc(rec
.methods
,m
);
928 WHILE (sSym
= conSy
) OR (sSym
= prcSy
) OR (sSym
= varSy
) DO
930 AddDesc(rec
.statics
,GetConstant());
931 ELSIF sSym
= prcSy
THEN
932 AddDesc(rec
.statics
,GetProc());
934 AddDesc(rec
.statics
,GetVar());
941 (* ============================================ *)
943 PROCEDURE ResolveProc(p
: Proc
);
947 p
.retType
:= typeList
[p
.retTypeNum
];
948 IF p
.retTypeNum
= 0 THEN ASSERT(p
.retType
= NIL); END;
950 p(Meth
).receiver
:= typeList
[p(Meth
).recTypeNum
];
952 FOR i
:= 0 TO p
.pars
.tide
-1 DO
953 p
.pars
.list
[i
].type
:= typeList
[p
.pars
.list
[i
].typeNum
];
957 (* ============================================ *)
959 PROCEDURE ReadTypeList(mod
: Module
);
960 (* TypeList = start { Array | Record | Pointer *)
961 (* | ProcType | NamedType | Enum } close. *)
962 (* TypeHeader = tDefS Ord [fromS Ord Name]. *)
963 VAR modOrd
: INTEGER;
974 WHILE sSym
= tDefS
DO
981 * The fromS symbol appears if the type is imported.
991 | arrSy
: typ
:= arrayType();
992 | vecSy
: typ
:= vectorType();
993 | recSy
: typ
:= recordType(typOrd
);
994 | ptrSy
: typ
:= pointerType();
995 | evtSy
: typ
:= eventType();
996 | pTpSy
: typ
:= procedureType();
997 | eTpSy
: typ
:= enumType();
1003 AddType(typeList
,typ
,typOrd
);
1005 typ
.importedFrom
:= mod
.imports
.list
[modOrd
];
1006 typ
.importedName
:= impName
;
1011 FOR i
:= Symbols
.tOffset
TO typOrd
DO
1013 IF typ
IS Array
THEN
1014 typ(Array
).elemType
:= typeList
[typ(Array
).elemTypeNum
];
1015 ELSIF typ
IS Vector
THEN
1016 typ(Vector
).elemType
:= typeList
[typ(Vector
).elemTypeNum
];
1017 ELSIF typ
IS Record
THEN
1019 IF (rec
.baseNum
> 0) THEN
1020 rec
.baseType
:= typeList
[rec
.baseNum
];
1022 FOR j
:= 0 TO rec
.fields
.tide
-1 DO
1023 f
:= rec
.fields
.list
[j
](VarDesc
);
1024 f
.type
:= typeList
[f
.typeNum
];
1026 FOR j
:= 0 TO rec
.methods
.tide
-1 DO
1027 ResolveProc(rec
.methods
.list
[j
](ProcDesc
).pType
);
1029 FOR j
:= 0 TO rec
.statics
.tide
-1 DO
1030 IF rec
.statics
.list
[j
] IS ProcDesc
THEN
1031 ResolveProc(rec
.statics
.list
[j
](ProcDesc
).pType
);
1032 ELSIF rec
.statics
.list
[j
] IS VarDesc
THEN
1033 f
:= rec
.statics
.list
[j
](VarDesc
);
1034 f
.type
:= typeList
[f
.typeNum
];
1037 ELSIF typ
IS Pointer
THEN
1038 typ(Pointer
).baseType
:= typeList
[typ(Pointer
).baseNum
];
1039 ELSIF typ
IS Proc
THEN
1040 ResolveProc(typ(Proc
));
1045 (* ============================================ *)
1047 PROCEDURE ResolveAnonRecs();
1053 FOR i
:= Symbols
.tOffset
TO LEN(typeList
)-1 DO
1055 IF ~verbatim
& (typ
# NIL) & (typ
.declarer
# NIL) THEN
1056 ch0
:= typ
.declarer
.name
[0];
1057 IF (ch0
= "@") OR (ch0
= "$") THEN typ
.declarer
:= NIL END;
1059 IF typ
IS Record
THEN
1061 FOR j
:= 0 TO r
.intrFaces
.tide
- 1 DO
1062 k
:= r
.intrFaces
.list
[j
](TypeDesc
).typeNum
;
1063 r
.intrFaces
.list
[j
](TypeDesc
).type
:= typeList
[k
];
1065 IF typ
.declarer
= NIL THEN (* anon record *)
1066 typ(Record
).isAnonRec
:= TRUE
;
1068 ELSIF (typ
IS Pointer
) & (typ(Pointer
).baseType
IS Record
) THEN
1069 IF (typ
.declarer
= NIL) & (typ
.importedFrom
= NIL) THEN
1070 typ(Pointer
).isAnonPointer
:= TRUE
;
1072 r
:= typ(Pointer
).baseType(Record
);
1073 IF (r
.declarer
= NIL) THEN (* anon record *)
1074 r
.isAnonRec
:= TRUE
;
1075 r
.ptrType
:= typ(Pointer
);
1079 END ResolveAnonRecs
;
1081 (* ============================================ *)
1083 PROCEDURE GetType() : UserTypeDesc
;
1084 (* Type = typSy Name TypeOrd. *)
1086 typeDesc
: UserTypeDesc
;
1090 typeDesc
.name
:= sAtt
;
1091 typeDesc
.access
:= iAtt
;
1092 typeDesc
.typeNum
:= readOrd();
1097 (* ============================================ *)
1099 PROCEDURE GetImport() : Module
;
1100 (* Import = impSy Name [String] Key. *)
1106 impMod
:= GetModule(sAtt
);
1109 impMod
.name
:= sAtt
;
1110 impMod
.systemMod
:= FALSE
;
1111 impMod
.progArg
:= FALSE
;
1114 IF sSym
= strSy
THEN impMod
.fName
:= sAtt
; GetSym(); END;
1119 (* ============================================ *)
1121 PROCEDURE GetConstant() : ConstDesc
;
1122 (* Constant = conSy Name Literal. *)
1124 constDesc
: ConstDesc
;
1128 constDesc
.name
:= sAtt
;
1129 constDesc
.access
:= iAtt
;
1131 GetLiteral(constDesc
.val
);
1135 (* ============================================ *)
1137 PROCEDURE GetVar() : VarDesc
;
1138 (* Variable = varSy Name TypeOrd. *)
1144 varDesc
.name
:= sAtt
;
1145 varDesc
.access
:= iAtt
;
1146 varDesc
.typeNum
:= readOrd();
1151 (* ============================================ *)
1153 PROCEDURE GetProc() : ProcDesc
;
1154 (* Procedure = prcSy Name [String] [trySy] FormalType. *)
1156 procDesc
: ProcDesc
;
1160 procDesc
.name
:= sAtt
;
1161 procDesc
.access
:= iAtt
;
1163 NEW(procDesc
.pType
);
1164 IF sSym
= strSy
THEN
1165 IF sAtt^
= "<init>" THEN
1166 procDesc
.pType
.fName
:= BOX("< init >");
1168 procDesc
.pType
.fName
:= sAtt
;
1172 procDesc
.pType
.fName
:= NIL;
1174 IF sSym
= truSy
THEN
1175 procDesc
.pType
.isConstructor
:= TRUE
;
1178 procDesc
.pType
.isConstructor
:= FALSE
;
1180 procDesc
.pType
.importedFrom
:= NIL;
1181 procDesc
.pType
.declarer
:= procDesc
;
1182 GetFormalType(procDesc
.pType
);
1186 (* ============================================ *)
1188 PROCEDURE SymFile(mod
: Module
);
1190 // SymFile = Header [String (falSy | truSy | <others>)]
1191 // {Import | Constant | Variable | Type | Procedure}
1193 // Header = magic modSy Name.
1195 // magic has already been recognized.
1199 typeDesc
: UserTypeDesc
;
1201 procDesc
: ProcDesc
;
1204 AddMod(mod
.imports
,mod
);
1206 IF sSym
= namSy
THEN (* do something with f.sAtt *)
1207 IF mod
.name^
# sAtt^
THEN
1208 Error
.WriteString("Wrong name in symbol file. Expected <");
1209 Error
.WriteString(mod
.name^
+ ">, found <");
1210 Error
.WriteString(sAtt^
+ ">");
1215 ELSE RTS
.Throw("Bad symfile header");
1217 IF sSym
= strSy
THEN (* optional name *)
1220 IF (sSym
= falSy
) OR (sSym
= truSy
) THEN
1222 ELSE RTS
.Throw("Bad explicit name");
1228 * Optional strong name info.
1230 IF sSym
= numSy
THEN
1231 NEW(mod
.strongNm
); (* POINTER TO ARRAY 6 OF INTEGER *)
1232 mod
.strongNm
[0] := RTS
.hiInt(lAtt
);
1233 mod
.strongNm
[1] := RTS
.loInt(lAtt
);
1235 mod
.strongNm
[2] := RTS
.hiInt(lAtt
);
1236 mod
.strongNm
[3] := RTS
.loInt(lAtt
);
1238 mod
.strongNm
[4] := RTS
.hiInt(lAtt
);
1239 mod
.strongNm
[5] := RTS
.loInt(lAtt
);
1242 (* end optional strong name information *)
1246 | typSy
: AddDesc(mod
.types
,GetType());
1247 | impSy
: AddMod(mod
.imports
,GetImport());
1248 | conSy
: AddDesc(mod
.consts
,GetConstant());
1249 | varSy
: AddDesc(mod
.vars
,GetVar());
1250 | prcSy
: AddDesc(mod
.procs
,GetProc());
1251 ELSE RTS
.Throw("Bad object");
1255 IF sSym
# keySy
THEN
1256 RTS
.Throw("Missing keySy");
1258 FOR i
:= 0 TO mod
.types
.tide
-1 DO
1259 typeDesc
:= mod
.types
.list
[i
](UserTypeDesc
);
1260 thisType
:= typeList
[typeDesc
.typeNum
];
1261 typeDesc
.type
:= thisType
;
1262 typeDesc
.type
.declarer
:= typeDesc
;
1264 FOR i
:= 0 TO mod
.vars
.tide
-1 DO
1265 varDesc
:= mod
.vars
.list
[i
](VarDesc
);
1266 varDesc
.type
:= typeList
[varDesc
.typeNum
];
1268 FOR i
:= 0 TO mod
.procs
.tide
-1 DO
1269 procDesc
:= mod
.procs
.list
[i
](ProcDesc
);
1270 ResolveProc(mod
.procs
.list
[i
](ProcDesc
).pType
);
1275 (* ============================================================ *)
1277 PROCEDURE GetSymAndModNames(VAR symName
: CharOpen
;
1278 OUT modName
: CharOpen
);
1282 modName
:= BOX(symName^
);
1284 WHILE ((i
< LEN(symName
)) & (symName
[i
] # '
.'
) &
1285 (symName
[i
] # 0X
)) DO INC(i
); END;
1286 IF (i
>= LEN(symName
)) OR (symName
[i
] # '
.'
) THEN
1287 symName
:= BOX(symName^
+ symExt
);
1291 END GetSymAndModNames
;
1295 marker
,modIx
,i
: INTEGER;
1299 WHILE (modIx
< modList
.tide
) DO
1300 mod
:= modList
.list
[modIx
];
1303 file
:= GPBinFiles
.findLocal(mod
.symName
);
1305 file
:= GPBinFiles
.findOnPath("CPSYM", mod
.symName
);
1306 IF (file
= NIL) OR (mod
.progArg
) THEN
1307 Error
.WriteString("File <" + mod
.symName^
+ "> not found");
1311 mod
.pathName
:= GPBinFiles
.getFullPathName(file
);
1313 WHILE (i
< LEN(mod
.pathName
)) & (mod
.pathName
[i
] # ".") DO INC(i
); END;
1314 mod
.pathName
[i
] := 0X
;
1316 marker
:= readInt();
1317 IF marker
= RTS
.loInt(magic
) THEN
1318 (* normal case, nothing to do *)
1319 ELSIF marker
= RTS
.loInt(syMag
) THEN
1320 mod
.systemMod
:= TRUE
;
1322 Error
.WriteString("File <" + fileName^
+ "> is not a valid symbol file");
1329 Error
.WriteString("Reading " + mod
.name^
); Error
.WriteLn
;
1332 GPBinFiles
.CloseFile(file
);
1336 Error
.WriteString("Error in Parse()"); Error
.WriteLn
;
1337 Error
.WriteString(RTS
.getStr(x
)); Error
.WriteLn
;
1340 (* ===================================================================== *)
1342 PROCEDURE (o
: Output
) WriteStart(mod
: Module
),NEW,EMPTY
;
1344 PROCEDURE (o
: Output
) WriteEnd(),NEW,EMPTY
;
1346 PROCEDURE (o
: Output
) Write(ch
: CHAR),NEW,EXTENSIBLE
;
1351 PROCEDURE (o
: Output
) WriteIdent(str
: ARRAY OF CHAR),NEW,EXTENSIBLE
;
1353 Console
.WriteString(str
);
1356 PROCEDURE (o
: Output
) WriteImport(impMod
: Module
),NEW,EXTENSIBLE
;
1358 Console
.WriteString(impMod
.name
);
1361 PROCEDURE (o
: Output
) WriteString(str
: ARRAY OF CHAR),NEW,EXTENSIBLE
;
1363 Console
.WriteString(str
);
1366 PROCEDURE (o
: Output
) WriteLn(),NEW,EXTENSIBLE
;
1371 PROCEDURE (o
: Output
) WriteInt(i
: INTEGER),NEW,EXTENSIBLE
;
1373 Console
.WriteInt(i
,1);
1376 PROCEDURE (o
: Output
) WriteLong(l
: LONGINT),NEW,EXTENSIBLE
;
1378 str
: ARRAY 30 OF CHAR;
1380 IF (l
> MAX(INTEGER)) OR (l
< MIN(INTEGER)) THEN
1381 RTS
.LongToStr(l
,str
);
1382 Console
.WriteString(str
);
1384 Console
.WriteInt(SHORT(l
),1);
1388 PROCEDURE (o
: Output
) WriteKeyword(str
: ARRAY OF CHAR),NEW,EXTENSIBLE
;
1390 Console
.WriteString(str
);
1393 PROCEDURE (o
: Output
) Indent(i
: INTEGER),NEW,EXTENSIBLE
;
1401 PROCEDURE (o
: Output
) WriteImportedTypeName(impMod
: Module
;
1402 tName
: ARRAY OF CHAR),NEW,EXTENSIBLE
;
1404 Console
.WriteString(impMod
.name^
+ "." + tName
);
1405 END WriteImportedTypeName
;
1407 PROCEDURE (o
: Output
) WriteTypeName(tName
: ARRAY OF CHAR),NEW,EXTENSIBLE
;
1409 Console
.WriteString(tName
);
1412 PROCEDURE (o
: Output
) WriteTypeDecl(tName
: ARRAY OF CHAR),NEW,EXTENSIBLE
;
1414 Console
.WriteString(tName
);
1418 PROCEDURE (o
: Output
) MethRef(IN nam
: ARRAY OF CHAR),NEW,EMPTY
;
1419 PROCEDURE (o
: Output
) MethAnchor(IN nam
: ARRAY OF CHAR),NEW,EMPTY
;
1422 (* ------------------------------------------------------------------- *)
1424 PROCEDURE (f
: FileOutput
) Write(ch
: CHAR),EXTENSIBLE
;
1426 GPText
.Write(f
.file
,ch
);
1429 PROCEDURE (f
: FileOutput
) WriteIdent(str
: ARRAY OF CHAR),EXTENSIBLE
;
1431 GPText
.WriteString(f
.file
,str
);
1434 PROCEDURE (f
: FileOutput
) WriteImport(impMod
: Module
),EXTENSIBLE
;
1436 GPText
.WriteString(f
.file
,impMod
.name
);
1439 PROCEDURE (f
: FileOutput
) WriteString(str
: ARRAY OF CHAR),EXTENSIBLE
;
1441 GPText
.WriteString(f
.file
,str
);
1444 PROCEDURE (f
: FileOutput
) WriteLn(),EXTENSIBLE
;
1446 GPText
.WriteLn(f
.file
);
1449 PROCEDURE (f
: FileOutput
) WriteInt(i
: INTEGER),EXTENSIBLE
;
1451 GPText
.WriteInt(f
.file
,i
,1);
1454 PROCEDURE (f
: FileOutput
) WriteLong(l
: LONGINT),EXTENSIBLE
;
1456 GPText
.WriteLong(f
.file
,l
,1);
1459 PROCEDURE (f
: FileOutput
) WriteKeyword(str
: ARRAY OF CHAR),EXTENSIBLE
;
1461 GPText
.WriteString(f
.file
,str
);
1464 PROCEDURE (f
: FileOutput
) Indent(i
: INTEGER),EXTENSIBLE
;
1467 GPText
.Write(f
.file
,' '
);
1472 PROCEDURE (f
: FileOutput
) WriteImportedTypeName(impMod
: Module
;
1473 tName
: ARRAY OF CHAR),EXTENSIBLE
;
1475 GPText
.WriteString(f
.file
,impMod
.name^
+ "." + tName
);
1476 END WriteImportedTypeName
;
1478 PROCEDURE (f
: FileOutput
) WriteTypeName(tName
: ARRAY OF CHAR),EXTENSIBLE
;
1480 GPText
.WriteString(f
.file
,tName
);
1483 PROCEDURE (f
: FileOutput
) WriteTypeDecl(tName
: ARRAY OF CHAR),EXTENSIBLE
;
1485 GPText
.WriteString(f
.file
,tName
);
1488 (* ------------------------------------------------------------------- *)
1490 PROCEDURE (h
: HtmlOutput
) WriteStart(mod
: Module
);
1492 GPText
.WriteString(h
.file
,"<html><head><title>");
1493 GPText
.WriteString(h
.file
,mod
.name
);
1494 GPText
.WriteString(h
.file
,"</title></head>");
1495 GPText
.WriteLn(h
.file
);
1496 GPText
.WriteString(h
.file
,'
<body bgcolor
="white">'
);
1497 GPText
.WriteLn(h
.file
);
1498 GPText
.WriteString(h
.file
,"<hr><pre>");
1499 GPText
.WriteLn(h
.file
);
1502 PROCEDURE (h
: HtmlOutput
) WriteEnd();
1504 GPText
.WriteString(h
.file
,"</font></pre></hr></body></html>");
1505 GPText
.WriteLn(h
.file
);
1508 PROCEDURE (h
: HtmlOutput
) Write(ch
: CHAR);
1510 GPText
.Write(h
.file
,ch
);
1513 PROCEDURE (h
: HtmlOutput
) WriteImport(impMod
: Module
);
1515 GPText
.WriteString(h
.file
,'
<a href
="');
1516 IF impMod.pathName = NIL THEN
1517 GPText.WriteString(h.file,impMod.name);
1519 GPText.WriteString(h.file,impMod.pathName);
1521 GPText.WriteString(h.file,'.html">'
);
1522 GPText
.WriteString(h
.file
,impMod
.name
);
1523 GPText
.WriteString(h
.file
,'
</a
>'
);
1526 PROCEDURE (h
: HtmlOutput
) WriteIdent(str
: ARRAY OF CHAR);
1528 GPText
.WriteString(h
.file
,'
<font color
="#cc0033">'
);
1529 GPText
.WriteString(h
.file
,str
);
1530 GPText
.WriteString(h
.file
,"</font>");
1533 PROCEDURE (h
: HtmlOutput
) WriteString(str
: ARRAY OF CHAR);
1535 GPText
.WriteString(h
.file
,str
);
1538 PROCEDURE (h
: HtmlOutput
) WriteLn();
1540 GPText
.WriteLn(h
.file
);
1543 PROCEDURE (h
: HtmlOutput
) WriteInt(i
: INTEGER );
1545 GPText
.WriteInt(h
.file
,i
,1);
1548 PROCEDURE (h
: HtmlOutput
) WriteLong(l
: LONGINT);
1550 GPText
.WriteLong(h
.file
,l
,1);
1553 PROCEDURE (h
: HtmlOutput
) WriteKeyword(str
: ARRAY OF CHAR);
1555 GPText
.WriteString(h
.file
,"<b>" + str
+ "</b>");
1558 PROCEDURE (h
: HtmlOutput
) Indent(i
: INTEGER);
1561 GPText
.Write(h
.file
,' '
);
1566 PROCEDURE (h
: HtmlOutput
) WriteImportedTypeName(impMod
: Module
;
1567 tName
: ARRAY OF CHAR);
1569 GPText
.WriteString(h
.file
,'
<a href
="');
1570 IF impMod.pathName = NIL THEN
1571 GPText.WriteString(h.file,impMod.name);
1573 GPText.WriteString(h.file,impMod.pathName);
1575 GPText.WriteString(h.file,'.html#type-');;
1576 GPText.WriteString(h.file,tName);
1577 GPText.WriteString(h.file,'">'
);
1578 GPText
.WriteString(h
.file
,impMod
.name^
+ "." + tName
);
1579 GPText
.WriteString(h
.file
,'
</a
>'
);
1580 END WriteImportedTypeName
;
1582 PROCEDURE (h
: HtmlOutput
) WriteTypeName(tName
: ARRAY OF CHAR);
1584 GPText
.WriteString(h
.file
,'
<a href
="#type-');;
1585 GPText.WriteString(h.file,tName);
1586 GPText.WriteString(h.file,'">'
);
1587 GPText
.WriteString(h
.file
,tName
);
1588 GPText
.WriteString(h
.file
,'
</a
>'
);
1591 PROCEDURE (h
: HtmlOutput
) WriteTypeDecl(tName
: ARRAY OF CHAR);
1593 GPText
.WriteString(h
.file
,'
<a name
="type-');
1594 GPText.WriteString(h.file,tName);
1595 GPText.WriteString(h.file,'"></a
>'
);
1596 GPText
.WriteString(h
.file
,'
<font color
="#cc0033">'
);
1597 GPText
.WriteString(h
.file
,tName
);
1598 GPText
.WriteString(h
.file
,"</font>");
1602 PROCEDURE (h
: HtmlOutput
) MethRef(IN nam
: ARRAY OF CHAR);
1604 GPText
.WriteString(h
.file
, '
<a href
="#meths-');;
1605 GPText.WriteString(h.file, nam);
1606 GPText.WriteString(h.file, '">'
);
1607 GPText
.WriteString(h
.file
, '
<font color
="#cc0033">'
);
1608 GPText
.WriteString(h
.file
, "(* Typebound Procedures *)");
1609 GPText
.WriteString(h
.file
, "</font>");
1610 GPText
.WriteString(h
.file
, '
</a
>'
);
1613 PROCEDURE (h
: HtmlOutput
) MethAnchor(IN nam
: ARRAY OF CHAR);
1615 GPText
.WriteString(h
.file
, '
<a name
="meths-');
1616 GPText.WriteString(h.file, nam);
1617 GPText.WriteString(h.file, '"></a
>'
);
1621 (* ==================================================================== *)
1622 (* Format Helpers *)
1623 (* ==================================================================== *)
1625 PROCEDURE qStrOf(str
: CharOpen
) : CharOpen
;
1629 rslt
: LitValue
.CharVector
;
1630 (* -------------------------------------- *)
1631 PROCEDURE hexDigit(d
: INTEGER) : CHAR;
1633 IF d
< 10 THEN RETURN CHR(d
+ ORD('
0'
))
1634 ELSE RETURN CHR(d
-10 + ORD('a'
));
1637 (* -------------------------------------- *)
1638 PROCEDURE AppendHex2D(r
: LitValue
.CharVector
; o
: INTEGER);
1642 APPEND(r
, hexDigit(o
DIV 16 MOD 16));
1643 APPEND(r
, hexDigit(o
MOD 16));
1645 (* -------------------------------------- *)
1646 PROCEDURE AppendUnicode(r
: LitValue
.CharVector
; o
: INTEGER);
1650 APPEND(r
, hexDigit(o
DIV 1000H
MOD 16));
1651 APPEND(r
, hexDigit(o
DIV 100H
MOD 16));
1652 APPEND(r
, hexDigit(o
DIV 10H
MOD 16));
1653 APPEND(r
, hexDigit(o
MOD 16));
1655 (* -------------------------------------- *)
1658 * Translate the string into ANSI-C like
1659 * for human, rather than machine consumption.
1661 NEW(rslt
, LEN(str
) * 2);
1663 FOR idx := 0 TO LEN(str) - 2 DO
1664 ord := ORD(str[idx]);
1666 | 0 : APPEND(rslt, '\');
1668 | 9 : APPEND(rslt, '\');
1670 | 10 : APPEND(rslt, '\');
1672 | 12 : APPEND(rslt, '\');
1678 IF ord > 0FFH THEN AppendUnicode(rslt, ord);
1679 ELSIF (ord > 07EH) OR (ord < ORD(' ')) THEN AppendHex2D(rslt, ord);
1680 ELSE APPEND(rslt, CHR(ord));
1686 RETURN LitValue
.chrVecToCharOpen(rslt
);
1689 PROCEDURE hexOf(ch
: CHAR) : CharOpen
;
1693 (* -------------------------------------- *)
1694 PROCEDURE hexDigit(d
: INTEGER) : CHAR;
1696 IF d
< 10 THEN RETURN CHR(d
+ ORD('
0'
))
1697 ELSE RETURN CHR(d
-10 + ORD('A'
));
1700 (* -------------------------------------- *)
1704 NEW(res
, 4); res
[3] := 0X
; res
[2] := "X";
1705 res
[1] := hexDigit(ord
MOD 16);
1706 res
[0] := hexDigit(ord
DIV 16);
1707 ELSIF ord
<= 0FFH
THEN
1708 NEW(res
, 5); res
[4] := 0X
; res
[3] := "X";
1709 res
[2] := hexDigit(ord
MOD 16);
1710 res
[1] := hexDigit(ord
DIV 16);
1712 ELSIF ord
<= 07FFFH
THEN
1713 NEW(res
, 10); res
[9] := 0X
; res
[8] := "X";
1714 FOR idx
:= 7 TO 0 BY
-1 DO
1715 res
[idx
] := hexDigit(ord
MOD 16); ord
:= ord
DIV 16;
1718 NEW(res
, 11); res
[10] := 0X
; res
[9] := "X";
1719 FOR idx
:= 8 TO 0 BY
-1 DO
1720 res
[idx
] := hexDigit(ord
MOD 16); ord
:= ord
DIV 16;
1726 (* ==================================================================== *)
1728 PROCEDURE LongToHex(n
: LONGINT) : CharOpen
;
1729 VAR arr
: ARRAY 40 OF CHAR;
1731 (* -------------------------------------- *)
1732 PROCEDURE hexDigit(d
: INTEGER) : CHAR;
1734 IF d
< 10 THEN RETURN CHR(d
+ ORD('
0'
))
1735 ELSE RETURN CHR(d
-10 + ORD('a'
));
1738 (* -------------------------------------- *)
1739 PROCEDURE DoDigit(n
: LONGINT;
1740 VAR a
: ARRAY OF CHAR;
1745 DoDigit(n
DIV 16, a
, i
);
1746 a
[i
] := hexDigit(SHORT(n
MOD 16)); INC(i
);
1749 a
[1] := hexDigit(SHORT(n
)); i
:= 2;
1751 a
[0] := hexDigit(SHORT(n
)); i
:= 1;
1754 (* -------------------------------------- *)
1757 DoDigit(n
, arr
, idx
);
1758 arr
[idx
] := 'H'
; INC(idx
); arr
[idx
] := 0X
;
1762 (* ==================================================================== *)
1764 PROCEDURE Length(a
: ARRAY OF CHAR) : INTEGER;
1768 WHILE (a
[i
] # 0X
) & (i
< LEN(a
)) DO INC(i
); END;
1772 PROCEDURE (v
: AbsValue
) Print(),NEW,EMPTY
;
1774 PROCEDURE (n
: NumValue
) Print();
1776 IF hexCon
& (n
.numVal
>= 0) THEN
1777 output
.WriteString(LongToHex(n
.numVal
));
1779 output
.WriteLong(n
.numVal
);
1783 PROCEDURE (f
: FltValue
) Print();
1785 str
: ARRAY 30 OF CHAR;
1787 RTS
.RealToStr(f
.fltVal
,str
);
1788 output
.WriteString(str
);
1791 PROCEDURE (s
: SetValue
) Print();
1796 (* ----------------------------------- *)
1797 PROCEDURE WriteRange(j
,k
:INTEGER; VAR f
: BOOLEAN);
1799 IF f
THEN f
:= FALSE
ELSE output
.Write('
,'
) END;
1803 |
1 : output
.Write('
,'
);
1805 ELSE output
.WriteString('
..'
);
1809 (* ----------------------------------- *)
1810 BEGIN (* this is an FSA with two states *)
1812 first
:= TRUE
; inSet
:= FALSE
; j
:= 0; k
:= 0;
1813 FOR i
:= 0 TO MAX(SET) DO
1815 IF i
IN s
.setVal
THEN k
:= i
;
1816 ELSE inSet
:= FALSE
; WriteRange(j
,k
,first
);
1819 IF i
IN s
.setVal
THEN inSet
:= TRUE
; j
:= i
; k
:= i
END;
1822 IF k
= MAX(SET) THEN WriteRange(j
,k
,first
) END;
1826 PROCEDURE (c
: ChrValue
) Print();
1828 IF (c
.chrVal
<= " ") OR (c
.chrVal
> 7EX
) THEN
1829 output
.WriteString(hexOf(c
.chrVal
));
1832 output
.Write(c
.chrVal
);
1837 PROCEDURE (s
: StrValue
) Print();
1839 output
.WriteString(qStrOf(s
.strVal
));
1842 PROCEDURE (b
: BoolValue
) Print();
1845 output
.WriteString("TRUE");
1847 output
.WriteString("FALSE");
1851 PROCEDURE (t
: Type
) PrintType(indent
: INTEGER),NEW,EMPTY
;
1853 PROCEDURE (t
: Type
) Print(indent
: INTEGER;details
: BOOLEAN),NEW,EXTENSIBLE
;
1855 IF t
.importedFrom
# NIL THEN
1856 IF t
.importedFrom
= output
.thisMod
THEN
1857 output
.WriteKeyword(t
.importedName
);
1859 output
.WriteImportedTypeName(t
.importedFrom
, t
.importedName
);
1864 IF ~details
& (t
.declarer
# NIL) THEN
1865 output
.WriteTypeName(t
.declarer
.name
);
1867 t
.PrintType(indent
);
1871 PROCEDURE (b
: Basic
) Print(indent
: INTEGER; details
: BOOLEAN);
1873 output
.WriteString(b
.name
);
1876 PROCEDURE^
PrintList(indent
: INTEGER; dl
: DescList
; xLine
: BOOLEAN);
1878 PROCEDURE (e
: Enum
) PrintType(indent
: INTEGER),EXTENSIBLE
;
1882 output
.WriteKeyword("ENUM"); output
.WriteLn
;
1883 PrintList(indent
+2,e
.ids
,FALSE
);
1884 output
.Indent(indent
);
1885 output
.WriteKeyword("END");
1888 PROCEDURE printBaseType(r
: Record
) : BOOLEAN;
1892 IF r
.intrFaces
.tide
# 0 THEN RETURN TRUE
END;
1893 IF (r
.baseType
# NIL) & ~
(r
.baseType
IS Basic
) THEN
1894 IF (r
.baseType
IS Pointer
) THEN
1895 RETURN ~r
.baseType(Pointer
).isAnonPointer
;
1897 IF (r
.baseType
IS Record
) & (r
.baseType(Record
).isAnonRec
) THEN
1898 pType
:= r
.baseType(Record
).ptrType
;
1899 IF (pType
= NIL) OR (pType
.isAnonPointer
) THEN
1908 PROCEDURE (r
: Record
) PrintType(indent
: INTEGER),EXTENSIBLE
;
1910 eStr
= "EXTENSIBLE ";
1913 iStr
= "INTERFACE ";
1914 vStr
= "(* vlCls *) ";
1915 nStr
= "(* noNew *) ";
1917 rStr
: ARRAY 12 OF CHAR;
1924 PROCEDURE maxFldLen(r
: Record
) : INTEGER;
1925 VAR j
,l
,m
: INTEGER;
1928 FOR j
:= 0 TO r
.fields
.tide
-1 DO
1929 l
:= LEN(r
.fields
.list
[j
].name$
);
1935 PROCEDURE fieldNumber(VAR lst
: DescList
) : INTEGER;
1936 VAR count
: INTEGER;
1939 FOR count
:= 0 TO lst
.tide
- 1 DO
1940 IF lst
.list
[count
] IS ProcDesc
THEN RETURN count
END;
1946 CASE r
.recAtt
MOD 8 OF
1954 IF r
.recAtt
DIV 8 = 1 THEN output
.WriteString(nStr
);
1955 ELSIF r
.recAtt
DIV 16 = 1 THEN output
.WriteString(vStr
);
1958 output
.WriteKeyword(rStr
+ "RECORD");
1959 IF printBaseType(r
) THEN
1960 output
.WriteString(" (");
1961 IF (r
.baseType
IS Record
) & (r
.baseType(Record
).ptrType
# NIL) THEN
1962 r
.baseType(Record
).ptrType
.Print(0,FALSE
);
1963 ELSIF r
.baseType
= NIL THEN
1964 output
.WriteString("ANYPTR");
1966 r
.baseType
.Print(0,FALSE
);
1969 FOR i
:= 0 TO r
.intrFaces
.tide
-1 DO
1970 output
.WriteString(" + ");
1971 iTyp
:= r
.intrFaces
.list
[i
](TypeDesc
).type
;
1972 IF (iTyp
IS Record
) & (iTyp(Record
).ptrType
# NIL) THEN
1973 iTyp(Record
).ptrType
.Print(0,FALSE
);
1975 iTyp
.Print(0,FALSE
);
1979 output
.WriteString(")");
1983 IF r
.methods
.tide
> 0 THEN
1984 IF r
.declarer
# NIL THEN
1985 output
.MethRef(r
.declarer
.name
);
1986 ELSIF (r
.ptrType
# NIL) & (r
.ptrType
.declarer
# NIL) THEN
1987 output
.MethRef(r
.ptrType
.declarer
.name
);
1993 fLen
:= maxFldLen(r
);
1994 FOR i
:= 0 TO r
.fields
.tide
-1 DO
1995 output
.Indent(indent
+2);
1996 output
.WriteIdent(r
.fields
.list
[i
].name
);
1997 output
.Write(accArray
[r
.fields
.list
[i
].access
]);
1998 output
.Indent(fLen
- LEN(r
.fields
.list
[i
].name$
));
1999 output
.WriteString(" : ");
2000 r
.fields
.list
[i
](VarDesc
).type
.Print(indent
+ fLen
+ 6, FALSE
);
2001 output
.Write('
;'
); output
.WriteLn
;
2003 IF r
.statics
.tide
> 0 THEN
2005 sLen
:= r
.statics
.tide
- 1;
2006 fNum
:= fieldNumber(r
.statics
);
2007 IF fNum
> 1 THEN QuickSortDescs(0, fNum
-1, r
.statics
) END;
2008 IF fNum
< sLen
THEN QuickSortDescs(fNum
, sLen
, r
.statics
) END;
2010 output
.Indent(indent
);
2011 output
.WriteKeyword("STATIC"); output
.WriteLn
;
2012 PrintList(indent
+2, r
.statics
, FALSE
);
2014 output
.Indent(indent
);
2015 output
.WriteKeyword("END");
2018 PROCEDURE (a
: Array
) PrintType(indent
: INTEGER),EXTENSIBLE
;
2020 output
.WriteKeyword("ARRAY ");
2021 IF a
.size
> 0 THEN output
.WriteInt(a
.size
); output
.Write(' '
); END;
2022 output
.WriteKeyword("OF ");
2023 a
.elemType
.Print(indent
,FALSE
);
2026 PROCEDURE (a
: Vector
) PrintType(indent
: INTEGER),EXTENSIBLE
;
2028 output
.WriteKeyword("VECTOR ");
2029 output
.WriteKeyword("OF ");
2030 a
.elemType
.Print(indent
,FALSE
);
2033 PROCEDURE PrintPar(p
: Par
; num
, indent
, pLen
: INTEGER; noModes
: BOOLEAN);
2034 VAR extra
: INTEGER;
2037 output
.Indent(indent
);
2041 |
1 : output
.WriteString("IN ");
2042 |
2 : output
.WriteString("OUT ");
2043 |
3 : output
.WriteString("VAR ");
2044 ELSE output
.WriteString(" ");
2047 IF p
.opNm
= NIL THEN
2048 output
.WriteString("p");
2049 output
.WriteInt(num
);
2050 IF num
> 9 THEN output
.Indent(pLen
-3) ELSE output
.Indent(pLen
-2) END;
2052 output
.WriteString(p
.opNm
);
2053 output
.Indent(pLen
- LEN(p
.opNm$
));
2055 output
.WriteString(" : ");
2056 p
.type
.Print(indent
+extra
,FALSE
);
2059 PROCEDURE PrintFormals(p
: Proc
; indent
: INTEGER);
2064 PROCEDURE maxParLen(p
: Proc
) : INTEGER;
2065 VAR j
,l
,m
: INTEGER;
2068 FOR j
:= 0 TO p
.pars
.tide
-1 DO
2069 IF p
.pars
.list
[j
].opNm
# NIL THEN
2070 l
:= LEN(p
.pars
.list
[j
].opNm$
);
2083 IF p
.pars
.tide
> 0 THEN
2084 pLen
:= maxParLen(p
);
2085 PrintPar(p
.pars
.list
[0],0,0, pLen
, p
.noModes
);
2086 FOR i
:= 1 TO p
.pars
.tide
-1 DO
2089 PrintPar(p
.pars
.list
[i
], i
, indent
+1, pLen
, p
.noModes
);
2093 IF p
.retType
# NIL THEN
2094 output
.WriteString('
: '
);
2095 p
.retType
.Print(indent
,FALSE
);
2099 (* ----------------------------------------------------------- *)
2101 PROCEDURE (p
: Proc
) PrintType(indent
: INTEGER),EXTENSIBLE
;
2103 output
.WriteKeyword("PROCEDURE");
2104 PrintFormals(p
, indent
+9);
2107 (* ----------------------------------------------------------- *)
2109 PROCEDURE (p
: Proc
) PrintProc(indent
: INTEGER),NEW;
2111 output
.Indent(indent
);
2112 output
.WriteKeyword("PROCEDURE ");
2113 output
.WriteIdent(p
.declarer
.name
);
2114 output
.Write(accArray
[p
.declarer
.access
]);
2115 IF printFNames
& (p
.fName
# NIL) THEN
2116 output
.WriteString('
["' + p.fName^ + '"]'
);
2117 INC(indent
,Length(p
.fName
)+4);
2119 PrintFormals(p
,indent
+11+Length(p
.declarer
.name
));
2120 IF p
.isConstructor
THEN output
.WriteKeyword(",CONSTRUCTOR"); END;
2121 output
.WriteString(";"); output
.WriteLn
;
2124 (* ----------------------------------------------------------- *)
2126 PROCEDURE (m
: Meth
) PrintType(indent
: INTEGER),EXTENSIBLE
;
2129 output
.WriteKeyword("PROCEDURE ");
2131 IF m
.recMode
= 1 THEN
2132 output
.WriteString("IN ");
2134 ELSIF m
.recMode
= 3 THEN
2135 output
.WriteString("VAR ");
2138 IF m
.recName
= NIL THEN
2139 output
.WriteString("self");
2142 output
.WriteString(m
.recName
);
2143 INC(indent
,LEN(m
.recName$
));
2145 output
.WriteString(":");
2146 ASSERT(m
.receiver
.importedFrom
= NIL);
2147 output
.WriteString(m
.receiver
.declarer
.name
);
2148 output
.WriteString(") ");
2149 output
.WriteIdent(m
.declarer
.name
);
2150 output
.Write(accArray
[m
.declarer
.access
]);
2151 IF printFNames
& (m
.fName
# NIL) THEN
2152 output
.WriteString('
["' + m.fName^ + '"]'
);
2153 INC(indent
,Length(m
.fName
)+4);
2155 PrintFormals(m
, indent
+ 15 +
2156 Length(m
.declarer
.name
)+
2157 Length(m
.receiver
.declarer
.name
));
2160 |
1 : output
.WriteKeyword(",NEW");
2161 |
2 : output
.WriteKeyword(",ABSTRACT");
2162 |
3 : output
.WriteKeyword(",NEW,ABSTRACT");
2163 |
4 : output
.WriteKeyword(",EMPTY");
2164 |
5 : output
.WriteKeyword(",NEW,EMPTY");
2165 |
6 : output
.WriteKeyword(",EXTENSIBLE");
2166 |
7 : output
.WriteKeyword(",NEW,EXTENSIBLE");
2169 output
.WriteString(";"); output
.WriteLn
;
2172 PROCEDURE (p
: Pointer
) PrintType(indent
: INTEGER),EXTENSIBLE
;
2174 output
.WriteKeyword("POINTER TO ");
2175 p
.baseType
.Print(indent
,FALSE
);
2178 PROCEDURE (p
: Event
) PrintType(indent
: INTEGER);
2180 output
.WriteKeyword("EVENT");
2181 PrintFormals(p
, indent
+5);
2184 PROCEDURE PrintList(indent
: INTEGER; dl
: DescList
; xLine
: BOOLEAN);
2189 (* ----------------------------------------------- *)
2190 PROCEDURE notHidden(d
: Desc
) : BOOLEAN;
2192 RETURN verbatim
OR ((d
.name
[0] # "@") & (d
.name
[0] # "$"));
2194 (* ----------------------------------------------- *)
2195 PROCEDURE maxNamLen(dl
: DescList
) : INTEGER;
2196 VAR j
,l
,m
: INTEGER;
2200 FOR j
:= 0 TO dl
.tide
-1 DO
2202 IF notHidden(d
) THEN m
:= MAX(m
, LEN(d
.name$
)) END;
2206 (* ----------------------------------------------- *)
2209 FOR i
:= 0 TO dl
.tide
-1 DO
2211 IF ~
notHidden(d
) THEN
2213 ELSIF d
IS ProcDesc
THEN
2214 d(ProcDesc
).pType
.PrintProc(indent
);
2215 IF xLine
THEN output
.WriteLn
; END;
2217 output
.Indent(indent
);
2218 IF d
IS TypeDesc
THEN
2219 output
.WriteTypeDecl(d
.name
);
2221 output
.WriteIdent(d
.name
);
2223 output
.Write(accArray
[d
.access
]);
2225 IF (d
IS VarDesc
) OR (d
IS ConstDesc
) THEN
2226 output
.Indent(m
- LEN(d
.name$
));
2229 WITH d
: ConstDesc
DO
2230 output
.WriteString(" = ");
2233 IF d
IS VarDesc
THEN
2234 output
.WriteString(" : ");
2236 output
.WriteString(" = ");
2238 d
.type
.Print(Length(d
.name
)+6, d
IS UserTypeDesc
);
2242 IF xLine
THEN output
.WriteLn
; END;
2247 (* ==================================================================== *)
2249 PROCEDURE PrintDigest(i0
,i1
: INTEGER);
2250 VAR buffer
: ARRAY 17 OF CHAR;
2252 (* ------------------------------------ *)
2253 PROCEDURE hexRep(i
: INTEGER) : CHAR;
2255 i
:= ORD(BITS(i
) * {0..3});
2256 IF i
<= 9 THEN RETURN CHR(ORD("0") + i
);
2257 ELSE RETURN CHR(ORD("A") - 10 + i
);
2260 (* ------------------------------------ *)
2262 IF (i0
= 0) & (i1
= 0) THEN RETURN END;
2263 output
.Write(" "); output
.Write("[");
2264 FOR index
:= 7 TO 0 BY
-1 DO
2265 buffer
[index
] := hexRep(i0
); i0
:= i0
DIV 16;
2267 FOR index
:= 15 TO 8 BY
-1 DO
2268 buffer
[index
] := hexRep(i1
); i1
:= i1
DIV 16;
2271 output
.WriteString(buffer
);
2275 (* ==================================================================== *)
2277 PROCEDURE PrintModule(mod
: Module
);
2283 heading
: ARRAY 20 OF CHAR;
2284 (* --------------------------- *)
2285 PROCEDURE WriteOptionalExtras(impMod
: Module
);
2287 IF impMod
.fName
# NIL THEN
2289 output
.WriteString('
(* "' + impMod.fName^ + '" *)'
);
2291 output
.WriteString('
:= "' + impMod.fName^ + '"'
);
2294 END WriteOptionalExtras
;
2295 (* --------------------------- *)
2298 IF (mod
.types
.tide
> 0) & alpha
THEN
2299 QuickSortDescs(0, mod
.types
.tide
-1, mod
.types
);
2302 output
.WriteStart(mod
);
2303 IF mod
.systemMod
THEN
2304 heading
:= "SYSTEM ";
2305 ELSIF mod
.fName
# NIL THEN
2306 heading
:= "FOREIGN ";
2310 heading
:= heading
+ "MODULE ";
2311 output
.WriteKeyword(heading
);
2312 output
.WriteIdent(mod
.name
);
2313 IF printFNames
& (mod
.fName
# NIL) THEN
2314 output
.WriteString('
["' + mod.fName^ + '"]'
);
2318 * Optional strong name goes here.
2320 IF mod
.strongNm
# NIL THEN
2322 output
.WriteString(" (* version ");
2323 output
.WriteInt(mod
.strongNm
[0]); output
.Write(":");
2324 output
.WriteInt(mod
.strongNm
[1]); output
.Write(":");
2325 output
.WriteInt(mod
.strongNm
[2]); output
.Write(":");
2326 output
.WriteInt(mod
.strongNm
[3]);
2327 PrintDigest(mod
.strongNm
[4], mod
.strongNm
[5]);
2328 output
.WriteString(" *)");
2330 (* end optional strong name. *)
2331 output
.WriteLn
; output
.WriteLn
;
2332 IF mod
.imports
.tide
> 1 THEN
2333 output
.WriteKeyword("IMPORT"); output
.WriteLn
;
2335 output
.WriteImport(mod
.imports
.list
[1]);
2336 WriteOptionalExtras(mod
.imports
.list
[1]);
2337 FOR i
:= 2 TO mod
.imports
.tide
-1 DO
2338 output
.Write('
,'
); output
.WriteLn
;
2340 output
.WriteImport(mod
.imports
.list
[i
]);
2341 WriteOptionalExtras(mod
.imports
.list
[i
]);
2343 output
.Write('
;'
); output
.WriteLn
;
2346 IF mod
.consts
.tide
> 0 THEN
2347 output
.WriteKeyword("CONST"); output
.WriteLn
;
2348 PrintList(2,mod
.consts
,FALSE
);
2351 IF mod
.types
.tide
> 0 THEN
2352 output
.WriteKeyword("TYPE");
2353 output
.WriteLn
; output
.WriteLn
;
2354 PrintList(2,mod
.types
,TRUE
);
2357 IF mod
.vars
.tide
> 0 THEN
2358 output
.WriteKeyword("VAR"); output
.WriteLn
;
2359 PrintList(2,mod
.vars
,FALSE
);
2362 FOR i
:= 0 TO mod
.procs
.tide
-1 DO
2364 mod
.procs
.list
[i
](ProcDesc
).pType
.PrintProc(0);
2367 FOR i
:= 0 TO mod
.types
.tide
-1 DO
2368 ty
:= mod
.types
.list
[i
](UserTypeDesc
).type
;
2369 IF ty
IS Pointer
THEN ty
:= ty(Pointer
).baseType
; END;
2370 IF ty
IS Record
THEN
2373 IF (rec
.methods
.tide
> 0) & alpha
THEN
2374 QuickSortDescs(0, rec
.methods
.tide
-1, rec
.methods
);
2378 IF rec
.methods
.tide
> 0 THEN
2379 IF rec
.declarer
# NIL THEN
2380 output
.MethAnchor(rec
.declarer
.name
);
2381 ELSIF (rec
.ptrType
# NIL) & (rec
.ptrType
.declarer
# NIL) THEN
2382 output
.MethAnchor(rec
.ptrType
.declarer
.name
);
2387 FOR j
:= 0 TO rec
.methods
.tide
-1 DO
2388 rec
.methods
.list
[j
](ProcDesc
).pType
.PrintType(0);
2393 output
.WriteKeyword("END ");
2394 output
.WriteIdent(mod
.name
);
2395 output
.Write("."); output
.WriteLn
;
2399 (* ============================================================ *)
2401 PROCEDURE InitTypes();
2407 NEW(t
); t
.name
:= BOX("BOOLEAN"); typeList
[1] := t
;
2408 NEW(t
); t
.name
:= BOX("SHORTCHAR"); typeList
[2] := t
;
2409 NEW(t
); t
.name
:= BOX("CHAR"); typeList
[3] := t
;
2410 NEW(t
); t
.name
:= BOX("BYTE"); typeList
[4] := t
;
2411 NEW(t
); t
.name
:= BOX("SHORTINT"); typeList
[5] := t
;
2412 NEW(t
); t
.name
:= BOX("INTEGER"); typeList
[6] := t
;
2413 NEW(t
); t
.name
:= BOX("LONGINT"); typeList
[7] := t
;
2414 NEW(t
); t
.name
:= BOX("SHORTREAL"); typeList
[8] := t
;
2415 NEW(t
); t
.name
:= BOX("REAL"); typeList
[9] := t
;
2416 NEW(t
); t
.name
:= BOX("SET"); typeList
[10] := t
;
2417 NEW(t
); t
.name
:= BOX("ANYREC"); typeList
[11] := t
;
2418 NEW(t
); t
.name
:= BOX("ANYPTR"); typeList
[12] := t
;
2419 NEW(t
); t
.name
:= BOX("ARRAY OF CHAR"); typeList
[13] := t
;
2420 NEW(t
); t
.name
:= BOX("ARRAY OF SHORTCHAR"); typeList
[14] := t
;
2421 NEW(t
); t
.name
:= BOX("UBYTE"); typeList
[15] := t
;
2423 * NEW(t); t.name := "SPECIAL"; typeList[16] := t;
2427 PROCEDURE InitAccArray();
2435 (* ============================================================ *)
2439 Console
.WriteString("gardens point Browse: " + GPCPcopyright
.verStr
);
2441 IF RTS
.defaultTarget
= "net" THEN
2442 Console
.WriteString("Usage: Browse [options] <ModuleName>");
2444 Console
.WriteString("Browse Options ... ");
2446 Console
.WriteString(" /all ==> browse this and all imported modules");
2448 Console
.WriteString(" /file ==> write output to a file <ModuleName>.bro ");
2450 Console
.WriteString(" /full ==> display explicit foreign names ");
2452 Console
.WriteString(" /help ==> display this usage message");
2454 Console
.WriteString(" /hex ==> use hexadecimal for short literals");
2456 Console
.WriteString(
2457 " /html ==> write html output to file <ModuleName>.html");
2459 Console
.WriteString(" /sort ==> sort procedures and types alphabetically");
2461 Console
.WriteString(" /verbatim ==> display anonymous public type names");
2463 ELSE (* RTS.defaultTarget = "jvm" *)
2464 Console
.WriteString("Usage: cprun Browse [options] <ModuleName>");
2466 Console
.WriteString("Browse Options ... ");
2468 Console
.WriteString(" -all ==> browse this and all imported modules");
2470 Console
.WriteString(" -file ==> write output to a file <ModuleName>.bro ");
2472 Console
.WriteString(" -full ==> display explicit foreign names ");
2474 Console
.WriteString(" -help ==> display this usage message");
2476 Console
.WriteString(" -hex ==> use hexadecimal for short literals");
2478 Console
.WriteString(
2479 " -html ==> write html output to file <ModuleName>.html");
2481 Console
.WriteString(" -sort ==> sort procedures and types alphabetically");
2483 Console
.WriteString(" -verbatim ==> display anonymous public type names");
2489 PROCEDURE BadOption(optStr
: ARRAY OF CHAR);
2491 Console
.WriteString("Unrecognised option: " + optStr
);
2495 PROCEDURE ParseOptions() : INTEGER;
2498 option
: FileNames
.NameString
;
2499 fOutput
: FileOutput
;
2500 hOutput
: HtmlOutput
;
2501 fileOutput
, htmlOutput
: BOOLEAN;
2503 printFNames
:= FALSE
;
2504 fileOutput
:= FALSE
;
2505 htmlOutput
:= FALSE
;
2511 ProgArgs
.GetArg(argNo
,option
);
2512 WHILE (option
[0] = '
-'
) OR (option
[0] = GPFiles
.optChar
) DO
2515 IF option
[1] = 'f'
THEN
2516 IF option
= "-full" THEN
2517 printFNames
:= TRUE
;
2518 ELSIF option
= "-file" THEN
2520 Console
.WriteString("Cannot have html and file output");
2530 ELSIF option
[1] = 'v'
THEN
2531 IF option
= "-verbatim" THEN
2533 ELSIF option
= "-verbose" THEN
2538 ELSIF option
= "-all" THEN
2540 ELSIF option
= "-hex" THEN
2542 ELSIF option
= "-html" THEN
2544 Console
.WriteString("Cannot have html and file output");
2551 ELSIF option
= "-sort" THEN
2553 ELSIF option
= "-help" THEN
2558 IF argNo
< args
THEN ProgArgs
.GetArg(argNo
,option
) ELSE RETURN argNo
END;
2567 FOR i
:= 0 TO modList
.tide
-1 DO
2568 IF modList
.list
[i
].print
THEN
2569 output
.thisMod
:= modList
.list
[i
];
2570 IF output
IS FileOutput
THEN
2571 output(FileOutput
).file
:=
2572 GPTextFiles
.createFile(modList
.list
[i
].name^
+ outExt
);
2574 PrintModule(modList
.list
[i
]);
2575 IF output
IS FileOutput
THEN
2576 GPTextFiles
.CloseFile(output(FileOutput
).file
);
2581 Error
.WriteString("Error in Parse()"); Error
.WriteLn
;
2582 Error
.WriteString(RTS
.getStr(x
)); Error
.WriteLn
;
2591 NEW(modList
.list
,5);
2593 args
:= ProgArgs
.ArgNumber();
2594 IF (args
< 1) THEN Usage(); END;
2595 argNo
:= ParseOptions();
2596 IF (output
IS FileOutput
) THEN
2597 IF (output
IS HtmlOutput
) THEN
2603 WHILE (argNo
< args
) DO
2604 ProgArgs
.GetArg(argNo
,fileName
);
2605 GetSymAndModNames(fileName
,modName
);
2606 module
:= GetModule(modName
);
2607 module
.symName
:= fileName
;
2608 module
.progArg
:= TRUE
;
2615 (* ============================================================ *)