add fat pointers for strings, update makefile, test

This commit is contained in:
zongor 2025-06-08 16:41:53 -04:00
parent 2817e940e1
commit a1c74760a1
5 changed files with 38 additions and 53 deletions

3
.gitignore vendored
View File

@ -101,4 +101,5 @@ Module.symvers
Mkfile.old Mkfile.old
dkms.conf dkms.conf
zlc zre
memory_dump.bin

View File

@ -7,7 +7,7 @@ LDLIBS +=
# Source and build configuration # Source and build configuration
SRC = $(wildcard *.c) SRC = $(wildcard *.c)
OBJ = $(SRC:.c=.o) OBJ = $(SRC:.c=.o)
EXEC = zlc EXEC = zre
# Phony targets # Phony targets
.PHONY: all clean test install .PHONY: all clean test install

View File

@ -4,15 +4,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/mman.h>
#include <unistd.h> #include <unistd.h>
#define MEMORY_SIZE 65536 /* 64KB memory (adjustable) */ /* #define MEMORY_SIZE 65536 /\* 64KB memory (adjustable) *\/ */
#define MEMORY_SIZE 200
typedef union { typedef union {
float f; float f;
uint32_t u; uint32_t u;
} FloatUint32Union; } Data;
FloatUint32Union memory[MEMORY_SIZE]; /* Memory array */ Data memory[MEMORY_SIZE]; /* Memory array */
typedef enum { typedef enum {
OP_HALT, /* terminate execution */ OP_HALT, /* terminate execution */
@ -38,6 +38,7 @@ uint8_t get_char(uint32_t word, int index) {
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 * index))) | (ch << (8 * index));
} }
void run_vm() { void run_vm() {
uint32_t pc = 0; /* Program counter */ uint32_t pc = 0; /* Program counter */
@ -58,51 +59,30 @@ void run_vm() {
switch (opcode) { switch (opcode) {
case OP_ADD: case OP_ADD:
memory[dest_addr].u = memory[src1_addr].u + memory[src2_addr].u; memory[dest_addr].u = memory[src1_addr].u + memory[src2_addr].u;
printf("ADD;src1[%d]:%d;src2[%d]:%d;dest[%d]:%d\n", src1_addr,
memory[src1_addr].u, src2_addr, memory[src2_addr].u, dest_addr,
memory[dest_addr].u);
break; break;
case OP_SUB: case OP_SUB:
memory[dest_addr].u = memory[src1_addr].u - memory[src2_addr].u; memory[dest_addr].u = memory[src1_addr].u - memory[src2_addr].u;
printf("ADD;src1[%d]:%d;src2[%d]:%d;dest[%d]:%d\n", src1_addr,
memory[src1_addr].u, src2_addr, memory[src2_addr].u, dest_addr,
memory[dest_addr].u);
break; break;
case OP_MUL: case OP_MUL:
memory[dest_addr].u = memory[src1_addr].u * memory[src2_addr].u; memory[dest_addr].u = memory[src1_addr].u * memory[src2_addr].u;
printf("ADD;src1[%d]:%d;src2[%d]:%d;dest[%d]:%d\n", src1_addr,
memory[src1_addr].u, src2_addr, memory[src2_addr].u, dest_addr,
memory[dest_addr].u);
break; break;
case OP_DIV: case OP_DIV:
memory[dest_addr].u = memory[src1_addr].u / memory[src2_addr].u; memory[dest_addr].u = memory[src1_addr].u / memory[src2_addr].u;
printf("ADD;src1[%d]:%d;src2[%d]:%d;dest[%d]:%d\n", src1_addr,
memory[src1_addr].u, src2_addr, memory[src2_addr].u, dest_addr,
memory[dest_addr].u);
break; break;
case OP_ADD_F32: case OP_ADD_F32:
memory[dest_addr].f = memory[src1_addr].f + memory[src2_addr].f; memory[dest_addr].f = memory[src1_addr].f + memory[src2_addr].f;
printf("ADD;src1[%d]:%f;src2[%d]:%f;dest[%d]:%f\n", src1_addr,
memory[src1_addr].f, src2_addr, memory[src2_addr].f, dest_addr,
memory[dest_addr].f);
break; break;
case OP_SUB_F32: case OP_SUB_F32:
memory[dest_addr].f = memory[src1_addr].f - memory[src2_addr].f; memory[dest_addr].f = memory[src1_addr].f - memory[src2_addr].f;
printf("ADD;src1[%d]:%f;src2[%d]:%f;dest[%d]:%f\n", src1_addr,
memory[src1_addr].f, src2_addr, memory[src2_addr].f, dest_addr,
memory[dest_addr].f);
break; break;
case OP_MUL_F32: case OP_MUL_F32:
memory[dest_addr].f = memory[src1_addr].f * memory[src2_addr].f; memory[dest_addr].f = memory[src1_addr].f * memory[src2_addr].f;
printf("ADD;src1[%d]:%f;src2[%d]:%f;dest[%d]:%f\n", src1_addr,
memory[src1_addr].f, src2_addr, memory[src2_addr].f, dest_addr,
memory[dest_addr].f);
break; break;
case OP_DIV_F32: case OP_DIV_F32:
@ -111,31 +91,16 @@ void run_vm() {
exit(1); exit(1);
} }
memory[dest_addr].f = memory[src1_addr].f / memory[src2_addr].f; memory[dest_addr].f = memory[src1_addr].f / memory[src2_addr].f;
printf("ADD;src1[%d]:%f;src2[%d]:%f;dest[%d]:%f\n", src1_addr,
memory[src1_addr].f, src2_addr, memory[src2_addr].f, dest_addr,
memory[dest_addr].f);
break; break;
case OP_HALT: case OP_HALT:
printf("ADD;src1[%d]:%d;src2[%d]:%d;dest[%d]:%d\n", src1_addr,
memory[src1_addr].u, src2_addr, memory[src2_addr].u, dest_addr,
memory[dest_addr].u);
return; return;
case OP_MOV: case OP_MOV:
printf("ADD;src1[%d]:%d;src2[%d]:%d;dest[%d]:%d\n", src1_addr,
memory[src1_addr].u, src2_addr, memory[src2_addr].u, dest_addr,
memory[dest_addr].u);
memory[dest_addr] = memory[src1_addr]; memory[dest_addr] = memory[src1_addr];
break; break;
case OP_JMP: case OP_JMP:
printf("ADD;src1[%d]:%d;src2[%d]:%d;dest[%d]:%d\n", src1_addr,
memory[src1_addr].u, src2_addr, memory[src2_addr].u, dest_addr,
memory[dest_addr].u);
pc = src1_addr; /* Jump to address */ pc = src1_addr; /* Jump to address */
break; break;
case OP_JGZ: { case OP_JGZ: {
printf("ADD;src1[%d]:%d;src2[%d]:%d;dest[%d]:%d\n", src1_addr,
memory[src1_addr].u, src2_addr, memory[src2_addr].u, dest_addr,
memory[dest_addr].u);
uint32_t value = memory[src1_addr].u; uint32_t value = memory[src1_addr].u;
uint32_t jump_target = src2_addr; uint32_t jump_target = src2_addr;
@ -145,10 +110,11 @@ void run_vm() {
break; break;
} }
case OP_PRINT_STRING: { case OP_PRINT_STRING: {
printf("PRINT_STRING;");
uint32_t string_addr = src1_addr; uint32_t string_addr = src1_addr;
int i = 0; uint32_t length = memory[src1_addr-1].u;
while (1) {
uint32_t i;
while (i < length) {
int j = 0; int j = 0;
uint32_t word = memory[string_addr + (i++)].u; uint32_t word = memory[string_addr + (i++)].u;
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
@ -163,10 +129,12 @@ void run_vm() {
break; break;
} }
case OP_READ_STRING: { case OP_READ_STRING: {
printf("> "); putchar('>');
uint32_t buffer_addr = dest_addr; putchar(' ');
uint32_t buffer_addr = dest_addr + 1;
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();
@ -180,6 +148,7 @@ void run_vm() {
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) {
@ -187,6 +156,8 @@ void run_vm() {
word_index++; word_index++;
} }
} }
memory[dest_addr].u = length;
break; break;
} }
default: default:
@ -214,7 +185,7 @@ int main() {
memory[14].u = 4; memory[14].u = 4;
memory[15].u = 4; memory[15].u = 4;
memory[16].u = OP_PRINT_STRING; memory[16].u = OP_PRINT_STRING;
memory[17].u = 104; memory[17].u = 105;
memory[18].u = 0; memory[18].u = 0;
memory[19].u = 0; memory[19].u = 0;
memory[20].u = OP_HALT; memory[20].u = OP_HALT;
@ -225,6 +196,19 @@ int main() {
run_vm(); run_vm();
printf("Dest at address 103: %f\n", memory[103].f); 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 0;
} }

View File

@ -1 +1 @@
1 + 2 print(1 + 2);

View File

@ -1,5 +1,5 @@
for (let i = 0; i < 10; i = i + 1) { for (let i = 0; i < 10; i = i + 1) {
print i; print(i);
} }
let val = true; let val = true;
@ -7,6 +7,6 @@ let j = 0;
while (val) { while (val) {
j = j + 1; j = j + 1;
if (j > 9) val = false; if (j > 9) val = false;
print j; print(j);
} }
print "done"; print("done");