add direct char casting
This commit is contained in:
parent
6b7beadaeb
commit
5107ac5df8
72
src/vm.c
72
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue