Browse Source

Implement parse_bytes(), bugfixes, improve error messages.

master
Ben Kurtovic 9 years ago
parent
commit
82f2d9740a
3 changed files with 54 additions and 16 deletions
  1. +1
    -1
      src/assembler/errors.c
  2. +34
    -2
      src/assembler/parse_util.c
  3. +19
    -13
      src/assembler/tokenizer.c

+ 1
- 1
src/assembler/errors.c View File

@@ -35,7 +35,7 @@ static const char *error_descs[] = {
[ED_LYT_BLOCK0] = "block zero cannot be mapped into a nonzero slot", [ED_LYT_BLOCK0] = "block zero cannot be mapped into a nonzero slot",
[ED_LYT_SLOTS] = "multiple slot declarations for block directive", [ED_LYT_SLOTS] = "multiple slot declarations for block directive",
[ED_LYT_BLOCK_CROSS] = "instruction or data extends past block boundary", [ED_LYT_BLOCK_CROSS] = "instruction or data extends past block boundary",
[ED_LYT_OVERLAP] = "location overlaps with instruction or data",
[ED_LYT_OVERLAP] = "multiple instructions/data occupy same location",
[ED_LYT_OVERLAP_HEAD] = "location overlaps with ROM header", [ED_LYT_OVERLAP_HEAD] = "location overlaps with ROM header",


[ED_SYM_DUPE_LABELS] = "duplicate definitions for label", [ED_SYM_DUPE_LABELS] = "duplicate definitions for label",


+ 34
- 2
src/assembler/parse_util.c View File

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


#include "parse_util.h" #include "parse_util.h"
#include "directives.h" #include "directives.h"
#include "../logging.h"
#include "../util.h" #include "../util.h"


#define MAX_REGION_SIZE 32 #define MAX_REGION_SIZE 32
@@ -125,6 +126,8 @@ bool parse_string(char **result, size_t *length, const char *arg, ssize_t size)


*length = size - 2; *length = size - 2;
*result = malloc(sizeof(char) * (*length)); *result = malloc(sizeof(char) * (*length));
if (!*result)
OUT_OF_MEMORY()
memcpy(*result, arg + 1, *length); memcpy(*result, arg + 1, *length);
return true; return true;
} }
@@ -137,8 +140,37 @@ bool parse_string(char **result, size_t *length, const char *arg, ssize_t size)
*/ */
bool parse_bytes(uint8_t **result, size_t *length, const char *arg, ssize_t size) bool parse_bytes(uint8_t **result, size_t *length, const char *arg, ssize_t size)
{ {
// TODO
return false;
if (size <= 0)
return false;

const char *end = arg + size;
uint8_t *bytes = NULL;
size_t nbytes = 0;

while (arg != end) {
const char *start = arg;
while (arg != end && *arg != ' ')
arg++;

uint32_t temp;
if (!parse_uint32_t(&temp, start, arg - start) || temp > UINT8_MAX) {
free(bytes);
return false;
}

nbytes++;
bytes = realloc(bytes, sizeof(uint8_t) * nbytes);
if (!bytes)
OUT_OF_MEMORY()
bytes[nbytes - 1] = temp;

if (arg++ == end)
break;
}

*result = bytes;
*length = nbytes;
return true;
} }


