#include "./assembler.h" #include "../emu/cpu_const.h" #include "../emu/cpu_human.h" #include "./asm_const.h" #include #include #include #include #include // i apologise for the next three functions, they are written very werirdly, // and are not as readable as they coudld be, sorry // the rough flow for each is just to loop along a string until you // encounter a specific char, or a non space / tab char // // again i apologise for the unreadability, they use way to many // goto's, but should be pretty efficient. char *FindNextChar(char *data, char toFind, bool careAboutNull) { begin: switch (*data) { case '\0': if (careAboutNull) { fprintf(stderr, "FOUND NULL CHAR BEFORE CHAR TO FIND\n"); exit(-1); } goto final; default: if (*data == toFind) { final: return data; } data++; goto begin; } } char *FindNextNonSpaceChar(char *data, bool careAboutNull) { begin: switch(*data) { case '\0': if (careAboutNull) { fprintf(stderr, "FOUND NULL CHAR BEFORE NON SPACE / TAB CHAR\n"); exit(-1); } goto final; case ' ': case '\t': data++; goto begin; default: final: return data; } } char *FindNextSpaceChar(char *data, bool careAboutNull) { begin: switch(*data) { case '\0': if (careAboutNull) { fprintf(stderr, "FOUND NULL CHAR BEFORE NON SPACE / TAB CHAR\n"); exit(-1); } case ' ': case '\t': return data; default: data++; goto begin; } } AsmInstructionArray *InterpretAssembly(char *data) { char *d = data; AsmInstructionArray *asmIA = malloc(sizeof(AsmInstructionArray)); uint32_t cSize = 0, mSize = ARRAY_SNAP_SIZE; asmIA->instruction = malloc(sizeof(AsmInstruction) * ARRAY_SNAP_SIZE); while (true) { loopStart: if (cSize == mSize) { mSize += ARRAY_SNAP_SIZE; asmIA->instruction = realloc(asmIA->instruction, mSize); } AsmInstruction current = *(asmIA->instruction + (cSize * sizeof(AsmInstruction))); d = FindNextNonSpaceChar(d, false); if (*d == '\0') goto final; if (*d == '\n') { d++; goto loopStart; } if (*(FindNextSpaceChar(d, true) - 1) == ':') { memcpy(¤t.label, d, (FindNextSpaceChar(d, true) - 1) - d); d = FindNextNonSpaceChar(d, true); } else { current.label[0] = '\0'; } memcpy(¤t.instruction, d, 3); d = FindNextNonSpaceChar(d, false); if (*d == '\0') goto final; if (*d == '\n') { d++; goto loopEnd; } char *comma = FindNextChar(d, ',', true), *nline = FindNextChar(d, '\n', true); bool a2 = comma < nline; char *eoA1 = a2 ? comma : nline; memcpy(¤t.arg1, d, eoA1 - d); if (!a2) goto loopEnd; d = FindNextNonSpaceChar(eoA1 + 1, true); memcpy(¤t.arg2, d, nline - d); d = nline + 1; loopEnd: cSize++; } final: asmIA->instruction = realloc(asmIA->instruction, cSize); asmIA->length = cSize; return asmIA; } AsmLabelArray *GenerateLabels(AsmInstructionArray *assembly) { AsmLabelArray *labels = malloc(sizeof(AsmLabelArray)); uint32_t cSize = 0, mSize = ARRAY_SNAP_SIZE; labels->labels = malloc(sizeof(AsmLabel) * ARRAY_SNAP_SIZE); for (int i = 0; i < assembly->length; i++) { if (cSize == mSize) { mSize += ARRAY_SNAP_SIZE; labels->labels = reallc(labels->labels, mSize); } if (assembly->instruction[0].label[0] == '\0') continue; labels->labels[cSize].location = i; strcpy(&labels->labels[cSize].label, &assembly->instruction[0].label); cSize++; } labels->labels = realloc(labels->labels, cSize); labels->length = cSize; return labels; } uint16_t *CompileAsembly(AsmInstructionArray *assembly, AsmLabelArray *labels) { }