kolibrios-fun/programs/develop/c--/trunk/tree.h--
Yogev Ezra 02b76505a6 Add sources of "C--"'like compiler written in C--.
git-svn-id: svn://kolibrios.org@1846 a494cfbc-eb01-0410-851d-a64ba20cac60
2011-02-05 16:39:49 +00:00

462 lines
12 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ---- ‡ ­¥á¥­¨¥ ¯®¨¬¥­®¢ ­­®© ª®­áâ ­âë ¢ ᯨ᮪
AddConstToTree(dword keystring,constvalue)
dword ptr,newptr; // idrec structure
{
newptr=LocalAlloc(0x40,recsize);
IF(EAX==NULL){
preerror("Compiler out of memory for identifier tree");
ExitProcess(e_outofmemory);
}
ptr=treestart;
IF(EAX == NULL ) // <20>ãá⮩ ᯨ᮪?
treestart = newptr;
ELSE{
for(;;){
// <20>®¨áª ᢮¡®¤­®© áá뫪¨
ESI=ptr;
EAX=lstrcmpA(DSDWORD[ESI+recid],keystring);
ESI=ptr;
IF(long EAX<0){
// ptr.left
IF(DSDWORD[ESI+left]==0){ // <20> è«¨ ¯ãá⮩ «¥¢ë© - ¤®¡ ¢¨¬
DSDWORD[ESI+left]=newptr;
BREAK; // ptr.left=newptr
}
ptr=DSDWORD[ESI+left];
}
ELSE IF(EAX!=0){
// ptr.right
IF(DSDWORD[ESI+right]==0){ // <20> è«¨ ¯ãá⮩ ¯à ¢ë© - ¤®¡ ¢¨¬
DSDWORD[ESI+right]=newptr;
BREAK;
}
ptr=DSDWORD[ESI+right];
}
ELSE internalerror("string found in tree when trying to add to it");
}
}
// ”®à¬¨à㥬 ­®¢ãî § ¯¨áì ¢ ᯨ᪥
ESI=newptr;
DSDWORD[ESI+recid]=LocalAlloc(0x40,lstrlenA(keystring)+1);
lstrcpyA(DSDWORD[ESI+recid],keystring);
ESI=newptr;
DSDWORD[ESI+newid]= NULL;
DSDWORD[ESI+rectok]=tk_number;
DSDWORD[ESI+recnumber]=constvalue;
DSDWORD[ESI+recpost]=0;
DSDWORD[ESI+left]=NULL;
DSDWORD[ESI+right]=NULL;
DSDWORD[ESI+recmodline] = currmod<<16+linenumber;
}
// ---- „®¡ ¢¨âì «®ª «ì­ãî ¯¥à¥¬¥­­ãî ¢ ᯨ᮪
AddLocalvar(dword str,tk,ltype,num)
dword newptr;
{
newptr=LocalAlloc(0x40,local_size);
IF(EAX==NULL){
preerror("Compiler out of memory for local symbol linked list");
ExitProcess(e_outofmemory);
}
IF(locallist==NULL)locallist = newptr;
ELSE{
EAX=locallist;
EBX><EAX; //ptr;
for(;;){
EAX=DSDWORD[EBX+localnext];
IF(EAX==0)BREAK;
EBX><EAX;
}
DSDWORD[EBX+localnext]=newptr;
}
EBX=newptr;
lstrcpyA(EBX+localid,str);
EBX=newptr;
DSDWORD[EBX+localtok] = tk;
DSDWORD[EBX+localtype] = ltype;
DSDWORD[EBX+localnumber] = num;
DSDWORD[EBX+localnext] = NULL;
localptr=EBX;
}
// ---- „®¡ ¢¨âì ¨¤¥­â¨ä¨ª â®à ¢ ᯨ᮪
AddToTree(dword keystring)
dword ptr,newptr;
{
newptr=LocalAlloc(0x40,recsize);
IF(EAX==NULL)outofmemory();
ptr = treestart;
//WRITESTR(keystring);WRITESTR("\n");
IF(EAX==NULL)treestart = newptr;
ELSE{
for(;;){
// <20>®¨áª ᢮¡®¤­®© áá뫪¨
ESI=ptr;
EAX=lstrcmpA(DSDWORD[ESI+recid],keystring);
ESI=ptr;
IF(long EAX<0){
// ptr.left
IF(DSDWORD[ESI+left]==0){ // <20> è«¨ ¯ãá⮩ «¥¢ë© - ¤®¡ ¢¨¬
DSDWORD[ESI+left]=newptr;
BREAK; // ptr.left=newptr
}
ptr=DSDWORD[ESI+left];
}
ELSE IF(EAX!=0){
// ptr.right
IF(DSDWORD[ESI+right]==0){ // <20> è«¨ ¯ãá⮩ ¯à ¢ë© - ¤®¡ ¢¨¬
DSDWORD[ESI+right]=newptr;
BREAK;
}
ptr=DSDWORD[ESI+right];
}
ELSE internalerror("string found in tree when trying to add to it");
}
}
ESI=newptr;
DSDWORD[ESI+recid]=LocalAlloc(0x40,lstrlenA(keystring)+1);
lstrcpyA(EAX,keystring);
IF(tok == tk_string){
ESI=newptr;
DSDWORD[ESI+newid] = LocalAlloc(0x40,number+1);
IF( EAX == NULL )outofmemory();
ECX=number;
EDI=EAX;
ESI=#string;
$REP $MOVSB
}
ELSE{
IF( lstrlenA(#string) == 0 ){
ESI=newptr;
DSDWORD[ESI+newid]=NULL;
}
ELSE{
ESI=newptr;
DSDWORD[ESI+newid]=LocalAlloc(0x40,lstrlenA(#string)+1);
IF( EAX == NULL )outofmemory();
lstrcpyA(EAX,#string);
}
}
ESI=newptr;
DSDWORD[ESI+rectok] = tok;
DSDWORD[ESI+recnumber] = number;
DSDWORD[ESI+rectype] = type;
DSDWORD[ESI+recsrc] = src;
DSDWORD[ESI+recpost] = post;
DSDWORD[ESI+left] = NULL;
DSDWORD[ESI+right] = NULL;
DSDWORD[ESI+recmodline] = modline;
treeptr = newptr;
}
// ---- ‚뢮¤ ¢á¥å ¨¤¥­â¨ä¨ª â®à®¢
void DisplayTree ()
{ // dump all identifiers to MAP file
fprint(mapfile,"ALL GLOBAL IDENTIFIERS LIST:\n");
fprint(mapfile,"tok type number post\tIDENTIFIER\n");
numberofids = 0;
DisplayTreeAll(treestart);
wsprintfA(#mapstr,"\n %u Unique Global Identifiers.\n\n",numberofids);
fprint(mapfile,#mapstr);
fprint(mapfile,"GLOBAL CONSTANT IDENTIFIER LIST:\n");
numberofids = 0;
DisplayTreeConstants(treestart);
wsprintfA(#mapstr,"\n %u Unique Global Constant Value Identifiers.\n\n",numberofids);
fprint(mapfile,#mapstr);
}
// ---- ‚뢮¤ ¢á¥£® ᯨ᪠ ¨¤¥­â¨ä¨ ªâ®à®¢
DisplayTreeAll(dword ptr)
{
if( ptr != NULL ){
ESI=ptr;
DisplayTreeAll(DSDWORD[ESI+right]);
ESI=ptr;
if(DSDWORD[ESI+rectok]-DSDWORD[ESI+recpost]!=tk_API){
wsprintfA(#mapstr,"%3d %8lXh %8lXh %6Xh\t%s\n",DSDWORD[ESI+rectok],
DSDWORD[ESI+rectype],DSDWORD[ESI+recnumber],DSDWORD[ESI+recpost],
DSDWORD[ESI+recid]);
fprint(mapfile,#mapstr);
EAX=DSDWORD[ESI+newid];
IF(EAX!=0){
IF(lstrcmpA(DSDWORD[ESI+recid],EAX) != 0 ){
ESI=ptr;
wsprintfA(#mapstr,"Alias=%s\n",DSDWORD[ESI+newid]);
fprint(mapfile,#mapstr);
}
}
IF(list){
ESI=ptr;
EAX=DSDWORD[ESI+recsrc];
IF(EAX!=0){
EBX=DSDWORD[ESI+recmodline]>>16;
EAX=FILENAMESIZE*EBX+#modules;
EBX=EAX;
wsprintfA(#mapstr,"File:%s, line=%-d:\n%s\n",EBX,
DSDWORD[ESI+recmodline]&0xFFFF,DSDWORD[ESI+recsrc]);
fprint(mapfile,#mapstr);
ESI=ptr; LocalFree(DSDWORD[ESI+recsrc]); // Žá¢®¡®¤¨¬ ¯ ¬ïâì
DSDWORD[ESI+recsrc]=0;
}
}
numberofids++;
}
ESI=ptr;
DisplayTreeAll(DSDWORD[ESI+left]);
}
}
// ---- ‚뢮¤ ᯨ᪠ £«®¡ «ì­ëå ª®­áâ ­â
DisplayTreeConstants(dword ptr)
{
IF( ptr != NULL ){
ESI=ptr;
DisplayTreeConstants(DSDWORD[ESI+right]);
ESI=ptr;
EAX=DSDWORD[ESI+rectok];
IF(EAX == tk_number){
wsprintfA(#mapstr,"#define %10ld /* %8lX hex */ %s\n",
DSDWORD[ESI+recnumber],DSDWORD[ESI+recnumber],DSDWORD[ESI+recid]);
fprint(mapfile,#mapstr);
numberofids++;
}
ESI=ptr;
DisplayTreeConstants(DSDWORD[ESI+left]);
}
}
// ---- ‚ëç¨á«¥­¨¥ §­ ç¥­¨ï ¡¥§§­ ª®¢® ª®­áâ ­âë
dword DoConstDwordMath()
dword value;
{
IF(tok == tk_minus){
NextTok();
IF(tok != tk_number){
numexpected();
return(0);
}
number = -number;
}
IF(tok != tk_number){
numexpected();
return(0);
}
value = number;
while(tok2isopperand()){
NextTok();
IF(tok2!=tk_number)return(value);
switch(tok){
case tk_minus: value -= number2; break;
case tk_plus: value += number2; break;
case tk_xor: value ^= number2; break;
case tk_and: value &= number2; break;
case tk_or: value |= number2; break;
case tk_mod: value = value % number2; BREAK;
case tk_div: value = value / number2; BREAK;
case tk_mult: value = value * number2; BREAK;
case tk_rr: value >>= number2; BREAK;
case tk_ll: value <<= number2; BREAK;
case tk_xorminus: value ^= -number2; BREAK;
case tk_andminus: value &= -number2; BREAK;
case tk_orminus: value |= -number2; BREAK;
/* case(tok==tk_modminus) value %= -number2;
case(tok==tk_divminus) value /= -number2;
case(tok==tk_multminus) value *= -number2; */
case tk_rrminus: value >>= -number2; BREAK;
case tk_llminus: value <<= -number2; BREAK;
}
NextTok();
}
return(value);
}
// ---- ‚ëç¨á«¥­¨¥ §­ ç¥­¨ï §­ ª®¢®© ª®­áâ ­âë
long DoConstMath()
long value;
{
IF(tok == tk_minus){
NextTok();
IF(tok != tk_number){
numexpected();
return(0);
}
number = -number;
}
IF(tok != tk_number){
numexpected();
return(0);
}
value = number;
while(tok2isopperand()){
NextTok();
IF(tok2 != tk_number) return(value);
switch(tok){
case tk_minus: value -= number2; break;
case tk_plus: value += number2; break;
case tk_xor: value ^= number2; break;
case tk_and: value &= number2; break;
case tk_or: value |= number2; break;
case tk_mod: value = value % number2; BREAK;
case tk_div: value = value / number2; BREAK;
case tk_mult: value = value * number2; BREAK;
case tk_rr: value >>= number2; BREAK;
case tk_ll: value <<= number2; BREAK;
case tk_xorminus: value ^= -number2; BREAK;
case tk_andminus: value &= -number2; BREAK;
case tk_orminus: value |= -number2; BREAK;
/* case(tok==tk_modminus) value %= -number2;
case(tok==tk_divminus) value /= -number2;
case(tok==tk_multminus) value *= -number2; */
case tk_rrminus: value >>= -number2; BREAK;
case tk_llminus: value <<= -number2; BREAK;
}
NextTok();
}
return(value);
}
// ---- ‚ëç¨á«¥­¨¥ §­ ç¥­¨ï §­ ª®¢®© ª®­áâ ­âë
long DoConstLongMath()
long value;
{
value=DoConstMath();
NextTok();
return(value);
}
// ---- ‘«¥¤ãî騩 token - ®¯¥à æ¨ï?
dword tok2isopperand()
{
EAX=tok2;
IF(EAX==tk_plus)||(EAX==tk_minus)||(EAX==tk_mult)||(EAX==tk_div)||(EAX==tk_mod)||
(EAX==tk_rr)||(EAX==tk_ll)||(EAX==tk_or)||(EAX==tk_and)||(EAX==tk_xor)||
(EAX==tk_divminus)||(EAX==tk_modminus)||(EAX==tk_multminus)||(EAX==tk_xorminus)||
(EAX==tk_orminus)||(EAX==tk_andminus)||(EAX==tk_llminus)||(EAX==tk_rrminus)return(1);
return(0);
}
// ---- ‘«¥¤ãî騩 token § ªà뢠¥â ¢ëà ¦¥­¨¥?
dword tok2notstopper ()
{
EAX=tok2;
IF(EAX==tk_semicolon)||(EAX==tk_comma)||(EAX==tk_closebracket)||
(EAX==tk_openblock)EAX=0;
ELSE EAX=1;
}
// ---- <20>®¨áª ¢ ᯨ᪥ «®ª «ì­ëå ¯¥à¥¬¥­­ëå
SearchLocals(dword tok4,type4,string4,number4)
{
if( locallist != NULL ){
localptr = locallist;
S00:
ESI=EAX; //localptr;
lstrcmpA(string4,ESI+localid);
ESI=localptr;
IF(EAX==0){ // <20>¥à¥¬¥­­ ï ­ ©¤¥­ 
EBX=number4;
DSDWORD[EBX]=DSDWORD[ESI+localnumber];
EBX=type4;
DSDWORD[EBX]=DSDWORD[ESI+localtype];
EBX=tok4;
EAX=DSDWORD[ESI+localtok];
DSDWORD[EBX]=EAX;
IF(EAX==tk_local){
EBX=number4;
DSDWORD[EBX]-=localsize;
}
ELSE IF(EAX==tk_param){
EBX=number4;
EAX=DSDWORD[EBX]+4;
DSDWORD[EBX]=EAX;
IF(current_proc_type==cpt_far)DSDWORD[EBX]+=4; // move over seg on stack
}
ELSE IF(EAX!=tk_locallabel)&&(EAX!=tk_number)internalerror("Bad *tok4 value in SearchLocals");
}
ELSE{
IF(DSDWORD[ESI+localnext]!=NULL){
localptr=DSDWORD[ESI+localnext];
$JMP S00
}
}
}
}
// ---- <20>®¨áª ¢ ᯨ᪥ £«®¡ «ì­ëå ¨¤¥­â¨ä¨ª â®à®¢
dword SearchTree(dword tok4,type4,src4,post4,string4,number4)
dword ptr;
long cmpresult;
{
cmpresult=123;
ptr = treestart;
// <20>®¨áª ᢮¡®¤­®© áá뫪¨
for(;;){
ESI=EAX;
IF(ESI==0){
treeptr=NULL;
return(0); // Not found
}
cmpresult = lstrcmpA(DSDWORD[ESI+recid],string4);
ESI=ptr;
IF(cmpresult<0)ptr=DSDWORD[ESI+left];
ELSE IF(cmpresult>0)ptr=DSDWORD[ESI+right];
ELSE BREAK;
}
EBX=number4; DSDWORD[EBX]=DSDWORD[ESI+recnumber];
EBX=type4; DSDWORD[EBX]=DSDWORD[ESI+rectype];
EBX=src4; DSDWORD[EBX]=DSDWORD[ESI+recsrc];
EBX=post4; DSDWORD[EBX]=DSDWORD[ESI+recpost];
EBX=tok4; EAX=DSDWORD[ESI+rectok]; DSDWORD[EBX]=EAX;
IF(EAX==tk_string ){
EBX=number4; ECX=DSDWORD[EBX]; EDI=string4;
ESI=DSDWORD[ESI+newid]; $REP $MOVSB
}
ELSE{
IF(DSDWORD[ESI+newid])lstrcpyA(string4,DSDWORD[ESI+newid]);
}
ESI=ptr;
IF(lstrcmpA(DSDWORD[ESI+recid],string4)!=0) // <20>஢¥à¨¬: ¬¥­ï«®áì «¨ ¨¬ï ¨¤¥­â¨ä¨ª â®à 
SearchTree(tok4,type4,src4,post4,string4,number4); // „  - ¯®¢â®à¨¬ ¯®¨áª
treeptr = ptr;
return(1);
}
// ---- <20>®¨áª ­¥®âª®¬¯¨«¨à®¢ ­­ëå ¥é¥ ááë«®ª
dword SeekToDo(dword ptr)
{
IF(ptr!=NULL){
ESI=ptr;
IF(SeekToDo(DSDWORD[ESI+right]))RETURN(1);
ESI=ptr; EAX=DSDWORD[ESI+recpost];
IF(EAX>1){
treeptr=ptr; ESI=ptr;
number=DSDWORD[ESI+recnumber];
type=DSDWORD[ESI+rectype]; modline=DSDWORD[ESI+recmodline];
src=DSDWORD[ESI+recsrc];
post=DSDWORD[ESI+recpost];
tok=DSDWORD[ESI+rectok]; RETURN(1);
}
ESI=ptr;
IF(SeekToDo(DSDWORD[ESI+left]))RETURN(1);
}
return(0);
}
// ---- <20>®¨áª ­¥§ ªàëâëå ááë«®ª
SeekUndefined(dword ptr)
{
IF( ptr != NULL ){
ESI=ptr;
SeekUndefined(DSDWORD[ESI+right]);
ESI=ptr; EAX=DSDWORD[ESI+rectok];
IF(EAX==tk_undefproc){
wsprintfA(#mapstr,"'%s' undefined\n",DSDWORD[ESI+recid]);
IF( makemapfile )fprint(mapfile,#mapstr);
WRITESTR(#mapstr);
}
ESI=ptr;
SeekUndefined(DSDWORD[ESI+left]);
}
}