dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/asmitree.c

278 lines
6.9 KiB
C

/* asmitree.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* Opcode-Abfrage als Binaerbaum */
/* */
/* Historie: 30.10.1996 Grundsteinlegung */
/* 8.10.1997 Hash-Tabelle */
/* 6.12.1998 dynamisches Kopieren der Namen */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include "chunks.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmitree.h"
/*---------------------------------------------------------------------------*/
static Boolean AddSingle(PInstTreeNode *Node, char *NName, InstProc NProc, Word NIndex)
BEGIN
PInstTreeNode p1,p2;
Boolean Result=False;
ChkStack();
if (*Node==Nil)
BEGIN
*Node=(PInstTreeNode) malloc(sizeof(TInstTreeNode));
(*Node)->Left=Nil; (*Node)->Right=Nil;
(*Node)->Proc=NProc; (*Node)->Index=NIndex;
(*Node)->Balance=0;
(*Node)->Name=strdup(NName);
Result=True;
END
else if (strcmp(NName,(*Node)->Name)<0)
BEGIN
if (AddSingle(&((*Node)->Left),NName,NProc,NIndex))
switch ((*Node)->Balance)
BEGIN
case 1:
(*Node)->Balance=0;
break;
case 0:
(*Node)->Balance=(-1);
Result=True;
break;
case -1:
p1=(*Node)->Left;
if (p1->Balance==-1)
BEGIN
(*Node)->Left=p1->Right; p1->Right=(*Node);
(*Node)->Balance=0; *Node=p1;
END
else
BEGIN
p2=p1->Right;
p1->Right=p2->Left; p2->Left=p1;
(*Node)->Left=p2->Right; p2->Right=(*Node);
if (p2->Balance==-1) (*Node)->Balance= 1; else (*Node)->Balance=0;
if (p2->Balance== 1) p1 ->Balance=(-1); else p1 ->Balance=0;
*Node=p2;
END
(*Node)->Balance=0;
break;
END
END
else
BEGIN
if (AddSingle(&((*Node)->Right),NName,NProc,NIndex))
switch ((*Node)->Balance)
BEGIN
case -1:
(*Node)->Balance=0;
break;
case 0:
(*Node)->Balance=1;
Result=True;
break;
case 1:
p1=(*Node)->Right;
if (p1->Balance==1)
BEGIN
(*Node)->Right=p1->Left; p1->Left=(*Node);
(*Node)->Balance=0; *Node=p1;
END
else
BEGIN
p2=p1->Left;
p1->Left=p2->Right; p2->Right=p1;
(*Node)->Right=p2->Left; p2->Left=(*Node);
if (p2->Balance== 1) (*Node)->Balance=(-1); else (*Node)->Balance=0;
if (p2->Balance==-1) p1 ->Balance= 1; else p1 ->Balance=0;
*Node=p2;
END
(*Node)->Balance=0;
break;
END
END
return Result;
END
void AddInstTree(PInstTreeNode *Root, char *NName, InstProc NProc, Word NIndex)
BEGIN
AddSingle(Root,NName,NProc,NIndex);
END
static void ClearSingle(PInstTreeNode *Node)
BEGIN
ChkStack();
if (*Node!=Nil)
BEGIN
free((*Node)->Name);
ClearSingle(&((*Node)->Left));
ClearSingle(&((*Node)->Right));
free(*Node); *Node=Nil;
END
END
void ClearInstTree(PInstTreeNode *Root)
BEGIN
ClearSingle(Root);
END
Boolean SearchInstTree(PInstTreeNode Root, char *OpPart)
BEGIN
int z;
z=0;
while ((Root!=Nil) AND (strcmp(Root->Name,OpPart)!=0))
BEGIN
Root=(strcmp(OpPart,Root->Name)<0)? Root->Left : Root->Right;
z++;
END
if (Root==Nil) return False;
else
BEGIN
Root->Proc(Root->Index);
return True;
END
END
static void PNode(PInstTreeNode Node, Word Lev)
BEGIN
ChkStack();
if (Node!=Nil)
BEGIN
PNode(Node->Left,Lev+1);
printf("%*s %s %p %p %d\n",5*Lev,"",Node->Name,Node->Left,Node->Right,Node->Balance);
PNode(Node->Right,Lev+1);
END
END
void PrintInstTree(PInstTreeNode Root)
BEGIN
PNode(Root,0);
END
/*----------------------------------------------------------------------------*/
static int GetKey(char *Name, LongWord TableSize)
BEGIN
register unsigned char *p;
LongWord tmp=0;
for (p=(unsigned char *)Name; *p!='\0'; p++) tmp=(tmp<<2)+((LongWord)*p);
return tmp%TableSize;
END
PInstTable CreateInstTable(int TableSize)
BEGIN
int z;
PInstTableEntry tmp;
PInstTable tab;
tmp=(PInstTableEntry) malloc(sizeof(TInstTableEntry)*TableSize);
for (z=0; z<TableSize; z++) tmp[z].Name=Nil;
tab=(PInstTable) malloc(sizeof(TInstTable));
tab->Fill=0; tab->Size=TableSize; tab->Entries=tmp; tab->Dynamic=FALSE;
return tab;
END
void SetDynamicInstTable(PInstTable Table)
BEGIN
Table->Dynamic=TRUE;
END
void DestroyInstTable(PInstTable tab)
BEGIN
int z;
if (tab->Dynamic)
for (z=0; z<tab->Size; z++)
free(tab->Entries[z].Name);
free(tab->Entries);
free(tab);
END
void AddInstTable(PInstTable tab, char *Name, Word Index, InstProc Proc)
BEGIN
LongWord h0=GetKey(Name,tab->Size),z=0;
/* mindestens ein freies Element lassen, damit der Sucher garantiert terminiert */
if (tab->Size-1<=tab->Fill) exit(255);
while (1)
BEGIN
if (tab->Entries[h0].Name==Nil)
BEGIN
tab->Entries[h0].Name=(tab->Dynamic) ? strdup(Name) : Name;
tab->Entries[h0].Proc=Proc;
tab->Entries[h0].Index=Index;
tab->Entries[h0].Coll=z;
tab->Fill++;
return;
END
z++;
if ((++h0)==tab->Size) h0=0;
END
END
void RemoveInstTable(PInstTable tab, char *Name)
BEGIN
LongWord h0=GetKey(Name,tab->Size);
while (1)
BEGIN
if (tab->Entries[h0].Name==Nil) return;
else if (strcmp(tab->Entries[h0].Name,Name)==0)
BEGIN
tab->Entries[h0].Name=Nil;
tab->Entries[h0].Proc=Nil;
tab->Fill--;
return;
END
if ((++h0)==tab->Size) h0=0;
END
END
Boolean LookupInstTable(PInstTable tab, char *Name)
BEGIN
LongWord h0=GetKey(Name,tab->Size);
while (1)
BEGIN
if (tab->Entries[h0].Name==Nil) return False;
else if (strcmp(tab->Entries[h0].Name,Name)==0)
BEGIN
tab->Entries[h0].Proc(tab->Entries[h0].Index);
return True;
END
if ((++h0)==tab->Size) h0=0;
END
END
void PrintInstTable(FILE *stream, PInstTable tab)
BEGIN
int z;
for (z=0; z<tab->Size; z++)
if (tab->Entries[z].Name!=Nil)
fprintf(stream,"[%3d]: %-10s Index %4d Coll %2d\n",z,tab->Entries[z].Name,tab->Entries[z].Index,tab->Entries[z].Coll);
END
/*----------------------------------------------------------------------------*/
void asmitree_init(void)
BEGIN
END