Kaynağa Gözat

Finish preprocessor.

master
Ben Kurtovic 9 yıl önce
ebeveyn
işleme
d7aac27e51
6 değiştirilmiş dosya ile 52 ekleme ve 35 silme
  1. +15
    -3
      src/assembler.c
  2. +1
    -1
      src/assembler/errors.c
  3. +6
    -2
      src/assembler/errors.h
  4. +28
    -28
      src/assembler/preprocessor.c
  5. +0
    -1
      src/rom.c
  6. +2
    -0
      src/rom.h

+ 15
- 3
src/assembler.c Dosyayı Görüntüle

@@ -23,8 +23,20 @@ static ErrorInfo* tokenize(AssemblerState *state)


// verify no instructions clash with header offset // verify no instructions clash with header offset
// if rom size is set, verify nothing overflows // if rom size is set, verify nothing overflows
// otherwise, check nothing overflows max rom size (1 MB)


(void) state; (void) state;

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


@@ -39,13 +51,13 @@ static ErrorInfo* resolve_defaults(AssemblerState *state)
// TODO // TODO


// if (!state.rom_size) // if (!state.rom_size)
// set to max possible >= 32 KB, or error if too many instructions
// if (state.header.rom_size)
// check reported rom size is <= actual rom size
// set to max possible >= 32 KB (max of instructions, offset, and state.header.rom_size)


// if (!state.header.rom_size) // if (!state.header.rom_size)
// set to actual rom size using util's size_bytes_to_code() // set to actual rom size using util's size_bytes_to_code()


state->rom_size = 8;

(void) state; (void) state;
return NULL; return NULL;
} }


+ 1
- 1
src/assembler/errors.c Dosyayı Görüntüle

@@ -76,7 +76,7 @@ ErrorInfo* error_info_create(


einfo->type = err_type; einfo->type = err_type;
einfo->desc = err_desc; einfo->desc = err_desc;
einfo->line = create_error_line(line);
einfo->line = line ? create_error_line(line) : NULL;
return einfo; return einfo;
} }




+ 6
- 2
src/assembler/errors.h Dosyayı Görüntüle

@@ -23,7 +23,9 @@ typedef enum {
ED_PP_DUPLICATE, ED_PP_DUPLICATE,
ED_PP_NO_ARG, ED_PP_NO_ARG,
ED_PP_BAD_ARG, ED_PP_BAD_ARG,
ED_PP_ARG_RANGE
ED_PP_ARG_RANGE,
ED_PP_HEADER_RANGE,
ED_PP_DECLARE_RANGE
} ASMErrorDesc; } ASMErrorDesc;


/* Strings */ /* Strings */
@@ -42,7 +44,9 @@ static const char *asm_error_descs[] = {
"multiple values for directive", "multiple values for directive",
"missing argument for directive", "missing argument for directive",
"invalid argument for directive", "invalid argument for directive",
"directive argument out of range"
"directive argument out of range",
"header offset exceeds given ROM size",
"declared ROM size in header exceeds actual size"
}; };


/* Structs */ /* Structs */


+ 28
- 28
src/assembler/preprocessor.c Dosyayı Görüntüle

@@ -15,6 +15,7 @@
#include "io.h" #include "io.h"
#include "parse_util.h" #include "parse_util.h"
#include "../logging.h" #include "../logging.h"
#include "../rom.h"
#include "../util.h" #include "../util.h"


/* Helper macros for preprocess() */ /* Helper macros for preprocess() */
@@ -49,6 +50,9 @@
#define PARSER_BRANCH(arg_type, true_part, false_part) \ #define PARSER_BRANCH(arg_type, true_part, false_part) \
if (CALL_PARSER_(arg_type)) {true_part} else {false_part} if (CALL_PARSER_(arg_type)) {true_part} else {false_part}


#define SAVE_LINE(target) \
target = line;

