home *** CD-ROM | disk | FTP | other *** search
- {THIS PROGRAM ALLOWS EXAMINATION OF THE SYMBOL TABLE GENERATED BY TURBO
- VERSION 3.00B. IT EXAMINES THE TABLE GENERATED WHEN IT IS COMPILED.
- THE SYMBOL TABLE RESIDES IN SSEG JUST FAR ENOUGH BELOW THE STACK THAT THE
- TWO DON'T INTERFERE. IT IS SCANNED FROM LOWER MEMORY IN LARGE CHUNKS, EACH
- OF WHICH STARTS WITH A COUNT FOR THAT CHUNK TO ALLOW JUMPING OVER INFO
- THAT IS NOT WANTED. HOWEVER, EACH CHUNK IS SCANNED BACKWARDS (FROM HIGHER
- TO LOWER MEMORY). AN EXCEPTION IS THE SYMBOL NAMES THEMSELVES WHICH ARE
- IN A FORWARD DIRECTION ( BUT THE LENGTH BYTE IS AT THE UPPER MEMORY END).
-
- THIS PROGRAM ATTEMPTS TO MAKE THE INFORMATION IN THE TABLE MORE CLEAR.
- EACH CHUNK IS SCANNED BACKWARDS BUT THE INFORMATION IS OUTPUT FROM LEFT TO
- RIGHT. SYMBOL NAMES ARE OUTPUT SO THAT THEY CORRESPOND TO THE PROGRAM
- SYMBOLS.
-
- THE FIRST HEX VALUE OUTPUT DOES NOT APPEAR IN THE SYMBOL TABLE BUT RATHER
- IS THE OFFSET OF THAT SYMBOL TABLE ITEM IN SSEG. IT IS OFTEN USED AS A
- POINTER FROM WITHIN OTHER SYMBOL TABLE ITEMS. FOR INSTANCE, A VARIABLE OF
- TYPE INTEGER WILL HAVE WITHIN ITS DEFINITION A POINTER TO THE DEFINITION
- OF TYPE INTEGER.
-
- NEXT ON THE LINE IS A WORD DEFINING THE SYMBOL TABLE ITEM TYPE (PROCEDURE,
- FUNCTION, VARIABLE, TYPE DEFINITION, CONST, ETC). THE HIGH BYTE OF THIS
- WORD DETERMINES THE TYPE. THE LOW BYTE IS USUALLY ZERO EXCEPT FOR RECORDS
- WHERE IT APPEARS TO DEFINE WHICH RECORD THE SYMBOL BELONGS TO. SEE THE
- CASE STATEMENT IN 'MAIN' FOR WHICH SYMBOL TYPES HAVE WHICH NUMBERS.
-
- IF THE SYMBOL TYPE HAS A SYMBOL, THE NEXT BYTE IS THE SYMBOL LENGTH AND
- THIS IS FOLLOWED BY THE SYMBOL NAME ITSELF.
-
- MORE INFORMATION ON WHAT IS WHAT CAN BE FOUND IN THE CODE COMMENTS.
-
- THE VERY LAST ITEM ON THE LINE IS THE COUNT OF BYTES FOR THAT ITEM.
-
- NOTE THAT ALL ITEMS APPEARING AFTER THE 'INTEGER' SYMBOL DEFINITION APPEAR
- IN THE TABLE FOR EVERY COMPILATION. THEY ARE COPIED THERE IN ONE BLOCK.
-
- THE LAST TEN LINES REPRESENT STANDARD TYPE DEFINITIONS. THESE ARE:
- INTEGER
- CHAR
- REAL
- BOOLEAN
- FILE
- BYTE
- POINTER
- UNKNOWN
- UNKNOWN
- UNKNOWN
-
- AS COMPILATION TAKES PLACE, THE SYMBOL INFORMATION FOR LOCAL VARIABLES,
- LOCAL PROCEDURES, AND OTHER LOCALS IS ENTERED IN THE SYMBOL TABLE. HOWEVER,
- THIS INFORMATION IS OVERWRITTEN AS SOON AS IT IS NO LONGER NEEDED, SO THAT
- IT IS NOT AVAIABLE WHEN COMPILATION IS COMPLETE.
- }
- PROGRAM EXAMINE;
- LABEL 99;
- {THE FOLLOWING THREE CONSTANTS ARE THOSE NEEDED TO EXTRACT THE SYMBOLS
- AND MAY WELL BE DIFFERENT FOR VERSION OTHER THAN 3.00B.}
- CONST
- TURBO_DS=$178; {OFFSET REL TO PROGRAM DSEG WHICH CONTAINS THE
- COMPILER DSEG}
- SYMBOL_START=$598; {OFFSET REL TO COMPILER DSEG CONTAINING THE OFFSET OF THE
- SYMBOL TABLE START (RELATIVE TO SSEG)}
- SYMBOL_END=$59A; {OFFSET REL TO COMPILER DSEG CONTAINING THE OFFSET OF THE
- SYMBOL TABLE END (RELATIVE TO SSEG)}
- {THE FOLLOWING CONST's, TYPE's AND VAR's ARE NECESSARY FOR THE OPERATION OF
- THE PROGRAM}
- TYPE STRING30=STRING[30];
- VAR TURB_DS,SYMTYPE,COUNT,SYMLENG,
- SYMINDX,ENDSYM,NEXTSYM,OLDSYMINDX :INTEGER;
- NAME :STRING30;
- OUT :TEXT;
- {END OF NECESSARY ITEMS}
-
- {BELOW IS AN AREA WHERE TYPES, CONST's, VAR's,PROCEDURE's AND FUNCTION's
- MAY BE ADDED TO SEE WHAT APPEARS IN THE SYMBOL TABLE}
-
- {DEFINE SOME TYPED CONSTANTS FOR OBSERVATION}
- CONST
- CINT :INTEGER = $ABCD;
- CSTRING :STRING[20] = 'STRING';
- TYPE RECTYPE=RECORD ABC,DEF,GHI :INTEGER; END;
- RECTYPE2=RECORD ABC,DEF,GHI :INTEGER; END;
- VARREC =RECORD
- BBB,BBBB :BYTE;
- CASE VA :INTEGER OF
- 2,3 :(PDQ :BYTE;
- RST :INTEGER;);
- 8 :(XYZ :CHAR;
- OTHER :INTEGER);
- END;
- ARTYPE =ARRAY[-5..11] OF CHAR;
- ABC=(A,B,C,D,E,F);
- VAR REC :RECTYPE;
- VAR XX :ABC;
- REC2 :RECTYPE2;
- VREC :VARREC;
- ARY :ARTYPE;
- ARYPTR :^ARTYPE;
- PT :^INTEGER;
- ARRAY1 :ARRAY[A..E] OF INTEGER;
- ARRAY2 :ARRAY[-1..4,1..5] OF INTEGER;
- ARRAY3 :ARRAY[-1..4,-5..5,-1..2] OF INTEGER;
- CPT :^CHAR;
- FUNCTION DUMMY(VAR XX :BYTE):REAL;
- BEGIN END;
-
- {END OF EXPERIMENTAL AREA}
-
- {-------------SPACE}
- PROCEDURE SPACE(N :INTEGER); {OUTPUT N SPACES}
- VAR I :INTEGER;
- BEGIN
- FOR I:=1 TO N DO WRITE(OUT,' ');
- END;
-
- {-------------DONAME}
- PROCEDURE DONAME; {OUTPUT SYMBOL NAME}
- VAR I,J :INTEGER;
- BEGIN
- J:=1;
- FOR I:=SYMINDX-SYMLENG+1 TO SYMINDX DO
- BEGIN
- WRITE(OUT,CHR(MEM[SSEG:I])); J:=J+1;
- END;
- WHILE J<=16 DO BEGIN SPACE(1); J:=J+1; END;
- SYMINDX:=SYMINDX-SYMLENG;
- END;
-
- {-------------WRITEHEX2}
- PROCEDURE WRITEHEX2(N :BYTE);
- {WRITE A BYTE IN HEX}
- VAR BY :BYTE;
- CH :CHAR;
- I :INTEGER;
- BEGIN
- FOR I:=1 TO 2 DO
- BEGIN
- BY:=N SHR 4;
- IF BY<=9 THEN CH:=CHR(BY+ORD('0'))
- ELSE CH:=CHR(BY-10+ORD('A'));
- WRITE(OUT,CH);
- N:=N SHL 4;
- END;
- END;
-
- {-------------WRITEHEX4}
- PROCEDURE WRITEHEX4(N :INTEGER);
- {WRITE A WORD IN HEX}
- BEGIN
- WRITEHEX2(HI(N)); WRITEHEX2(LO(N));
- END;
-
- {-------------OUT2}
- PROCEDURE OUT2; {OUTPUT THE NEXT BYTE, UPDATE SYMINDX}
- BEGIN
- WRITEHEX2(MEM[SSEG:SYMINDX]); SPACE(1);
- SYMINDX:=SYMINDX-1;
- END;
-
- {-------------OUT4}
- PROCEDURE OUT4; {OUTPUT THE NEXT WORD, UPDATE SYMINDX}
- BEGIN
- WRITEHEX4(MEMW[SSEG:SYMINDX-1]); SPACE(1);
- SYMINDX:=SYMINDX-2;
- END;
-
- {-------------FINISH_PROC_FUNC}
- PROCEDURE FINISH_PROC_FUNC; {FINISH UP PROCEDURE, FUNCTIONS SYMTYPES}
- VAR NDUMMIES,I :INTEGER;
- BEGIN
- WRITELN(OUT); SPACE(10);
- OUT4; {OFFSET IN CSEG FOR PROC/FUNC}
- OUT4; {6+SPACE OCCUPIED BY PARAMETERS + LOCALS}
- OUT2; OUT2; OUT2; OUT2; OUT2; {???}
- NDUMMIES:=MEM[SSEG:SYMINDX]; {THE # OF DUMMY PARAMETERS}
- OUT2; {THE # OF DUMMY PARAMETERS}
- FOR I:=1 TO NDUMMIES DO
- BEGIN
- WRITELN(OUT); SPACE(14);
- OUT4; {PTS TO TYPE DEFINITION OF DUMMY}
- OUT2; {0, DUMMY IS BY VALUE--FF, DUMMY IS BY ADDRESS}
- OUT2; {??}
- SYMLENG:=MEM[SSEG:SYMINDX];
- OUT2; {LENGTH OF DUMMY NAME}
- DONAME; {DUMMY PARAMETER NAME}
- END;
- END;
-
- {-------------MAIN}
- BEGIN
- WRITE('Output Filename? '); READLN(NAME);
- ASSIGN(OUT, NAME);
- REWRITE(OUT);
- TURB_DS:=MEMW[DSEG:TURBO_DS]; {DSEG FOR THE COMPILER}
- SYMINDX:=MEMW[TURB_DS:SYMBOL_START]; {INITIATE SYMBOL INDEX}
- ENDSYM:=MEMW[TURB_DS:SYMBOL_END];
- OLDSYMINDX:=SYMINDX;
- WHILE SYMINDX<ENDSYM DO
- BEGIN
- COUNT:=MEMW[SSEG:SYMINDX]; {BYTE COUNT OF THIS SYMBOL ITEM}
- NEXTSYM:=SYMINDX+COUNT; {KEEP TRACK OF WHERE NEXT SYMBOL ITEM STARTS}
- SYMINDX:=NEXTSYM-2; {THE ADDRESS OF THIS SYMBOL ITEM}
- WRITEHEX4(SYMINDX); WRITE(OUT,'-');
- SYMTYPE:=MEMW[SSEG:SYMINDX]; {THE SYMBOL TYPE CODE. SEE BELOW FOR LIST}
- WRITEHEX4(SYMTYPE); SPACE(1);
- SYMINDX:=SYMINDX-1;
- IF (HI(SYMTYPE)<>0) AND (HI(SYMTYPE)<>8) THEN
- BEGIN
- SYMLENG:=MEM[SSEG:SYMINDX]; {LENGTH IN BYTES OF THE SYMBOL NAME}
- OUT2;
- DONAME;
- END;
-
- CASE HI(SYMTYPE) OF
- 8, {STRING}
- 0: BEGIN {TYPE DEFINITION}
- OUT4; {SIZEOF}
- OUT4; {UPPER LIMIT, DON'T CARE FOR POINTER}
- OUT4; {LOWER LIMIT, TYPE POINTED TO FOR POINTER}
- OUT2; {STORED AS A WORD BUT SEEM TO BE SEPARATE, USE UNKNOWN}
- OUT2; {4 FOR POINTER, BYTE SEEMS TO INDICATE TYPE}
- END;
- 1: {LABEL}
- OUT4; {OFFSET IN CSEG OF LABEL}
- 2: BEGIN {CONSTANTS}
- OUT2; {BYTE REPRESENTING TYPE??. SEEMS TO CORRESPOND TO BYTE
- IN TYPE DEFINITION}
- OUT4; {VALUE (WORD FOR INTEGER BUT CAN BE STRING OR REAL)}
- END;
- 3: {TYPE NAME}
- OUT4; {PTS TO TYPE DEFINITION}
- 4: BEGIN {DATA AND TYPED CONSTANTS}
- OUT4; {PTS TO TYPE DEFINITION}
- OUT4; {OFFSET OF DATA}
- OUT2; {FF=DSEG, FE=CSEG, 1=LOCAL ON STACK? }
- OUT2; {ALWAYS 0?. SEEMS TO BE STORED AS WORD WITH ABOVE}
- END;
- 5: BEGIN {PROCEDURE}
- OUT4; OUT4; OUT2; {UNUSED FILL TO MATCH FUNCTION}
- OUT2; {USUALLY FF, CAN BE 0}
- FINISH_PROC_FUNC;
- END;
- 6: BEGIN {FUNCTION}
- OUT4; {PTS TO FUNCTION TYPE DEFINITION}
- OUT4; {WORD OF UNKNOWN USE}
- OUT2; {BYTE OF UNKNOWN USE}
- OUT2; {USUALLY FF, CAN BE 0}
- FINISH_PROC_FUNC;
- END;
- ELSE; {WHAT IS 7? DOES 9 EXIST? }
- END; {CASE}
- WHILE SYMINDX>OLDSYMINDX+1 DO {FINISH UP ANY REMAINING BYTES}
- OUT2;
- OUT4; {THE COUNT}
- SYMINDX:=NEXTSYM;
- OLDSYMINDX:=OLDSYMINDX+COUNT;
- WRITELN(OUT);
- END; {WHILE}
- CLOSE(OUT);
- 99:END.