瀏覽代碼

Implement normalize_line(), misc.

master
Ben Kurtovic 9 年之前
父節點
當前提交
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 char *filename;
struct ASMLine *next;
struct ASMLine *include;
};
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)
{
// 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) {
ASMLine *temp = line->next;
free(line->data);
free_asm_lines(line->include);
free(line);
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.

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
// 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;
}



Loading…
取消
儲存