quick-n-dirty num to str
This commit is contained in:
parent
a1c74760a1
commit
af01b5afae
152
src/vm.c
152
src/vm.c
|
@ -7,7 +7,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* #define MEMORY_SIZE 65536 /\* 64KB memory (adjustable) *\/ */
|
/* #define MEMORY_SIZE 65536 /\* 64KB memory (adjustable) *\/ */
|
||||||
#define MEMORY_SIZE 200
|
#define MEMORY_SIZE 1024
|
||||||
typedef union {
|
typedef union {
|
||||||
float f;
|
float f;
|
||||||
uint32_t u;
|
uint32_t u;
|
||||||
|
@ -27,16 +27,66 @@ typedef enum {
|
||||||
OP_MOV, /* dest = src1 */
|
OP_MOV, /* dest = src1 */
|
||||||
OP_JMP, /* jump to address src1 unconditionally */
|
OP_JMP, /* jump to address src1 unconditionally */
|
||||||
OP_JGZ, /* jump to address dest if src1 > 0 */
|
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_READ_STRING,
|
||||||
OP_PRINT_STRING,
|
OP_PRINT_STRING,
|
||||||
} Opcode;
|
} 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) {
|
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) {
|
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() {
|
void run_vm() {
|
||||||
|
@ -109,22 +159,32 @@ void run_vm() {
|
||||||
pc = (jump_target & mask) | (pc & ~mask);
|
pc = (jump_target & mask) | (pc & ~mask);
|
||||||
break;
|
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: {
|
case OP_PRINT_STRING: {
|
||||||
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;
|
||||||
while (i < length) {
|
for (i = 0; i < length;) {
|
||||||
int j = 0;
|
uint32_t word = memory[string_addr + (i / 4)].u;
|
||||||
uint32_t word = memory[string_addr + (i++)].u;
|
uint8_t ch = get_char(word, i % 4);
|
||||||
for (j = 0; j < 4; j++) {
|
|
||||||
char ch = (word >> (8 * j)) & 0xFF;
|
|
||||||
if (ch == '\0')
|
if (ch == '\0')
|
||||||
goto done;
|
break;
|
||||||
putchar(ch);
|
putchar(ch);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
done:
|
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -132,31 +192,30 @@ void run_vm() {
|
||||||
putchar('>');
|
putchar('>');
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
uint32_t buffer_addr = dest_addr + 1;
|
uint32_t buffer_addr = dest_addr + 1;
|
||||||
|
uint32_t length = 0;
|
||||||
int word_index = 0;
|
int word_index = 0;
|
||||||
int char_index = 0;
|
int char_index = 0;
|
||||||
uint32_t length = 1;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int ch = getchar();
|
int ch = getchar();
|
||||||
if (ch == '\n' || ch == EOF) {
|
if (ch == '\n' || ch == EOF) {
|
||||||
/* Store null terminator */
|
|
||||||
uint32_t word = memory[buffer_addr + word_index].u;
|
uint32_t word = memory[buffer_addr + word_index].u;
|
||||||
word = set_char(word, char_index, '\0');
|
word = set_char(word, char_index, '\0');
|
||||||
memory[buffer_addr + word_index].u = word;
|
memory[buffer_addr + word_index].u = word;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t word = memory[buffer_addr + word_index].u;
|
uint32_t word = memory[buffer_addr + word_index].u;
|
||||||
word = set_char(word, char_index, ch);
|
word = set_char(word, char_index, ch);
|
||||||
memory[buffer_addr + word_index].u = word;
|
memory[buffer_addr + word_index].u = word;
|
||||||
length++;
|
|
||||||
|
|
||||||
char_index++;
|
char_index++;
|
||||||
if (char_index == 4) {
|
if (char_index == 4) {
|
||||||
char_index = 0;
|
char_index = 0;
|
||||||
word_index++;
|
word_index++;
|
||||||
}
|
}
|
||||||
|
length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory[dest_addr].u = length;
|
memory[dest_addr].u = length;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -168,27 +227,28 @@ void run_vm() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
memory[0].u = OP_READ_STRING;
|
int i = 0;
|
||||||
memory[1].u = 0;
|
memory[i++].u = OP_ADD_F32;
|
||||||
memory[2].u = 0;
|
memory[i++].u = 102;
|
||||||
memory[3].u = 104;
|
memory[i++].u = 103;
|
||||||
memory[4].u = OP_ADD_F32;
|
memory[i++].u = 103;
|
||||||
memory[5].u = 102;
|
memory[i++].u = OP_SUB;
|
||||||
memory[6].u = 103;
|
memory[i++].u = 100;
|
||||||
memory[7].u = 103;
|
memory[i++].u = 101;
|
||||||
memory[8].u = OP_SUB;
|
memory[i++].u = 100;
|
||||||
memory[9].u = 100;
|
memory[i++].u = OP_JGZ;
|
||||||
memory[10].u = 101;
|
memory[i++].u = 100;
|
||||||
memory[11].u = 100;
|
memory[i++].u = 4;
|
||||||
memory[12].u = OP_JGZ;
|
memory[i++].u = 4;
|
||||||
memory[13].u = 100;
|
memory[i++].u = OP_F32_TO_STRING;
|
||||||
memory[14].u = 4;
|
memory[i++].u = 103;
|
||||||
memory[15].u = 4;
|
memory[i++].u = 0;
|
||||||
memory[16].u = OP_PRINT_STRING;
|
memory[i++].u = 104;
|
||||||
memory[17].u = 105;
|
memory[i++].u = OP_PRINT_STRING;
|
||||||
memory[18].u = 0;
|
memory[i++].u = 105;
|
||||||
memory[19].u = 0;
|
memory[i++].u = 0;
|
||||||
memory[20].u = OP_HALT;
|
memory[i++].u = 0;
|
||||||
|
memory[i++].u = OP_HALT;
|
||||||
memory[100].u = 5;
|
memory[100].u = 5;
|
||||||
memory[101].u = 1;
|
memory[101].u = 1;
|
||||||
memory[102].f = 5.f;
|
memory[102].f = 5.f;
|
||||||
|
@ -196,19 +256,5 @@ int main() {
|
||||||
|
|
||||||
run_vm();
|
run_vm();
|
||||||
|
|
||||||
FILE *file = fopen("memory_dump.bin", "wb");
|
return core_dump();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue