Files
2025-02-Compiler/src/symtab.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 */