This commit is contained in:
2026-07-16 18:29:05 +10:00

View File

@@ -5,6 +5,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <time.h>
#include <inttypes.h>
#include "../instruction.h" #include "../instruction.h"
@@ -201,6 +203,56 @@ Program createProgramFromText(const char* input) {
return program; return program;
} }
void assemble(const char* input, const char* outputFileName) { void serializeProgramToFile(Program* program, const char* outputFileName) {
Program program = createProgramFromText(input);
FILE* fp = fopen(outputFileName, "wb");
if (fp == NULL) {
fprintf(stderr, "Couldn't open file %s for writing\n", outputFileName);
exit(1);
}
for (size_t i = 0; i < program->len; i++) {
Instruction* inst = &program->at[i];
uint16_t packed = 0;
packed |= (SerializedInst)(inst->opcode & 0b0000000000001111) ;
packed |= (SerializedInst)(inst->operands[0] & 0b0000000000001111) << 4;
packed |= (SerializedInst)(inst->operands[1] & 0b0000000000001111) << 8;
packed |= (SerializedInst)(inst->operands[2] & 0b0000000000001111) << 12;
size_t written = fwrite(&packed, sizeof(uint16_t), 1, fp);
if (written != 1) {
fprintf(stderr, "failed to write %" PRIx16 " into file %s\n", packed, outputFileName);
fclose(fp);
exit(1);
}
if (inst->hasImm16) {
size_t written = fwrite(&inst->immediate, sizeof(uint16_t), 1, fp);
if (written != 1) {
fprintf(stderr, "failed to write %" PRIx16 " into file %s\n", packed, outputFileName);
fclose(fp);
exit(1);
}
}
}
fclose(fp);
}
void assemble(const char* input, const char* outputFileName) {
clock_t start = clock();
Program program = createProgramFromText(input);
clock_t parsed = clock();
serializeProgramToFile(&program, outputFileName);
clock_t serialized = clock();
printf("Finished assembling %s, took %lg seconds (%lg secs parsing, %lg secs serializing)\n",
outputFileName,
(serialized - start) / (long double) CLOCKS_PER_SEC,
(parsed - start) / (long double) CLOCKS_PER_SEC,
(serialized - parsed) / (long double) CLOCKS_PER_SEC
);
} }