WIP change to store primitives in memory intead of code

This commit is contained in:
zongor 2025-08-23 21:29:46 -07:00
parent cc009b4a4a
commit 8aeeebc351
6 changed files with 202 additions and 123 deletions

View File

@ -1,5 +1,6 @@
#include "../../compiler.h"
#include "../../vm.h"
#include "../../test.h"
#define MAX_SRC_SIZE 16384
@ -55,12 +56,14 @@ int main(int argc, char **argv) {
vm.memory_size = MEMORY_SIZE;
if (argc == 1) {
repl(&vm);
test_loop_compile(&vm);
/* repl(&vm); */
} else if (argc == 2) {
compileFile(argv[1], &vm);
} else {
fprintf(stderr, "Usage: %s <file.zrl>\n", argv[0]);
return 64;
repl(&vm);
}
bool running = true;

View File

@ -31,6 +31,7 @@ typedef struct {
} ParseRule;
Parser parser;
SymbolTable st;
void errorAt(Token *token, const char *message) {
if (parser.panicMode)
@ -309,11 +310,29 @@ static void expressionStatement(VM *vm) {
static void intDeclaration(VM *vm) {
/* insert variable name in symbol table */
uint32_t length = parser.previous.length - 2;
if (length > SYMBOL_NAME_SIZE) {
error("Variable names cannot be longer than 24 characters.");
return;
}
st.symbols[st.sc].type = INT;
st.symbols[st.sc].frame = vm->fp;
Frame f = vm->frames[vm->fp];
st.symbols[st.sc].reg = f.rp;
uint32_t i;
for (i = 0; i < length; i++) {
st.symbols[st.sc].name[i] = parser.previous.start[i + 1];
}
st.sc++;
if (match(TOKEN_EQ)) {
expression(vm);
} else {
/* not sure here yet */
/* initialize as zero/null */
emitOp(vm, OP_LOADI, vm->frames[vm->fp].rp++, 0, 0);
vm->code[vm->cp++].i = 0;
}
consume(TOKEN_SEMICOLON, "Expect ';' after expression.");
@ -337,6 +356,12 @@ bool compile(const char *source, VM *vm) {
parser.hadError = false;
parser.panicMode = false;
st.sc = 0;
st.name[0] = 'm';
st.name[1] = 'a';
st.name[2] = 'i';
st.name[3] = 'n';
advance();
while (!match(TOKEN_EOF)) {

View File

@ -18,7 +18,7 @@ typedef struct array_def_t {
#define SYMBOL_NAME_SIZE 24
typedef struct symbol_table_t {
typedef struct symbol_t {
char name[SYMBOL_NAME_SIZE];
SymbolType type;
union {
@ -26,6 +26,7 @@ typedef struct symbol_table_t {
ArrayDef ad;
};
int8_t reg;
uint8_t flags[3]; /* only use for padding now, might be used later*/
union {
uint32_t frame;
uint32_t ptr;
@ -35,10 +36,13 @@ typedef struct symbol_table_t {
#define MODULE_NAME_SIZE 32
#define SYMBOL_COUNT 256
typedef struct module_t {
typedef struct symbol_table_t {
char name[MODULE_NAME_SIZE];
Symbol symbols[SYMBOL_COUNT];
} Module;
uint32_t sc;
} SymbolTable;
extern SymbolTable st;
bool compile(const char *source, VM *vm);

View File

@ -3,9 +3,11 @@
bool test_add_compile(VM *vm) {
vm->code[vm->cp++].u = OP(OP_LOADU, 0, 0, 0);
vm->code[vm->cp++].u = 0;
int_alloc(vm, 1);
vm->code[vm->cp++].u = OP(OP_LOADU, 1, 1, 0);
vm->code[vm->cp++].u = 1;
vm->code[vm->cp++].u = OP(OP_LOADU, 1, 0, 0);
vm->code[vm->cp++].u = 2;
int_alloc(vm, 2);
vm->code[vm->cp++].u = OP(OP_ADD_UINT, 2, 1, 0); /* let sum = 1 + 2; */
vm->code[vm->cp++].u = OP(OP_UINT_TO_STRING, 3, 2, 0);
vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(sum.toS()); */
@ -15,25 +17,31 @@ bool test_add_compile(VM *vm) {
bool test_loop_compile(VM *vm) {
vm->code[vm->cp++].u = OP(OP_LOADF, 0, 0, 0); /* let a = 5.0 */
vm->code[vm->cp++].f = 5.0f;
uint32_t addr = real_alloc(vm, 5.0f);
vm->code[vm->cp++].u = addr;
vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 50000, 0, -1) { */
vm->code[vm->cp++].i = 50000;
addr = int_alloc(vm, 50000);
vm->code[vm->cp++].u = addr;
vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */
vm->code[vm->cp++].i = 0;
addr = int_alloc(vm, 0);
vm->code[vm->cp++].u = addr;
vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */
vm->code[vm->cp++].i = -1;
addr = int_alloc(vm, -1);
vm->code[vm->cp++].u = addr;
vm->code[vm->cp++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */
uint32_t jmp = vm->cp + 1;
vm->code[vm->cp++].u = jmp;
int_alloc(vm, vm->cp + 1);
vm->code[vm->cp++].u = 4;
vm->code[vm->cp++].u = OP(OP_LOADF, 5, 0, 0);
vm->code[vm->cp++].f = 5.0f;
addr = real_alloc(vm, 5.0f);
vm->code[vm->cp++].u = addr;
vm->code[vm->cp++].u = OP(OP_ADD_REAL, 0, 0, 5); /* a += 5.0; */
vm->code[vm->cp++].u = OP(OP_ADD_INT, 1, 1, 3); /* (implied by loop) i = i + (-1) */
vm->code[vm->cp++].u = OP(OP_JGE_INT, 4, 1, 2); /* } */
vm->code[vm->cp++].u = OP(OP_REAL_TO_UINT, 1, 0, 0); /* let b = a as nat; */
uint32_t prompt_addr = str_alloc(vm, "Enter a string:", 0);
vm->code[vm->cp++].u = OP(OP_LOADU, 5, 0, 0);
vm->code[vm->cp++].u = prompt_addr;
addr = str_alloc(vm, "Enter a string:", 0);
printf("addr=%d\n", addr);
vm->code[vm->cp++].u = addr;
vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 5, 0); /* print("Enter a string: "); */
vm->code[vm->cp++].u = OP(OP_READ_STRING, 2, 0, 0); /* let user_string = gets(); */
vm->code[vm->cp++].u = OP(OP_UINT_TO_STRING, 3, 1, 0);

View File

@ -43,6 +43,27 @@ uint32_t str_alloc(VM *vm, const char *str, uint32_t length) {
return str_addr;
}
uint32_t real_alloc(VM *vm, float v) {
uint32_t addr = vm->mp;
vm->memory[vm->mp++].f = v;
vm->frames[vm->fp].allocated.end++;
return addr;
}
uint32_t nat_alloc(VM *vm, uint32_t v) {
uint32_t addr = vm->mp;
vm->memory[vm->mp++].u = v;
vm->frames[vm->fp].allocated.end++;
return addr;
}
uint32_t int_alloc(VM *vm, int32_t v) {
uint32_t addr = vm->mp;
vm->memory[vm->mp++].i = v;
vm->frames[vm->fp].allocated.end++;
return addr;
}
/**
* Step to the next opcode in the vm.
*/
@ -74,23 +95,35 @@ bool step_vm(VM *vm) {
vm->frames[vm->fp--].allocated.start; /* reset memory pointer to start
of old slice, pop the frame */
return true;
case OP_LOADI:
vm->frames[vm->fp].registers[dest].i = vm->code[vm->pc++].i;
case OP_LOADI:{
uint32_t ptr = vm->code[vm->pc++].u;
int32_t v = vm->memory[ptr].i;
/* printf("loadi | ptr=%d value=%d dest=%d\n", ptr, v, dest); */
vm->frames[vm->fp].registers[dest].i = v;
return true;
case OP_LOADU:
vm->frames[vm->fp].registers[dest].u = vm->code[vm->pc++].u;
}
case OP_LOADU:{
uint32_t ptr = vm->code[vm->pc++].u;
uint32_t v = vm->memory[ptr].u;
/* printf("loadu | ptr=%d value=%d dest=%d\n", ptr, v, dest); */
vm->frames[vm->fp].registers[dest].u = v;
return true;
case OP_LOADF:
vm->frames[vm->fp].registers[dest].f = vm->code[vm->pc++].f;
}
case OP_LOADF: {
uint32_t ptr = vm->code[vm->pc++].u;
float v = vm->memory[ptr].f;
/* printf("loadf | ptr=%d value=%f dest=%d\n", ptr, v, dest); */
vm->frames[vm->fp].registers[dest].f = v;
return true;
}
case OP_STOREI:
vm->code[vm->pc++].i = vm->frames[vm->fp].registers[dest].i;
vm->memory[vm->code[vm->pc++].u].i = vm->frames[vm->fp].registers[src1].i;
return true;
case OP_STOREU:
vm->code[vm->pc++].u = vm->frames[vm->fp].registers[dest].u;
vm->memory[vm->code[vm->pc++].u].u = vm->frames[vm->fp].registers[src1].u;
return true;
case OP_STOREF:
vm->code[vm->pc++].f = vm->frames[vm->fp].registers[dest].f;
vm->memory[vm->code[vm->pc++].u].f = vm->frames[vm->fp].registers[src1].f;
return true;
case OP_PUSHI:
vm->stack[++vm->sp].i = vm->frames[vm->fp].registers[dest].i;
@ -257,10 +290,13 @@ bool step_vm(VM *vm) {
case OP_PRINT_STRING: {
uint32_t ptr = (uint32_t)vm->frames[vm->fp].registers[src1].u;
uint32_t length = vm->memory[ptr].u;
printf("len=%d\n", length);
uint32_t str_src = ptr + 1;
uint32_t i;
for (i = 0; i < length; i++) {
uint8_t ch = vm->memory[str_src + (i / 4)].c[i % 4];
printf("char=%c\n", ch);
if (ch == '\0')
break;
putchar(ch);

View File

@ -6,5 +6,8 @@
VM* init_vm();
bool step_vm(VM *vm);
uint32_t str_alloc(VM *vm, const char *str, uint32_t length);
uint32_t real_alloc(VM *vm, float v);
uint32_t nat_alloc(VM *vm, uint32_t v);
uint32_t int_alloc(VM *vm, int32_t v);
#endif