#include #include #include #include "ex-compiler.h" char * ex_strdup (const char *str) { char *copy; if (!str) return NULL; copy = calloc (strlen (str) + 1, sizeof (char)); strcpy (copy, str); return copy; } void ex_parse_error (int line, int pos, const char *err) { printf ("error: %d,%d: %s!\n", line, pos, err); exit (1); } void ex_fatal_error (int line, int pos, const char *err) { printf ("error: %d,%d: %s!\n", line, pos, err); exit (1); } expointer ex_malloc (size_t n) { return calloc (n, 1); } /* ExHashTable */ typedef struct HashNode HashNode; enum { HASH_SIZE = 367 }; struct HashNode { char * key; expointer value; HashNode * next; }; struct ExHashTable { HashNode *nodes [HASH_SIZE]; }; ExHashTable * ex_hash_table_new (void) { int i; ExHashTable *hash_table; hash_table = ex_new (ExHashTable, 1); for (i = 0; i < HASH_SIZE; ++i) hash_table->nodes[i] = NULL; return hash_table; } static int hash_string (const char *key) { int i; int hash = 0; for (i = 0; key[i] != 0; ++i) hash = (hash << 5) + key[i]; return hash % HASH_SIZE; } void ex_hash_table_insert (ExHashTable *table, const char *key, expointer value) { int hash; HashNode *node; hash = hash_string (key); for (node = table->nodes[hash]; node != NULL; node = node->next) { if (strcmp (node->key, key) == 0) { node->value = value; return; } } node = ex_new (HashNode, 1); node->next = table->nodes[hash]; table->nodes[hash] = node; } expointer ex_hash_table_lookup (ExHashTable *table, const char *key) { HashNode *node; int hash = hash_string (key); for (node = table->nodes[hash]; node != NULL; node = node->next) { if (strcmp (node->key, key) == 0) return node->value; } return NULL; }