This commit is contained in:
zongor 2025-07-13 09:35:11 -04:00
parent 7bcaa080b9
commit 66adb19578
2 changed files with 12 additions and 32 deletions

View File

@ -27,7 +27,7 @@ typedef struct {
#define STACK_SIZE 256 #define STACK_SIZE 256
typedef struct { typedef struct {
uint32_t pc; /* Program counter */ uint32_t pc; /* Program counter */
uint32_t fp; /* Frame pointer plast allocated value) */ uint32_t fp; /* Frame pointer (last allocated value) */
uint32_t sp; /* stack pointer (top of stack) */ uint32_t sp; /* stack pointer (top of stack) */
uint32_t rp; /* return stack pointer (top of stack) */ uint32_t rp; /* return stack pointer (top of stack) */
uint32_t mp; /* Memory pointer (last allocated value) */ uint32_t mp; /* Memory pointer (last allocated value) */

View File

@ -39,44 +39,22 @@ void mem_strcpy(Value *memory, const char *str, uint32_t length,
* Step to the next opcode in the vm. * Step to the next opcode in the vm.
*/ */
bool step_vm(VM *vm) { bool step_vm(VM *vm) {
uint32_t instruction = vm->memory[vm->pc].u; /* Get current instruction & Advance to next instruction */
uint32_t instruction = vm->memory[vm->pc++].u;
/* Extract 8-bit register indices from 32-bit instruction */
uint8_t opcode = (instruction >> 24) & 0xFF; uint8_t opcode = (instruction >> 24) & 0xFF;
uint8_t dest = (instruction >> 16) & 0xFF; uint8_t dest = (instruction >> 16) & 0xFF;
uint8_t src1 = (instruction >> 8) & 0xFF; uint8_t src1 = (instruction >> 8) & 0xFF;
uint8_t src2 = instruction & 0xFF; uint8_t src2 = instruction & 0xFF;
/* Advance to next instruction */
vm->pc++;
#ifdef DEBUG
printOp(opcode, dest, src1, src2);
printf("dest=%d, src1=%d, src2=%d\n", vm->frames[vm->fp].registers[dest].u,
vm->frames[vm->fp].registers[src1].i,
vm->frames[vm->fp].registers[src2].i);
uint32_t i;
printf("return_stack[");
for (i = 0; i < vm->rp; i++)
printf("%d,", vm->return_stack[i].u);
printf("]\n");
printf("stack[");
for (i = 0; i < vm->sp; i++)
printf("%d,", vm->stack[i].i);
printf("]\n");
#endif
switch (opcode) { switch (opcode) {
case OP_HALT: case OP_HALT:
return false; return false;
case OP_CALL:; case OP_CALL:; /* whats up with this semicolon? ANSI C does not allow you to create a variabel after a case, so this noop is here */
uint32_t jmp = uint32_t jmp = vm->memory[vm->pc++].u; /* location of function in memory */
vm->memory[vm->pc++].u; /* set pc to location of function in memory */
vm->return_stack[vm->rp++].u = vm->pc; /* set return address */ vm->return_stack[vm->rp++].u = vm->pc; /* set return address */
vm->fp++; /* increment to the next free frame */ vm->fp++; /* increment to the next free frame */
vm->frames[vm->fp].allocated.start = vm->frames[vm->fp].allocated.start = vm->mp; /* set start of new memory block */
vm->mp; /* set start of new memory block */
vm->pc = jmp; vm->pc = jmp;
return true; return true;
case OP_RETURN: case OP_RETURN:
@ -289,7 +267,7 @@ bool step_vm(VM *vm) {
uint32_t addr2 = (uint32_t)vm->frames[vm->fp].registers[src2].u; uint32_t addr2 = (uint32_t)vm->frames[vm->fp].registers[src2].u;
uint32_t length1 = vm->memory[addr1 - 1].u; uint32_t length1 = vm->memory[addr1 - 1].u;
uint32_t length2 = vm->memory[addr2 - 1].u; uint32_t length2 = vm->memory[addr2 - 1].u;
uint32_t equal = 1; uint32_t equal = 1; /* we dont have a native boolean type so we use uint32_t */
if (length1 != length2) { if (length1 != length2) {
equal = 0; equal = 0;
@ -302,13 +280,15 @@ bool step_vm(VM *vm) {
equal = 0; equal = 0;
break; break;
} }
if ((char1 & 0xFF) == '\0' && (char2 & 0xFF) == '\0') if ((char1 & 0xFF) == '\0' && (char2 & 0xFF) == '\0') {
return true; equal = 1;
break;
}
} }
} }
vm->memory[dest].u = equal; vm->memory[dest].u = equal;
return true; return true;
} }
} }
return false; return false; /* something bad happened */
} }