|
|
|
They are defined as SPC objects symtbl-hash-t, and symtbl-base-t in mip-h.emi like the following:
/* hashing table of a symbol table component */ dcl spc symtbl-hash-t bas(*) ; /* Number of hash buckets */ dcl dd symtbl-hash?num-buckets bin(4) dir ; /* Each hash bucket contains an offset to the first symbol table base segment entry of the chain. This offset is from the beginning of the symbol table. The end of the chain has a -1 value. */ dcl dd symtbl-hash?buckets(1000) bin(4) dir ; /* symbol table base segment */ dcl spc symtbl-base-t bas(*) ; /* Offset to next entry from beginning of the table. The end of the chain has a -1 value. */ dcl dd symtbl-base?next-entry-offset bin(4) unsgnd dir ; /* ODT or MI number */ dcl dd symtbl-base?num bin(2) dir ; /* bit 0. Instruction or ODT number 0 = MI instruction number. This also means the symbol is the name of a LABEL in the program template. 1 = ODT number. The symbol is the name of an ODT object. bit 1. Symbol origin 0 = Compiler generated 1 = Source program */ dcl dd symtbl-base?flag char(1) dir ; dcl dd symtbl-base?len char(1) dir ; dcl dd symtbl-base?name char(15) dir ;
Here is an sample MI program, tmip02.emi, that parses the symbol table component of OPM RPG program t143rpg.rpg. For the lastest source of tmip02, please refer to the svn repository of the project, https://....
/* @file tmip02.emi Test of SPC objects: symtbl-hash-t, and symtbl-base-t. */ entry *(pl-main) ext ; dcl spcptr .pgm-name parm ; dcl spcptr .pgm-type parm ; dcl ol pl-main( .pgm-name, .pgm-type ) parm ext ; dcl dd pgm-name char(10) bas(.pgm-name) ; dcl dd pgm-type char(2) bas(.pgm-type) ; dcl dd rt char(34) auto ; dcl sysptr pgm auto ; cpybrep rt, x'00' ; cpybla rt(1:2), pgm-type ; cpyblap rt(3:30), pgm-name, ' ' ; rslvsp pgm, rt, *, * ; brk '1' ; dcl spcptr p auto ; dcl dd len bin(4) auto ; modasa p, 8 ; cpynv p->matpg?bytes-in, 8 ; matpg p, pgm ; cpynv len, p->matpg?bytes-out ; modasa p, -8 ; modasa p, len ; cpynv p->matpg?bytes-in, len ; matpg p, pgm ; brk '2' ; calli dsp-header, *, dsp-header-ptr ; dcl dd inx bin(2) auto ; dcl spcptr symtbl-start auto ; dcl spcptr hash auto ; dcl spcptr sym auto ; addspp symtbl-start, p, p->matpg?symtbl-off ; addspp hash, p, p->matpg?symtbl-off ; cpynv inx, 1 ; loop-sym: cmpnv(b) inx, hash->symtbl-hash?num-buckets / hi(end-loop-sym); /* skip invalid BUCKET */ cmpnv(b) hash->symtbl-hash?buckets(inx), -1 / eq(next-bucket) ; addspp sym, symtbl-start, hash->symtbl-hash?buckets(inx) ; calli dsp-symbol, *, dsp-symbol-ptr ; /* has next entry? */ cmpnv(b) sym->symtbl-base?next-entry-offset, -1 / eq(next-bucket) ; addspp sym, symtbl-start, sym->symtbl-base?next-entry-offset ; calli dsp-symbol, *, dsp-symbol-ptr ; next-bucket: brk "WHERE" ; addn(s) inx, 1 ; b loop-sym ; end-loop-sym: brk 'END' ; neg(s) len ; modasa p, len ; rtx * ; /* display a symbol table entry @pre SPPPTR sym */ dcl insptr dsp-symbol-ptr auto ; entry dsp-symbol int ; dcl dd msg char(64) auto ; dcl dd fld-odt znd(8,0) def(msg) pos(1) ; dcl dd fld-inst znd(8,0) def(msg) pos(11) ; dcl dd fld-sym-name char(16) def(msg) pos(21) ; dcl dd fld-sym-org char(20) def(msg) pos(37) ; dcl spcptr fld-sym-name-ptr auto ; dcl spcptr symbol-name-ptr auto ; dcl dd symbol-len bin(2) auto ; dcl dd symbol-len-lo char(1) def(symbol-len) pos(2) ; cpybrep msg, ' ' ; /* symbol name */ cpybrep fld-sym-name, ' ' ; setspp fld-sym-name-ptr, fld-sym-name ; setspp symbol-name-ptr, sym->symtbl-base?name ; cpybla symbol-len-lo, sym->symtbl-base?len ; %memcpy(fld-sym-name-ptr, symbol-name-ptr, symbol-len) ; /* ODT number or MI instruction number */ tstbts(b) sym->symtbl-base?flag, 0 / zer(=+3) ; cpynv fld-odt, sym->symtbl-base?num ; /* flag bit 0 = 1, ODT number */ b =+2 ; : cpynv fld-inst, sym->symtbl-base?num ; /* flag bit 0 = 0, MI instruction */ : /* Symbol origin */ tstbts(b) sym->symtbl-base?flag, 1 / zer(=+3) ; cpybla fld-sym-org, "Source program" ; /* flag bit 1 = 1. source program */ b =+2 ; : cpybla fld-sym-org, "Compiler generated" ; /* flag bit 1 = 0. compiler generated */ : %sendmsg(msg , 64) ; b dsp-symbol-ptr ; dcl insptr dsp-header-ptr auto ; entry dsp-header int ; cpyblap msg, "HLL Symbol Table", " " ; %sendmsg(msg , 64) ; cpyblap msg, pgm-name, " " ; cvthc msg(11:4), pgm-type ; %sendmsg(msg , 64) ; cpyblap msg, "ODT Ref MI Inst Symbol Name Symbol Org", " " ; %sendmsg(msg , 64) ; b dsp-header-ptr ; /include mip-h.emi ; pend ;
Call TMIP02 like the following:
CALL TMIP02 ('T143RPG' X'0201)
The output is the following:
HLL Symbol Table
T143RPG 0201
ODT Ref MI Inst Symbol Name Symbol Org
00000240 ZIGNDECD Source program
00000022 *GETIN Source program
00000023 ARR Source program
00000076 *MONTH Source program
00000024 WHR Source program
00000072 *DATE Source program
00000017 *INXX Source program
00000020 *IN Source program
00000089 S.ARR Source program
00000138 *CANCL Source program
00000087 M.*YEAR Source program
00000085 M.*DAY Source program
00000084 *DETL Source program
00000037 *TOTC Source program
00000086 M.*MONTH Source program
00000078 *DAY Source program
00000013 *ON Source program
00000083 M.UYEAR Source program
00000080 M.UDATE Source program
00000038 *TOTL Source program
00000118 ZPGMSTUS Source program
00000079 UDAY Source program
00000077 UMONTH Source program
00000262 C.PGMJTM Source program
00000082 M.UMONTH Source program
00000073 UDATE Source program
00000022 *IN91 Source program
00000019 *INLR Source program
00000030 WORK. Source program
00000016 *INIT Source program
00000263 C*DATE Source program
00000014 *OFF Source program
00000039 *OFL Source program
00000075 UYEAR Source program
00000041 *DETC Source program
00000074 *YEAR Source program
00000081 M.UDAY Source program
00000146 *TERM Source program
00000084 M.*DATE Source program
1.5.9