From 5107ac5df8759c0e33af08ea15ab4e471896f046 Mon Sep 17 00:00:00 2001 From: zongor Date: Fri, 13 Jun 2025 19:13:47 -0400 Subject: [PATCH] add direct char casting --- src/vm.c | 72 +++++++++++++++++++++++--------------------------------- src/vm.h | 1 + 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/src/vm.c b/src/vm.c index 0bebbd7..09eba7f 100644 --- a/src/vm.c +++ b/src/vm.c @@ -20,23 +20,10 @@ int core_dump(Data *memory, uint32_t memory_size) { return EXIT_SUCCESS; } -uint8_t get_char(uint32_t word, int index) { - return (word >> (8 * index)) & 0xFF; -} - -uint32_t set_char(uint32_t word, int index, uint8_t ch) { - return (word & ~(0xFF << (8 * index))) | (ch << (8 * index)); -} - -void set_memory_char(Data *memory, uint8_t ch, uint32_t buffer_addr, - uint32_t length) { - uint32_t word = memory[buffer_addr + (length / 4)].u; - word = set_char(word, length % 4, ch); - memory[buffer_addr + (length / 4)].u = word; -} - -/* Pack string into union-based memory */ -void pack_string(Data *memory, const char *str, uint32_t length, +/** + * String copy in data memory. + */ +void mem_strcpy(Data *memory, const char *str, uint32_t length, uint32_t dest_addr) { memory[dest_addr].u = length; uint32_t buffer_addr = dest_addr + 1; @@ -46,7 +33,7 @@ void pack_string(Data *memory, const char *str, uint32_t length, if (ch == '\0') { break; } - set_memory_char(memory, ch, buffer_addr, i); + memory[buffer_addr + (i / 4)].c[i % 4] = ch; i++; } } @@ -69,6 +56,8 @@ void run_vm(Data *memory, uint32_t memory_size) { } switch (opcode) { + case OP_HALT: + return; case OP_ADD: memory[dest_addr].u = memory[src1_addr].u + memory[src2_addr].u; break; @@ -112,8 +101,6 @@ void run_vm(Data *memory, uint32_t memory_size) { memory[dest_addr].f = (float)memory[src1_addr].u; break; } - case OP_HALT: - return; case OP_MOV: memory[dest_addr] = memory[src1_addr]; break; @@ -133,28 +120,14 @@ void run_vm(Data *memory, uint32_t memory_size) { int32_t a = (int32_t)memory[src1_addr].u; char buffer[32]; sprintf(buffer, "%d", a); - pack_string(memory, buffer, strlen(buffer), dest_addr); + mem_strcpy(memory, 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(memory, 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 i; - for (i = 0; i < length; i++) { - uint32_t word = memory[string_addr + (i / 4)].u; - uint8_t ch = get_char(word, i % 4); - if (ch == '\0') - break; - putchar(ch); - } - putchar('\n'); + mem_strcpy(memory, buffer, strlen(buffer), dest_addr); break; } case OP_READ_STRING: { @@ -163,34 +136,47 @@ void run_vm(Data *memory, uint32_t memory_size) { while (1) { int ch = getchar(); if (ch == '\n' || ch == EOF) { - set_memory_char(memory, '\0', buffer_addr, length); + memory[buffer_addr + (length / 4)].c[length % 4] = '\0'; break; } - set_memory_char(memory, ch, buffer_addr, length); + memory[buffer_addr + (length / 4)].c[length % 4] = ch; length++; } memory[dest_addr].u = length; break; } + case OP_PRINT_STRING: { + uint32_t string_addr = src1_addr; + uint32_t length = memory[src1_addr - 1].u; + uint32_t i; + for (i = 0; i < length; i++) { + uint8_t ch = memory[string_addr + (i / 4)].c[i % 4]; + if (ch == '\0') + break; + putchar(ch); + } + putchar('\n'); + break; + } case OP_CMP_STRING: { uint32_t addr1 = src1_addr; uint32_t addr2 = src2_addr; uint32_t length1 = memory[src1_addr - 1].u; uint32_t length2 = memory[src2_addr - 1].u; - int equal = 1; + uint32_t equal = 1; if (length1 != length2) { equal = 0; } else { uint32_t i = 0; while (i < length1) { - uint32_t word1 = memory[addr1 + i].u; - uint32_t word2 = memory[addr2 + i].u; - if (word1 != word2) { + uint32_t char1 = memory[addr1 + i].u; + uint32_t char2 = memory[addr2 + i].u; + if (char1 != char2) { equal = 0; break; } - if ((word1 & 0xFF) == '\0' && (word2 & 0xFF) == '\0') + if ((char1 & 0xFF) == '\0' && (char2 & 0xFF) == '\0') break; } } diff --git a/src/vm.h b/src/vm.h index 47c0a34..60b5ae2 100644 --- a/src/vm.h +++ b/src/vm.h @@ -6,6 +6,7 @@ typedef union { float f; uint32_t u; + char c[4]; } Data; typedef enum {