From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- asmitree.c | 277 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 asmitree.c (limited to 'asmitree.c') diff --git a/asmitree.c b/asmitree.c new file mode 100644 index 0000000..12ef168 --- /dev/null +++ b/asmitree.c @@ -0,0 +1,277 @@ +/* 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 + +#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; zFill=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; zSize; 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; zSize; 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 -- cgit v1.2.3