1*22170Sdist /* 2*22170Sdist * Copyright (c) 1980 Regents of the University of California. 3*22170Sdist * All rights reserved. The Berkeley software License Agreement 4*22170Sdist * specifies the terms and conditions for redistribution. 5*22170Sdist */ 6755Speter 714733Sthien #ifndef lint 8*22170Sdist static char sccsid[] = "@(#)hash.c 5.1 (Berkeley) 06/05/85"; 9*22170Sdist #endif not lint 10755Speter 11755Speter #include "whoami.h" 12755Speter #include "0.h" 1314733Sthien #include "tree_ty.h" /* must be included for yy.h */ 14755Speter #include "yy.h" 15755Speter 16755Speter /* 17755Speter * The definition for the segmented hash tables. 18755Speter */ 19755Speter struct ht { 20755Speter int *ht_low; 21755Speter int *ht_high; 22755Speter int ht_used; 23755Speter } htab[MAXHASH]; 24755Speter 25755Speter /* 26755Speter * This is the array of keywords and their 27755Speter * token values, which are hashed into the table 28755Speter * by inithash. 29755Speter */ 30755Speter struct kwtab yykey[] = { 31755Speter "and", YAND, 32755Speter "array", YARRAY, 33755Speter "begin", YBEGIN, 34755Speter "case", YCASE, 35755Speter "const", YCONST, 36755Speter "div", YDIV, 37755Speter "do", YDO, 38755Speter "downto", YDOWNTO, 39755Speter "else", YELSE, 40755Speter "end", YEND, 41755Speter "file", YFILE, 42755Speter "for", YFOR, 43755Speter "forward", YFORWARD, 44755Speter "function", YFUNCTION, 45755Speter "goto", YGOTO, 46755Speter "if", YIF, 47755Speter "in", YIN, 48755Speter "label", YLABEL, 49755Speter "mod", YMOD, 50755Speter "nil", YNIL, 51755Speter "not", YNOT, 52755Speter "of", YOF, 53755Speter "or", YOR, 54755Speter "packed", YPACKED, 55755Speter "procedure", YPROCEDURE, 56755Speter "program", YPROG, 57755Speter "record", YRECORD, 58755Speter "repeat", YREPEAT, 59755Speter "set", YSET, 60755Speter "then", YTHEN, 61755Speter "to", YTO, 62755Speter "type", YTYPE, 63755Speter "until", YUNTIL, 64755Speter "var", YVAR, 65755Speter "while", YWHILE, 66755Speter "with", YWITH, 677955Smckusick 0, 0, /* the following keywords are non-standard */ 687955Smckusick "oct", YOCT, 697955Smckusick "hex", YHEX, 707955Smckusick "external", YEXTERN, 71755Speter 0 72755Speter }; 73755Speter 747955Smckusick char *lastkey; 75755Speter 76755Speter /* 77755Speter * Inithash initializes the hash table routines 78755Speter * by allocating the first hash table segment using 79755Speter * an already existing memory slot. 80755Speter */ 81755Speter #ifndef PI0 82755Speter inithash() 83755Speter #else 84755Speter inithash(hshtab) 85755Speter int *hshtab; 86755Speter #endif 87755Speter { 88755Speter register int *ip; 89755Speter #ifndef PI0 90755Speter static int hshtab[HASHINC]; 91755Speter #endif 92755Speter 93755Speter htab[0].ht_low = hshtab; 94755Speter htab[0].ht_high = &hshtab[HASHINC]; 9514733Sthien for (ip = ((int *)yykey); *ip; ip += 2) 9614733Sthien hash((char *) ip[0], 0)[0] = ((int) ip); 977955Smckusick /* 987955Smckusick * If we are not running in "standard-only" mode, 997955Smckusick * we load the non-standard keywords. 1007955Smckusick */ 1017955Smckusick if (!opt('s')) 1027955Smckusick for (ip += 2; *ip; ip += 2) 10314733Sthien hash((char *) ip[0], 0)[0] = ((int) ip); 1047955Smckusick lastkey = (char *)ip; 105755Speter } 106755Speter 107755Speter /* 108755Speter * Hash looks up the s(ymbol) argument 109755Speter * in the string table, entering it if 110755Speter * it is not found. If save is 0, then 111755Speter * the argument string is already in 112755Speter * a safe place. Otherwise, if hash is 113755Speter * entering the symbol for the first time 114755Speter * it will save the symbol in the string 115755Speter * table using savestr. 116755Speter */ 117755Speter int *hash(s, save) 118755Speter char *s; 119755Speter int save; 120755Speter { 121755Speter register int *h; 122755Speter register i; 123755Speter register char *cp; 124755Speter int *sym; 12514733Sthien struct cstruct *temp; 126755Speter struct ht *htp; 127755Speter int sh; 128755Speter 129755Speter /* 130755Speter * The hash function is a modular hash of 131755Speter * the sum of the characters with the sum 132755Speter * doubled before each successive character 133755Speter * is added. 134755Speter */ 135755Speter cp = s; 136755Speter if (cp == NIL) 137755Speter cp = token; /* default symbol to be hashed */ 138755Speter i = 0; 139755Speter while (*cp) 140755Speter i = i*2 + *cp++; 141755Speter sh = (i&077777) % HASHINC; 142755Speter cp = s; 143755Speter if (cp == NIL) 144755Speter cp = token; 145755Speter /* 146755Speter * There are as many as MAXHASH active 147755Speter * hash tables at any given point in time. 148755Speter * The search starts with the first table 149755Speter * and continues through the active tables 150755Speter * as necessary. 151755Speter */ 152755Speter for (htp = htab; htp < &htab[MAXHASH]; htp++) { 153755Speter if (htp->ht_low == NIL) { 15414733Sthien cp = (char *) pcalloc(sizeof ( int * ), HASHINC); 1551833Speter if (cp == 0) { 156755Speter yerror("Ran out of memory (hash)"); 157755Speter pexit(DIED); 158755Speter } 15914733Sthien htp->ht_low = ((int *)cp); 160755Speter htp->ht_high = htp->ht_low + HASHINC; 161755Speter cp = s; 162755Speter if (cp == NIL) 163755Speter cp = token; 164755Speter } 165755Speter h = htp->ht_low + sh; 166755Speter /* 167755Speter * quadratic rehash increment 168755Speter * starts at 1 and incremented 169755Speter * by two each rehash. 170755Speter */ 171755Speter i = 1; 172755Speter do { 173755Speter if (*h == 0) { 174755Speter if (htp->ht_used > (HASHINC * 3)/4) 175755Speter break; 176755Speter htp->ht_used++; 177755Speter if (save != 0) { 178755Speter *h = (int) savestr(cp); 179755Speter } else 18014733Sthien *h = ((int) s); 181755Speter return (h); 182755Speter } 18314733Sthien sym = ((int *) *h); 18414733Sthien if (sym < ((int *) lastkey) && sym >= ((int *) yykey)) 18514733Sthien sym = ((int *) *sym); 18614733Sthien temp = ((struct cstruct *) sym); 18714733Sthien if (temp->pchar == *cp && pstrcmp((char *) sym, cp) == 0) 188755Speter return (h); 189755Speter h += i; 190755Speter i += 2; 191755Speter if (h >= htp->ht_high) 192755Speter h -= HASHINC; 193755Speter } while (i < HASHINC); 194755Speter } 195755Speter yerror("Ran out of hash tables"); 196755Speter pexit(DIED); 19714733Sthien return (NIL); 19814733Sthien 199755Speter } 200