From af01b5afaee11e59663b45b1c68faa1d79703ca0 Mon Sep 17 00:00:00 2001 From: zongor Date: Sun, 8 Jun 2025 18:07:19 -0400 Subject: [PATCH] quick-n-dirty num to str --- src/vm.c | 180 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 113 insertions(+), 67 deletions(-) diff --git a/src/vm.c b/src/vm.c index c6412c2..668aed7 100644 --- a/src/vm.c +++ b/src/vm.c @@ -7,7 +7,7 @@ #include /* #define MEMORY_SIZE 65536 /\* 64KB memory (adjustable) *\/ */ -#define MEMORY_SIZE 200 +#define MEMORY_SIZE 1024 typedef union { float f; uint32_t u; @@ -15,28 +15,78 @@ typedef union { Data memory[MEMORY_SIZE]; /* Memory array */ typedef enum { - OP_HALT, /* terminate execution */ - OP_ADD, /* dest = src1 + src2 */ - OP_SUB, /* dest = src1 - src2 */ - OP_MUL, /* dest = src1 * src2 */ - OP_DIV, /* dest = src1 / src2 */ - OP_ADD_F32, /* dest = src1 + src2 */ - OP_SUB_F32, /* dest = src1 - src2 */ - OP_MUL_F32, /* dest = src1 * src2 */ - OP_DIV_F32, /* dest = src1 / src2 */ - OP_MOV, /* dest = src1 */ - OP_JMP, /* jump to address src1 unconditionally */ - OP_JGZ, /* jump to address dest if src1 > 0 */ + OP_HALT, /* terminate execution */ + OP_ADD, /* dest = src1 + src2 */ + OP_SUB, /* dest = src1 - src2 */ + OP_MUL, /* dest = src1 * src2 */ + OP_DIV, /* dest = src1 / src2 */ + OP_ADD_F32, /* dest = src1 + src2 */ + OP_SUB_F32, /* dest = src1 - src2 */ + OP_MUL_F32, /* dest = src1 * src2 */ + OP_DIV_F32, /* dest = src1 / src2 */ + OP_MOV, /* dest = src1 */ + OP_JMP, /* jump to address src1 unconditionally */ + OP_JGZ, /* jump to address dest if src1 > 0 */ + OP_INT_TO_STRING, /* dest = src1 as str */ + OP_F32_TO_STRING, /* dest = src2 as str */ OP_READ_STRING, OP_PRINT_STRING, } Opcode; +int core_dump() { + FILE *file = fopen("memory_dump.bin", "wb"); + if (!file) { + perror("Failed to open file"); + return EXIT_FAILURE; + } + size_t written = fwrite(memory, 1, MEMORY_SIZE, file); + if (written != MEMORY_SIZE) { + fprintf(stderr, "Incomplete write: %zu bytes written out of %u\n", written, + MEMORY_SIZE); + fclose(file); + return EXIT_FAILURE; + } + + fclose(file); + return EXIT_SUCCESS; +} + uint8_t get_char(uint32_t word, int index) { - return (word >> (8 * index)) & 0xFF; + return (word >> (8 * (3 - index))) & 0xFF; } uint32_t set_char(uint32_t word, int index, uint8_t ch) { - return (word & ~(0xFF << (8 * index))) | (ch << (8 * index)); + return (word & ~(0xFF << (8 * (3 - index)))) | (ch << (8 * (3 - index))); +} + +/* Pack string into union-based memory */ +void pack_string(const char *str, uint32_t length, uint32_t dest_addr) { + memory[dest_addr].u = length; + uint32_t buffer_addr = dest_addr + 1; + int word_index = 0; + int char_index = 0; + + uint32_t i = 0; + while (i < length) { + char ch = str[i++]; + if (ch == '\0' || ch == EOF) { + uint32_t word = memory[buffer_addr + word_index].u; + word = set_char(word, char_index, '\0'); + memory[buffer_addr + word_index].u = word; + break; + } + + uint32_t word = memory[buffer_addr + word_index].u; + word = set_char(word, char_index, ch); + memory[buffer_addr + word_index].u = word; + + char_index++; + if (char_index == 4) { + char_index = 0; + word_index++; + } + length++; + } } void run_vm() { @@ -109,22 +159,32 @@ void run_vm() { pc = (jump_target & mask) | (pc & ~mask); break; } + case OP_INT_TO_STRING: { + int32_t a = (int32_t)memory[src1_addr].u; + char buffer[32]; + sprintf(buffer, "%d", a); + pack_string(buffer, strlen(buffer), dest_addr); + break; + } + case OP_F32_TO_STRING: { + float a = memory[src1_addr].f; + char buffer[32]; + sprintf(buffer, "%f", a); + pack_string(buffer, strlen(buffer), dest_addr); + break; + } case OP_PRINT_STRING: { uint32_t string_addr = src1_addr; - uint32_t length = memory[src1_addr-1].u; - + uint32_t length = memory[src1_addr - 1].u; uint32_t i; - while (i < length) { - int j = 0; - uint32_t word = memory[string_addr + (i++)].u; - for (j = 0; j < 4; j++) { - char ch = (word >> (8 * j)) & 0xFF; - if (ch == '\0') - goto done; - putchar(ch); - } + for (i = 0; i < length;) { + uint32_t word = memory[string_addr + (i / 4)].u; + uint8_t ch = get_char(word, i % 4); + if (ch == '\0') + break; + putchar(ch); + i++; } - done: putchar('\n'); break; } @@ -132,31 +192,30 @@ void run_vm() { putchar('>'); putchar(' '); uint32_t buffer_addr = dest_addr + 1; + uint32_t length = 0; int word_index = 0; int char_index = 0; - uint32_t length = 1; while (1) { int ch = getchar(); if (ch == '\n' || ch == EOF) { - /* Store null terminator */ uint32_t word = memory[buffer_addr + word_index].u; word = set_char(word, char_index, '\0'); memory[buffer_addr + word_index].u = word; break; } + uint32_t word = memory[buffer_addr + word_index].u; word = set_char(word, char_index, ch); memory[buffer_addr + word_index].u = word; - length++; char_index++; if (char_index == 4) { char_index = 0; word_index++; } + length++; } - memory[dest_addr].u = length; break; } @@ -168,27 +227,28 @@ void run_vm() { } int main() { - memory[0].u = OP_READ_STRING; - memory[1].u = 0; - memory[2].u = 0; - memory[3].u = 104; - memory[4].u = OP_ADD_F32; - memory[5].u = 102; - memory[6].u = 103; - memory[7].u = 103; - memory[8].u = OP_SUB; - memory[9].u = 100; - memory[10].u = 101; - memory[11].u = 100; - memory[12].u = OP_JGZ; - memory[13].u = 100; - memory[14].u = 4; - memory[15].u = 4; - memory[16].u = OP_PRINT_STRING; - memory[17].u = 105; - memory[18].u = 0; - memory[19].u = 0; - memory[20].u = OP_HALT; + int i = 0; + memory[i++].u = OP_ADD_F32; + memory[i++].u = 102; + memory[i++].u = 103; + memory[i++].u = 103; + memory[i++].u = OP_SUB; + memory[i++].u = 100; + memory[i++].u = 101; + memory[i++].u = 100; + memory[i++].u = OP_JGZ; + memory[i++].u = 100; + memory[i++].u = 4; + memory[i++].u = 4; + memory[i++].u = OP_F32_TO_STRING; + memory[i++].u = 103; + memory[i++].u = 0; + memory[i++].u = 104; + memory[i++].u = OP_PRINT_STRING; + memory[i++].u = 105; + memory[i++].u = 0; + memory[i++].u = 0; + memory[i++].u = OP_HALT; memory[100].u = 5; memory[101].u = 1; memory[102].f = 5.f; @@ -196,19 +256,5 @@ int main() { run_vm(); - FILE *file = fopen("memory_dump.bin", "wb"); - if (!file) { - perror("Failed to open file"); - return EXIT_FAILURE; - } - size_t written = fwrite(memory, 1, MEMORY_SIZE, file); - if (written != MEMORY_SIZE) { - fprintf(stderr, "Incomplete write: %zu bytes written out of %u\n", written, MEMORY_SIZE); - fclose(file); - return EXIT_FAILURE; - } - - fclose(file); - - return 0; + return core_dump(); }