/* /*


+ 19
- 13
src/assembler/tokenizer.c View File

@@ -16,6 +16,7 @@
typedef struct { typedef struct {
size_t size; size_t size;
const ASMLine **overlap_table; const ASMLine **overlap_table;
const ASMLine **overlap_origins;
const ASMLine *origin; const ASMLine *origin;
uint8_t bank; uint8_t bank;
bool cross_blocks; bool cross_blocks;
@@ -125,15 +126,12 @@ static ErrorInfo* handle_block_directive(


if (bank >= MMU_NUM_ROM_BANKS || slot >= MMU_NUM_SLOTS) if (bank >= MMU_NUM_ROM_BANKS || slot >= MMU_NUM_SLOTS)
return error_info_create(line, ET_PREPROC, ED_PP_ARG_RANGE); return error_info_create(line, ET_PREPROC, ED_PP_ARG_RANGE);

if (nargs == 2) {
if (bank == 0 && slot != 0)
return error_info_create(line, ET_LAYOUT, ED_LYT_BLOCK0);
if (si->slots[bank] >= 0 && si->slots[bank] != slot) {
ErrorInfo *ei = error_info_create(line, ET_LAYOUT, ED_LYT_SLOTS);
error_info_append(ei, si->lines[bank]);
return ei;
}
if (bank == 0 && slot != 0)
return error_info_create(line, ET_LAYOUT, ED_LYT_BLOCK0);
if (si->slots[bank] >= 0 && si->slots[bank] != slot) {
ErrorInfo *ei = error_info_create(line, ET_LAYOUT, ED_LYT_SLOTS);
error_info_append(ei, si->lines[bank]);
return ei;
} }


*offset = bank * MMU_ROM_BANK_SIZE; *offset = bank * MMU_ROM_BANK_SIZE;
@@ -212,13 +210,14 @@ static ErrorInfo* parse_instruction(
static ErrorInfo* check_layout( static ErrorInfo* check_layout(
ASMLayoutInfo *li, const ASMLocation *loc, const ASMLine *line) ASMLayoutInfo *li, const ASMLocation *loc, const ASMLine *line)
{ {
const ASMLine *clash = NULL;
const ASMLine *clash = NULL, *clash_origin;
if (loc->offset + loc->length > li->size) { if (loc->offset + loc->length > li->size) {
clash = &bounds_sentinel; clash = &bounds_sentinel;
} else { } else {
for (size_t i = 0; i < loc->length; i++) { for (size_t i = 0; i < loc->length; i++) {
if (li->overlap_table[loc->offset + i]) { if (li->overlap_table[loc->offset + i]) {
clash = li->overlap_table[loc->offset + i]; clash = li->overlap_table[loc->offset + i];
clash_origin = li->overlap_origins[loc->offset + i];
break; break;
} }
} }
@@ -231,8 +230,11 @@ static ErrorInfo* check_layout(


if (li->origin) if (li->origin)
error_info_append(ei, li->origin); error_info_append(ei, li->origin);
if (clash != &header_sentinel && clash != &bounds_sentinel)
if (clash != &header_sentinel && clash != &bounds_sentinel) {
error_info_append(ei, clash); error_info_append(ei, clash);
if (clash_origin)
error_info_append(ei, clash_origin);
}
return ei; return ei;
} }


@@ -244,8 +246,10 @@ static ErrorInfo* check_layout(
return ei; return ei;
} }


for (size_t i = 0; i < loc->length; i++)
for (size_t i = 0; i < loc->length; i++) {
li->overlap_table[loc->offset + i] = line; li->overlap_table[loc->offset + i] = line;
li->overlap_origins[loc->offset + i] = li->origin;
}
return NULL; return NULL;
} }


@@ -263,7 +267,8 @@ ErrorInfo* tokenize(AssemblerState *state)
.origin = NULL, .bank = 0, .cross_blocks = state->cross_blocks .origin = NULL, .bank = 0, .cross_blocks = state->cross_blocks
}; };
li.overlap_table = calloc(li.size, sizeof(const ASMLine*)); li.overlap_table = calloc(li.size, sizeof(const ASMLine*));
if (!li.overlap_table)
li.overlap_origins = calloc(li.size, sizeof(const ASMLine*));
if (!li.overlap_table || !li.overlap_origins)
OUT_OF_MEMORY() OUT_OF_MEMORY()


ErrorInfo *ei = NULL; ErrorInfo *ei = NULL;
@@ -332,5 +337,6 @@ ErrorInfo* tokenize(AssemblerState *state)
state->instructions = dummy_inst.next; state->instructions = dummy_inst.next;
state->data = dummy_data.next; state->data = dummy_data.next;
free(li.overlap_table); free(li.overlap_table);
free(li.overlap_origins);
return ei; return ei;
} }

Loading…
Cancel
Save