123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "symtable.h"
- #include "dd_dynamic_array.h"
- // number of entries on each symtable
- #define SYMMAX 100
- #define symtable_index(table, index) ((table << 16) | index)
- // symtable
- struct symtable {
- struct entry entry[SYMMAX];
- int lastentry;
- int parent;
- int index;
- } *symtable;
- struct dd_dynamic_array symtable_array;
- int current_symtable;
- /* init
- * allocate memory
- * no symbols inside
- */
- int symtable_init() {
- // init symtable and its index
- symtable = 0;
- current_symtable = -1;
- // init symtable array and push the first table
- dd_da_init(&symtable_array, sizeof(struct symtable));
- symtable_push();
- /* everything OK */
- return 1;
- }
- // lookup on a single table
- int lookup_table(char s[], struct symtable *t) {
- for (int i = 0; i <= t->lastentry; i++) {
- if (strcmp(t->entry[i].lexptr, s) == 0) {
- return i;
- }
- }
- return -1;
- }
- // find symbol, and return its index
- int lookup(char s[]) {
- struct symtable *csymtable = symtable;
- while (csymtable) {
- int index = lookup_table(s, csymtable);
- if (index >= 0) {
- return symtable_index(csymtable->index, index);
- }
- csymtable = dd_da_get(&symtable_array, csymtable->parent);
- }
- /* symbol not found */
- return -1;
- }
- // insert new symbol
- int symtable_insert(char s[], int tok) {
- // entry to be returned
- struct entry *symentry;
- // entry already in sym table - return it
- int index = lookup(s);
- if (index >= 0) {
- return index;
- }
- // make sure sym table has space
- if (symtable->lastentry +1 >= SYMMAX) {
- printf("symbol table full");
- return -1;
- }
- // sym table about to get a new symbol - prepare it
- int len;
- len = strlen(s);
- // entry's index
- symtable->lastentry++;
- // create new entry
- symentry = &symtable->entry[symtable->lastentry];
- symentry->token = tok;
- symentry->lexptr = malloc(sizeof(char) *len +1);
- symentry->value = 0;
- strcpy(symentry->lexptr, s);
- return symtable_index(current_symtable, symtable->lastentry);
- }
- // clean current system table and all it's parents
- void symtable_clean() {
- dd_da_free(&symtable_array);
- }
- // print symbol table
- void symtable_print() {
- for (int i = 0; i < symtable_array.elements; i++) {
- printf("symtable %d\n", i);
- struct symtable *s = dd_da_get(&symtable_array, i);
- for (int i = 0; i <= s->lastentry; i++) {
- printf("\t%s | token: %d\n", s->entry[i].lexptr, s->entry[i].token);
- }
- if (s->parent >= 0) printf("parent: %d\n", s->parent);
- else printf("parent: none\n");
- printf("end symtable:\n");
- }
- }
- // get entry from index
- struct entry *symtable_entryat(int index) {
- int symindex = index >> 16;
- index = 0xFF & index;
- struct symtable *t = dd_da_get(&symtable_array, symindex);
- /* index is within array's bounds - return entry at index */
- if (index >= 0 && index <= t->lastentry) {
- return &t->entry[index];
- }
- /* index is outside array's bounds - return null pointer */
- return 0;
- } // entryat
- /* push a new table-scope
- */
- void symtable_push() {
- // new table
- struct symtable table;
- table.lastentry = -1;
- table.parent = -1;
- table.index = symtable_array.elements;
- // add new table to array and refresh pointers
- dd_da_add(&symtable_array, &table);
- if (symtable) symtable = dd_da_get(&symtable_array, current_symtable);
- current_symtable = symtable_array.elements-1;
- struct symtable *t = dd_da_get(&symtable_array, symtable_array.elements-1);
- if (!t) {
- printf("error getting symtable\n");
- return;
- }
- if (symtable) {
- t->parent = symtable->index;
- }
- symtable = t;
- }
- void symtable_pop() {
- if (symtable->parent >= 0) {
- symtable = dd_da_get(&symtable_array, symtable->parent);
- current_symtable = symtable->index;
- }
- }
|