Ver a proveniência

Implement label reading, symtab operations (except hashing).

master
Ben Kurtovic há 9 anos
ascendente
cometimento
c37375e4be
5 ficheiros alterados com 76 adições e 2 eliminações
  1. +36
    -2
      src/assembler.c
  2. +1
    -0
      src/assembler/errors.c
  3. +1
    -0
      src/assembler/errors.h
  4. +34
    -0
      src/assembler/state.c
  5. +4
    -0
      src/assembler/state.h

+ 36
- 2
src/assembler.c Ver ficheiro

@@ -17,6 +17,37 @@
#define IS_LABEL(line) (line->data[line->length - 1] == ':')

/*
Add a given line, representing a label, to the symbol table.

Return NULL on success and an ErrorInfo object on failure (in the case of
duplicate labels).
*/
static ErrorInfo* add_label_to_table(
ASMSymbolTable *symtable, const ASMLine *line, size_t offset)
{
char *symbol = strndup(line->data, line->length - 1);
if (!symbol)
OUT_OF_MEMORY()

const ASMSymbol *current = asm_symtable_find(symtable, symbol);
if (current) {
ErrorInfo *ei = error_info_create(line, ET_LAYOUT, ED_LYT_DUPE_LABELS);
error_info_append(ei, current->line);
return ei;
}

ASMSymbol *label = malloc(sizeof(ASMSymbol));
if (!label)
OUT_OF_MEMORY()

label->offset = offset;
label->symbol = symbol;
label->line = line;
asm_symtable_insert(symtable, label);
return NULL;
}

/*
Parse an instruction encoded in line into an ASMInstruction object.

On success, return NULL and store the instruction in *inst_ptr. On failure,
@@ -44,7 +75,9 @@ static ErrorInfo* tokenize(AssemblerState *state)
if (!overlap_table)
OUT_OF_MEMORY()

// TODO: fill overlap table for header with pointers to a dummy object
ASMLine header_indicator;
for (size_t i = 0; i < HEADER_SIZE; i++)
overlap_table[state->header.offset + i] = &header_indicator;

ErrorInfo *ei = NULL;
ASMInstruction dummy = {.next = NULL}, *inst, *prev = &dummy;
@@ -77,7 +110,8 @@ static ErrorInfo* tokenize(AssemblerState *state)
}
}
else if (IS_LABEL(line)) {
// TODO: add to symbol table
if ((ei = add_label_to_table(state->symtable, line, offset)))
goto cleanup;
}
else {
if ((ei = parse_instruction(line, &inst, offset)))


+ 1
- 0
src/assembler/errors.c Ver ficheiro

@@ -33,6 +33,7 @@ static const char *asm_error_descs[] = {

"header offset exceeds given ROM size", // ED_LYT_HEADER_RANGE
"declared ROM size in header exceeds actual size", // ED_LYT_DECLARE_RANGE
"duplicate definitions for label", // ED_LYT_DUPE_LABELS
"location overlaps with ROM header", // ED_LYT_HEAD_OVERLAP
"location overlaps with previous instruction", // ED_LYT_INST_OVERLAP
"location overlaps with previous data", // ED_LYT_DATA_OVERLAP


+ 1
- 0
src/assembler/errors.h Ver ficheiro

@@ -29,6 +29,7 @@ typedef enum {

ED_LYT_HEADER_RANGE,
ED_LYT_DECLARE_RANGE,
ED_LYT_DUPE_LABELS,
ED_LYT_HEAD_OVERLAP,
ED_LYT_INST_OVERLAP,
ED_LYT_DATA_OVERLAP,


+ 34
- 0
src/assembler/state.c Ver ficheiro

@@ -128,6 +128,40 @@ void asm_symtable_free(ASMSymbolTable *symtable)
free(symtable);
}

/*
...
*/
static inline size_t hash_key(const char *key)
{
return 0;
}

/*
Search for a key in the symbol table.

Return the key on success and NULL on failure.
*/
const ASMSymbol* asm_symtable_find(const ASMSymbolTable *tab, const char *key)
{
ASMSymbol *symbol = tab->buckets[hash_key(key)];
while (symbol) {
if (!strcmp(key, symbol->symbol))
return symbol;
symbol = symbol->next;
}
return NULL;
}

/*
Insert a symbol into the table.
*/
void asm_symtable_insert(ASMSymbolTable *tab, ASMSymbol *symbol)
{
size_t index = hash_key(symbol->symbol);
symbol->next = tab->buckets[index];
tab->buckets[index] = symbol;
}

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Print out an ASMLine list to stdout.


+ 4
- 0
src/assembler/state.h Ver ficheiro

@@ -53,6 +53,7 @@ typedef struct ASMData ASMData;
struct ASMSymbol {
size_t offset;
char *symbol;
const ASMLine *line;
struct ASMSymbol *next;
};
typedef struct ASMSymbol ASMSymbol;
@@ -92,6 +93,9 @@ void asm_instructions_free(ASMInstruction*);
void asm_data_free(ASMData*);
void asm_symtable_free(ASMSymbolTable*);

const ASMSymbol* asm_symtable_find(const ASMSymbolTable*, const char*);
void asm_symtable_insert(ASMSymbolTable*, ASMSymbol*);

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

Carregando…
Cancelar
Guardar