#define BEGIN_DIRECTIVE_BLOCK \ #define BEGIN_DIRECTIVE_BLOCK \
ssize_t first_ctr = -1; \ ssize_t first_ctr = -1; \
if (0) {} if (0) {}
@@ -233,6 +237,7 @@ static ErrorInfo* build_asm_lines(
const LineBuffer *root, const LineBuffer *source, ASMLine **head, const LineBuffer *root, const LineBuffer *source, ASMLine **head,
ASMLine **tail, ASMInclude **includes) ASMLine **tail, ASMInclude **includes)
{ {
ErrorInfo *ei;
ASMLine dummy = {.next = NULL}; ASMLine dummy = {.next = NULL};
ASMLine *line, *prev = &dummy; ASMLine *line, *prev = &dummy;
const Line *orig, *next_orig = source->lines; const Line *orig, *next_orig = source->lines;
@@ -249,21 +254,16 @@ static ErrorInfo* build_asm_lines(
line->next = NULL; line->next = NULL;


if (IS_DIRECTIVE(line, DIR_INCLUDE)) { if (IS_DIRECTIVE(line, DIR_INCLUDE)) {
ErrorInfo *ei;
char *path = read_include_path(line); char *path = read_include_path(line);
if (!path) { if (!path) {
ei = error_info_create(line, ET_INCLUDE, ED_INC_BAD_ARG); ei = error_info_create(line, ET_INCLUDE, ED_INC_BAD_ARG);
asm_lines_free(line);
asm_lines_free(dummy.next);
return ei;
goto error;
} }


if (path_has_been_loaded(path, root, *includes)) { if (path_has_been_loaded(path, root, *includes)) {
ei = error_info_create(line, ET_INCLUDE, ED_INC_RECURSION);
asm_lines_free(line);
asm_lines_free(dummy.next);
free(path); free(path);
return ei;
ei = error_info_create(line, ET_INCLUDE, ED_INC_RECURSION);
goto error;
} }


DEBUG("- reading included file: %s", path) DEBUG("- reading included file: %s", path)
@@ -271,9 +271,7 @@ static ErrorInfo* build_asm_lines(
free(path); free(path);
if (!incbuffer) { if (!incbuffer) {
ei = error_info_create(line, ET_INCLUDE, ED_INC_FILE_READ); ei = error_info_create(line, ET_INCLUDE, ED_INC_FILE_READ);
asm_lines_free(line);
asm_lines_free(dummy.next);
return ei;
goto error;
} }


ASMInclude *include = malloc(sizeof(ASMInclude)); ASMInclude *include = malloc(sizeof(ASMInclude));
@@ -288,9 +286,7 @@ static ErrorInfo* build_asm_lines(
if ((ei = build_asm_lines(root, incbuffer, &inchead, &inctail, if ((ei = build_asm_lines(root, incbuffer, &inchead, &inctail,
includes))) { includes))) {
error_info_append(ei, line); error_info_append(ei, line);
asm_lines_free(line);
asm_lines_free(dummy.next);
return ei;
goto error;
} }


prev->next = inchead; prev->next = inchead;
@@ -307,6 +303,11 @@ static ErrorInfo* build_asm_lines(
if (tail) if (tail)
*tail = prev; *tail = prev;
return NULL; return NULL;

error:
asm_lines_free(line);
asm_lines_free(dummy.next);
return ei;
} }


/* /*
@@ -342,6 +343,7 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)


ASMLine dummy = {.next = state->lines}; ASMLine dummy = {.next = state->lines};
ASMLine *prev, *line = &dummy, *next = state->lines, *condemned = NULL; ASMLine *prev, *line = &dummy, *next = state->lines, *condemned = NULL;
const ASMLine *rom_size_line = NULL, *rom_declsize_line = NULL;
const char *directive; const char *directive;


while ((prev = line, line = next)) { while ((prev = line, line = next)) {
@@ -364,6 +366,7 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
USE_PARSER(uint32_t, rom_size) USE_PARSER(uint32_t, rom_size)
}) })
VALIDATE(size_bytes_to_code) VALIDATE(size_bytes_to_code)
SAVE_LINE(rom_size_line)
END_DIRECTIVE END_DIRECTIVE


BEGIN_DIRECTIVE(DIR_ROM_HEADER, size_t, state->header.offset, DEFAULT_HEADER_OFFSET) BEGIN_DIRECTIVE(DIR_ROM_HEADER, size_t, state->header.offset, DEFAULT_HEADER_OFFSET)
@@ -401,6 +404,7 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
}, { }, {
USE_PARSER(uint8_t, size_code) USE_PARSER(uint8_t, size_code)
}) })
SAVE_LINE(rom_declsize_line)
END_DIRECTIVE END_DIRECTIVE


END_DIRECTIVE_BLOCK END_DIRECTIVE_BLOCK
@@ -412,24 +416,20 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
line = prev; line = prev;
} }


// TODO: if giving rom size, check header offset is in rom size range
// TODO: if giving reported and actual rom size, check reported is <= actual
if (state->rom_size && state->header.offset + HEADER_SIZE > state->rom_size) {
ei = error_info_create(rom_size_line, ET_PREPROC, ED_PP_HEADER_RANGE);
goto cleanup;
}


state->rom_size = 8; // TODO
if (state->rom_size && state->header.rom_size &&
size_code_to_bytes(state->header.rom_size) > state->rom_size) {
ei = error_info_create(rom_size_line, ET_PREPROC, ED_PP_DECLARE_RANGE);
error_info_append(ei, rom_declsize_line);
goto cleanup;
}


cleanup: cleanup:
asm_lines_free(condemned); asm_lines_free(condemned);
state->lines = dummy.next; // Fix list head if first line was a directive state->lines = dummy.next; // Fix list head if first line was a directive

#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 ei; return ei;
} }

+ 0
- 1
src/rom.c Dosyayı Görüntüle

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


#define NUM_LOCATIONS 3 #define NUM_LOCATIONS 3
#define MAGIC_LEN 8 #define MAGIC_LEN 8
#define HEADER_SIZE 16
#define SIZE_CODE_BUF 8 #define SIZE_CODE_BUF 8


static size_t header_locations[NUM_LOCATIONS] = {0x7FF0, 0x3FF0, 0x1FF0}; static size_t header_locations[NUM_LOCATIONS] = {0x7FF0, 0x3FF0, 0x1FF0};


+ 2
- 0
src/rom.h Dosyayı Görüntüle

@@ -6,6 +6,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>


#define HEADER_SIZE 16

/* Error strings */ /* Error strings */


static const char* rom_err_isdir = "Is a directory"; static const char* rom_err_isdir = "Is a directory";


Yükleniyor…
İptal
Kaydet