fix string handling
This commit is contained in:
parent
bb9e30a1c1
commit
6b7beadaeb
|
@ -31,7 +31,7 @@ OBJ_WASM = $(addprefix $(OBJ_DIR_WASM)/,$(notdir $(SRC:.c=.o)))
|
||||||
.PHONY: all clean install wasm
|
.PHONY: all clean install wasm
|
||||||
|
|
||||||
# Default target builds both versions
|
# Default target builds both versions
|
||||||
all: native wasm
|
all: native
|
||||||
|
|
||||||
# Native build rules
|
# Native build rules
|
||||||
# ------------------
|
# ------------------
|
||||||
|
|
69
src/vm.c
69
src/vm.c
|
@ -28,32 +28,26 @@ uint32_t set_char(uint32_t word, int index, uint8_t ch) {
|
||||||
return (word & ~(0xFF << (8 * index))) | (ch << (8 * index));
|
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 */
|
/* Pack string into union-based memory */
|
||||||
void pack_string(Data *memory, const char *str, uint32_t length, uint32_t dest_addr) {
|
void pack_string(Data *memory, const char *str, uint32_t length,
|
||||||
|
uint32_t dest_addr) {
|
||||||
memory[dest_addr].u = length;
|
memory[dest_addr].u = length;
|
||||||
uint32_t buffer_addr = dest_addr + 1;
|
uint32_t buffer_addr = dest_addr + 1;
|
||||||
int word_index = 0;
|
|
||||||
int char_index = 0;
|
|
||||||
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
while (i < length) {
|
while (i < length) {
|
||||||
char ch = str[i++];
|
char ch = str[i];
|
||||||
if (ch == '\0') {
|
if (ch == '\0') {
|
||||||
uint32_t word = memory[buffer_addr + word_index].u;
|
|
||||||
word = set_char(word, char_index, '\0');
|
|
||||||
memory[buffer_addr + word_index].u = word;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
set_memory_char(memory, ch, buffer_addr, i);
|
||||||
uint32_t word = memory[buffer_addr + word_index].u;
|
i++;
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,13 +105,11 @@ void run_vm(Data *memory, uint32_t memory_size) {
|
||||||
memory[dest_addr].f = memory[src1_addr].f / memory[src2_addr].f;
|
memory[dest_addr].f = memory[src1_addr].f / memory[src2_addr].f;
|
||||||
break;
|
break;
|
||||||
case OP_F32_TO_INT: {
|
case OP_F32_TO_INT: {
|
||||||
float tmp = memory[src1_addr].f;
|
memory[dest_addr].u = (uint32_t)memory[src1_addr].f;
|
||||||
memory[dest_addr].u = (uint32_t)tmp;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_INT_TO_F32: {
|
case OP_INT_TO_F32: {
|
||||||
uint32_t tmp = memory[src1_addr].u;
|
memory[dest_addr].f = (float)memory[src1_addr].u;
|
||||||
memory[dest_addr].f = (float)tmp;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_HALT:
|
case OP_HALT:
|
||||||
|
@ -155,43 +147,26 @@ void run_vm(Data *memory, uint32_t memory_size) {
|
||||||
uint32_t string_addr = src1_addr;
|
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;
|
uint32_t i;
|
||||||
for (i = 0; i < length;) {
|
for (i = 0; i < length; i++) {
|
||||||
uint32_t word = memory[string_addr + (i / 4)].u;
|
uint32_t word = memory[string_addr + (i / 4)].u;
|
||||||
uint8_t ch = get_char(word, i % 4);
|
uint8_t ch = get_char(word, i % 4);
|
||||||
if (ch == '\0')
|
if (ch == '\0')
|
||||||
break;
|
break;
|
||||||
putchar(ch);
|
putchar(ch);
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_READ_STRING: {
|
case OP_READ_STRING: {
|
||||||
putchar('>');
|
|
||||||
putchar(' ');
|
|
||||||
uint32_t buffer_addr = dest_addr + 1;
|
uint32_t buffer_addr = dest_addr + 1;
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
int word_index = 0;
|
|
||||||
int char_index = 0;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int ch = getchar();
|
int ch = getchar();
|
||||||
if (ch == '\n' || ch == EOF) {
|
if (ch == '\n' || ch == EOF) {
|
||||||
uint32_t word = memory[buffer_addr + word_index].u;
|
set_memory_char(memory, '\0', buffer_addr, length);
|
||||||
word = set_char(word, char_index, '\0');
|
|
||||||
memory[buffer_addr + word_index].u = word;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
set_memory_char(memory, ch, buffer_addr, length);
|
||||||
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++;
|
length++;
|
||||||
}
|
}
|
||||||
memory[dest_addr].u = length;
|
memory[dest_addr].u = length;
|
||||||
|
@ -201,10 +176,14 @@ void run_vm(Data *memory, uint32_t memory_size) {
|
||||||
uint32_t addr1 = src1_addr;
|
uint32_t addr1 = src1_addr;
|
||||||
uint32_t addr2 = src2_addr;
|
uint32_t addr2 = src2_addr;
|
||||||
uint32_t length1 = memory[src1_addr - 1].u;
|
uint32_t length1 = memory[src1_addr - 1].u;
|
||||||
|
uint32_t length2 = memory[src2_addr - 1].u;
|
||||||
int equal = 1;
|
int equal = 1;
|
||||||
|
|
||||||
uint32_t i;
|
if (length1 != length2) {
|
||||||
for (i = 0; i < length1;) {
|
equal = 0;
|
||||||
|
} else {
|
||||||
|
uint32_t i = 0;
|
||||||
|
while (i < length1) {
|
||||||
uint32_t word1 = memory[addr1 + i].u;
|
uint32_t word1 = memory[addr1 + i].u;
|
||||||
uint32_t word2 = memory[addr2 + i].u;
|
uint32_t word2 = memory[addr2 + i].u;
|
||||||
if (word1 != word2) {
|
if (word1 != word2) {
|
||||||
|
@ -214,6 +193,7 @@ void run_vm(Data *memory, uint32_t memory_size) {
|
||||||
if ((word1 & 0xFF) == '\0' && (word2 & 0xFF) == '\0')
|
if ((word1 & 0xFF) == '\0' && (word2 & 0xFF) == '\0')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
memory[dest_addr].u = equal;
|
memory[dest_addr].u = equal;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -223,4 +203,3 @@ void run_vm(Data *memory, uint32_t memory_size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue