107 lines
3.1 KiB
C
107 lines
3.1 KiB
C
/****************************************************/
|
|
/* File: symtab.c */
|
|
/* Symbol table implementation for the TINY compiler*/
|
|
/* (allows only one symbol table) */
|
|
/* Symbol table is implemented as a chained */
|
|
/* hash table */
|
|
/* Compiler Construction: Principles and Practice */
|
|
/* Kenneth C. Louden */
|
|
/****************************************************/
|
|
|
|
#include "symtab.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* SHIFT is the power of two used as multiplier
|
|
in hash function */
|
|
#define SHIFT 4
|
|
|
|
/* the hash function */
|
|
static int hash(char *key) {
|
|
int temp = 0;
|
|
int i = 0;
|
|
while (key[i] != '\0') {
|
|
temp = ((temp << SHIFT) + key[i]) % SYMTAB_SIZE;
|
|
++i;
|
|
}
|
|
return temp;
|
|
}
|
|
|
|
Scope curr_scope(void) {
|
|
if (top_stack == -1) {
|
|
return NULL;
|
|
} else {
|
|
return scope_stack[top_stack];
|
|
}
|
|
}
|
|
|
|
/* Procedure st_insert inserts line numbers and
|
|
* memory locations into the symbol table
|
|
* loc = memory location is inserted only the
|
|
* first time, otherwise ignored
|
|
*/
|
|
void st_insert(char *name, int lineno, int loc) {
|
|
int h = hash(name);
|
|
BucketList l = hashTable[h];
|
|
while ((l != NULL) && (strcmp(name, l->name) != 0))
|
|
l = l->next;
|
|
if (l == NULL) /* variable not yet in table */
|
|
{
|
|
l = (BucketList) malloc(sizeof(struct BucketListRec));
|
|
l->name = name;
|
|
l->lines = (LineList) malloc(sizeof(struct LineListRec));
|
|
l->lines->lineno = lineno;
|
|
l->memloc = loc;
|
|
l->lines->next = NULL;
|
|
l->next = hashTable[h];
|
|
hashTable[h] = l;
|
|
} else /* found in table, so just add line number */
|
|
{
|
|
LineList t = l->lines;
|
|
while (t->next != NULL) t = t->next;
|
|
t->next = (LineList) malloc(sizeof(struct LineListRec));
|
|
t->next->lineno = lineno;
|
|
t->next->next = NULL;
|
|
}
|
|
} /* st_insert */
|
|
|
|
/* Function st_lookup returns the memory
|
|
* location of a variable or -1 if not found
|
|
*/
|
|
int st_lookup(char *name) {
|
|
int h = hash(name);
|
|
BucketList l = hashTable[h];
|
|
while ((l != NULL) && (strcmp(name, l->name) != 0))
|
|
l = l->next;
|
|
if (l == NULL) return -1;
|
|
else
|
|
return l->memloc;
|
|
}
|
|
|
|
/* Procedure printSymTab prints a formatted
|
|
* listing of the symbol table contents
|
|
* to the listing file
|
|
*/
|
|
void printSymTab(FILE *listing) {
|
|
int i;
|
|
fprintf(listing, "Variable Name Location Line Numbers\n");
|
|
fprintf(listing, "------------- -------- ------------\n");
|
|
for (i = 0; i < SYMTAB_SIZE; ++i) {
|
|
if (hashTable[i] != NULL) {
|
|
BucketList l = hashTable[i];
|
|
while (l != NULL) {
|
|
LineList t = l->lines;
|
|
fprintf(listing, "%-14s ", l->name);
|
|
fprintf(listing, "%-8d ", l->memloc);
|
|
while (t != NULL) {
|
|
fprintf(listing, "%4d ", t->lineno);
|
|
t = t->next;
|
|
}
|
|
fprintf(listing, "\n");
|
|
l = l->next;
|
|
}
|
|
}
|
|
}
|
|
} /* printSymTab */
|