Преглед на файлове

Implement normalize_line(), misc.

master
Ben Kurtovic преди 11 години
родител
ревизия
8da3663670
променени са 1 файла, в които са добавени 98 реда и са изтрити 3 реда
  1. +98
    -3
      src/assembler.c

+ 98
- 3
src/assembler.c Целия файл

@@ -23,7 +23,6 @@ struct ASMLine {
const Line *original; const Line *original;
const char *filename; const char *filename;
struct ASMLine *next; struct ASMLine *next;
struct ASMLine *include;
}; };
typedef struct ASMLine ASMLine; typedef struct ASMLine ASMLine;


@@ -198,7 +197,7 @@ static bool write_binary_file(const char *path, const uint8_t *data, size_t size
void error_info_print(const ErrorInfo *error_info, FILE *file) void error_info_print(const ErrorInfo *error_info, FILE *file)
{ {
// TODO // TODO
fprintf(file, "Error: Unknown error");
fprintf(file, "Error: Unknown error\n");
} }


/* /*
@@ -241,7 +240,6 @@ static void free_asm_lines(ASMLine *line)
while (line) { while (line) {
ASMLine *temp = line->next; ASMLine *temp = line->next;
free(line->data); free(line->data);
free_asm_lines(line->include);
free(line); free(line);
line = temp; line = temp;
} }
@@ -295,6 +293,75 @@ static void free_asm_symtable(ASMSymbolTable *symtable)
} }


/* /*
Preprocess a single source line (source, length) into a normalized ASMLine.

*Only* the data and length fields in the ASMLine object are populated. The
normalization process converts tabs to spaces, removes runs of multiple
spaces (outside of string literals), strips comments, and other things.

Return NULL if an ASM line was not generated from the source, i.e. if it is
blank after being stripped.
*/
static ASMLine* normalize_line(const char *source, size_t length)
{
char *data = malloc(sizeof(char) * length);
if (!data)
OUT_OF_MEMORY()

size_t si, di, slashes = 0;
bool has_content = false, space_pending = false, in_string = false;
for (si = di = 0; si < length; si++) {
char c = source[si];

if (c == '\\')
slashes++;
else
slashes = 0;

if (in_string) {
if (c == '"' && (slashes % 2) == 0)
in_string = false;

data[di++] = c;
} else {
if (c == ';')
break;
if (c == '"' && (slashes % 2) == 0)
in_string = true;

if (c == '\t' || c == ' ')
space_pending = true;
else {
if (space_pending) {
if (has_content)
data[di++] = ' ';
space_pending = false;
}
has_content = true;
data[di++] = c;
}
}
}

if (!has_content) {
free(data);
return NULL;
}

ASMLine *line = malloc(sizeof(ASMLine));
if (!line)
OUT_OF_MEMORY()

data = realloc(data, sizeof(char) * di);
if (!data)
OUT_OF_MEMORY()

line->data = data;
line->length = di;
return line;
}

/*
Preprocess the LineBuffer into ASMLines. Change some state along the way. Preprocess the LineBuffer into ASMLines. Change some state along the way.


This function processes include directives, so read_source_file() may be This function processes include directives, so read_source_file() may be
@@ -322,6 +389,34 @@ static ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
// if giving reported and actual rom size, check reported is <= actual // if giving reported and actual rom size, check reported is <= actual
// ensure no duplicate explicit assignments // ensure no duplicate explicit assignments


ASMLine dummy = {.next = NULL};
ASMLine *line, *prev = &dummy;
const Line *orig = source->lines;

while (orig) {
if ((line = normalize_line(orig->data, orig->length))) {
line->original = orig;
line->filename = source->filename;
line->next = NULL;

prev->next = line;
prev = line;
}
orig = orig->next;
}

state->lines = dummy.next;

#ifdef DEBUG_MODE
DEBUG("Dumping ASMLines:")
const ASMLine *temp = state->lines;
while (temp) {
DEBUG("- %-40.*s [%s:%02zu]", (int) temp->length, temp->data,
temp->filename, temp->original->lineno)
temp = temp->next;
}
#endif

return NULL; return NULL;
} }




Зареждане…
Отказ
Запис