Browse Source

Do define substitution in argparsers; fix hashtables.

master
Ben Kurtovic 9 years ago
parent
commit
197ce39fd3
5 changed files with 44 additions and 21 deletions
  1. +23
    -9
      src/assembler/hash_table.c
  2. +3
    -2
      src/assembler/hash_table.h
  3. +9
    -3
      src/assembler/parse_util.c
  4. +7
    -5
      src/assembler/state.c
  5. +2
    -2
      src/assembler/state.h

+ 23
- 9
src/assembler/hash_table.c View File

@@ -26,15 +26,24 @@ struct HashNode {


This uses the djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html This uses the djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html
*/ */
static inline size_t hash_key(const HashTable *table, const char *key)
static inline size_t hash_key(
const HashTable *table, const char *key, ssize_t size)
{ {
size_t hash = 5381; size_t hash = 5381;
while (*key)
while ((size < 0 || size-- > 0) && *key)
hash = ((hash << 5) + hash) + *(key++); hash = ((hash << 5) + hash) + *(key++);
return hash % table->buckets; return hash % table->buckets;
} }


/* /*
Return true if the two key strings are equal, or false if they aren't.
*/
static inline bool keyeq(const char *s1, const char *s2, ssize_t size)
{
return !(size >= 0 ? strncmp(s1, s2, size) : strcmp(s1, s2));
}

/*
Create and return a new HashTable. Create and return a new HashTable.


These HashTables are designed to be generic, a sort of poor-man's C++ These HashTables are designed to be generic, a sort of poor-man's C++
@@ -89,12 +98,15 @@ void hash_table_free(HashTable *table)
Search for a key in the hash table. Search for a key in the hash table.


Return the corresponding node on success and NULL on failure. Return the corresponding node on success and NULL on failure.

If the key is null-terminated, pass size as -1.
*/ */
const HashNode* hash_table_find(const HashTable *table, const char *key)
const HashNode* hash_table_find(
const HashTable *table, const char *key, ssize_t size)
{ {
HashNode *node = table->nodes[hash_key(table, key)];
HashNode *node = table->nodes[hash_key(table, key, size)];
while (node) { while (node) {
if (!strcmp(key, NODE_KEY(table, node)))
if (keyeq(key, NODE_KEY(table, node), size))
return node; return node;
node = NEXT_NODE(table, node); node = NEXT_NODE(table, node);
} }
@@ -111,7 +123,7 @@ const HashNode* hash_table_find(const HashTable *table, const char *key)
*/ */
void hash_table_insert(HashTable *table, HashNode *node) void hash_table_insert(HashTable *table, HashNode *node)
{ {
size_t index = hash_key(table, NODE_KEY(table, node));
size_t index = hash_key(table, NODE_KEY(table, node), -1);
NEXT_NODE(table, node) = table->nodes[index]; NEXT_NODE(table, node) = table->nodes[index];
table->nodes[index] = node; table->nodes[index] = node;
} }
@@ -120,15 +132,17 @@ void hash_table_insert(HashTable *table, HashNode *node)
(Try to) remove a node with the given key from the table. (Try to) remove a node with the given key from the table.


Return true if the node was removed, or false if it was not found. Return true if the node was removed, or false if it was not found.

If the key is null-terminated, pass size as -1.
*/ */
bool hash_table_remove(HashTable *table, const char *key)
bool hash_table_remove(HashTable *table, const char *key, ssize_t size)
{ {
size_t index = hash_key(table, key);
size_t index = hash_key(table, key, size);
HashNode *node = table->nodes[index], *prev = NULL, *next; HashNode *node = table->nodes[index], *prev = NULL, *next;


while (node) { while (node) {
next = NEXT_NODE(table, node); next = NEXT_NODE(table, node);
if (!strcmp(key, NODE_KEY(table, node))) {
if (keyeq(key, NODE_KEY(table, node), size)) {
if (prev) if (prev)
NEXT_NODE(table, prev) = next; NEXT_NODE(table, prev) = next;
else else


+ 3
- 2
src/assembler/hash_table.h View File

@@ -5,6 +5,7 @@


#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <unistd.h>


#define hash_table_NEW(node, key, next, callback) \ #define hash_table_NEW(node, key, next, callback) \
hash_table_new(offsetof(node, key), offsetof(node, next), \ hash_table_new(offsetof(node, key), offsetof(node, next), \
@@ -28,6 +29,6 @@ typedef struct {


HashTable* hash_table_new(size_t, size_t, HashFreeCallback); HashTable* hash_table_new(size_t, size_t, HashFreeCallback);
void hash_table_free(HashTable*); void hash_table_free(HashTable*);
const HashNode* hash_table_find(const HashTable*, const char*);
const HashNode* hash_table_find(const HashTable*, const char*, ssize_t);
void hash_table_insert(HashTable*, HashNode*); void hash_table_insert(HashTable*, HashNode*);
bool hash_table_remove(HashTable*, const char*);
bool hash_table_remove(HashTable*, const char*, ssize_t);

+ 9
- 3
src/assembler/parse_util.c View File

@@ -303,7 +303,11 @@ bool argparse_immediate(ASMArgImmediate *result, ASMArgParseInfo ai)
if (ai.size <= 0) if (ai.size <= 0)
return false; return false;


// TODO: lookup here for definition table
const ASMDefine *define = asm_deftable_find(ai.deftable, ai.arg, ai.size);
if (define) {
*result = define->value;
return true;
}


bool negative = false; bool negative = false;
ssize_t i = 0; ssize_t i = 0;
@@ -421,8 +425,7 @@ bool argparse_label(ASMArgLabel *result, ASMArgParseInfo ai)
if (ai.size <= 0 || ai.size >= MAX_SYMBOL_SIZE) if (ai.size <= 0 || ai.size >= MAX_SYMBOL_SIZE)
return false; return false;


// TODO: check for deftable

// Validate the label characters:
for (const char *i = ai.arg; i < ai.arg + ai.size; i++) { for (const char *i = ai.arg; i < ai.arg + ai.size; i++) {
char c = *i; char c = *i;
if (!((c >= 'a' && c <= 'z') || c == '_' || c == '.' || if (!((c >= 'a' && c <= 'z') || c == '_' || c == '.' ||
@@ -430,6 +433,9 @@ bool argparse_label(ASMArgLabel *result, ASMArgParseInfo ai)
return false; return false;
} }


if (asm_deftable_find(ai.deftable, ai.arg, ai.size))
return false;

strncpy(result->text, ai.arg, ai.size); strncpy(result->text, ai.arg, ai.size);
result->text[ai.size] = '\0'; result->text[ai.size] = '\0';
return true; return true;


+ 7
- 5
src/assembler/state.c View File

@@ -151,7 +151,7 @@ void asm_deftable_free(ASMDefineTable *deftable)
*/ */
const ASMSymbol* asm_symtable_find(const ASMSymbolTable *tab, const char *key) const ASMSymbol* asm_symtable_find(const ASMSymbolTable *tab, const char *key)
{ {
return (ASMSymbol*) hash_table_find(tab, key);
return (ASMSymbol*) hash_table_find(tab, key, -1);
} }


/* /*
@@ -169,9 +169,10 @@ void asm_symtable_insert(ASMSymbolTable *tab, ASMSymbol *symbol)


Return the corresponding ASMDefine on success and NULL on failure. Return the corresponding ASMDefine on success and NULL on failure.
*/ */
const ASMDefine* asm_deftable_find(const ASMDefineTable *tab, const char *key)
const ASMDefine* asm_deftable_find(
const ASMDefineTable *tab, const char *key, size_t size)
{ {
return (ASMDefine*) hash_table_find(tab, key);
return (ASMDefine*) hash_table_find(tab, key, size);
} }


/* /*
@@ -189,9 +190,10 @@ void asm_deftable_insert(ASMDefineTable *tab, ASMDefine *define)


Return true if the node was removed, or false if it was not found. Return true if the node was removed, or false if it was not found.
*/ */
bool asm_deftable_remove(ASMDefineTable *tab, const char *key)
bool asm_deftable_remove(
ASMDefineTable *tab, const char *key, size_t size)
{ {
return hash_table_remove(tab, key);
return hash_table_remove(tab, key, size);
} }


#ifdef DEBUG_MODE #ifdef DEBUG_MODE


+ 2
- 2
src/assembler/state.h View File

@@ -108,9 +108,9 @@ void asm_deftable_free(ASMDefineTable*);


const ASMSymbol* asm_symtable_find(const ASMSymbolTable*, const char*); const ASMSymbol* asm_symtable_find(const ASMSymbolTable*, const char*);
void asm_symtable_insert(ASMSymbolTable*, ASMSymbol*); void asm_symtable_insert(ASMSymbolTable*, ASMSymbol*);
const ASMDefine* asm_deftable_find(const ASMDefineTable*, const char*);
const ASMDefine* asm_deftable_find(const ASMDefineTable*, const char*, size_t);
void asm_deftable_insert(ASMDefineTable*, ASMDefine*); void asm_deftable_insert(ASMDefineTable*, ASMDefine*);
bool asm_deftable_remove(ASMDefineTable*, const char*);
bool asm_deftable_remove(ASMDefineTable*, const char*, size_t);


#ifdef DEBUG_MODE #ifdef DEBUG_MODE
void asm_lines_print(const ASMLine*); void asm_lines_print(const ASMLine*);


Loading…
Cancel
Save