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
*/
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;
while (*key)
while ((size < 0 || size-- > 0) && *key)
hash = ((hash << 5) + hash) + *(key++);
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.

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.

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) {
if (!strcmp(key, NODE_KEY(table, node)))
if (keyeq(key, NODE_KEY(table, node), size))
return 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)
{
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];
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.

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;

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


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

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

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

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

HashTable* hash_table_new(size_t, size_t, HashFreeCallback);
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*);
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)
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;
ssize_t i = 0;
@@ -421,8 +425,7 @@ bool argparse_label(ASMArgLabel *result, ASMArgParseInfo ai)
if (ai.size <= 0 || ai.size >= MAX_SYMBOL_SIZE)
return false;

// TODO: check for deftable

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

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

strncpy(result->text, ai.arg, ai.size);
result->text[ai.size] = '\0';
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)
{
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.
*/
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.
*/
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


+ 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*);
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*);
bool asm_deftable_remove(ASMDefineTable*, const char*);
bool asm_deftable_remove(ASMDefineTable*, const char*, size_t);

#ifdef DEBUG_MODE
void asm_lines_print(const ASMLine*);


Loading…
Cancel
Save