start of conditionals

This commit is contained in:
SpookyDervish
2025-12-20 16:55:40 +11:00
parent c88a6a993d
commit 7abe9c8f91
4 changed files with 124 additions and 22 deletions

View File

@@ -11,7 +11,7 @@ VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction i
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
}
vmblState->stack[vmblState->stackSize++] = instruction.opperand;
vmblState->stack[vmblState->stackSize++] = instruction.opperands[0];
break;
case INSTRUCTION_ADD:
@@ -22,9 +22,33 @@ VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction i
vmblState->stack[vmblState->stackSize - 2] += vmblState->stack[vmblState->stackSize - 1];
vmblState->stackSize--;
break;
case INSTRUCTION_SUB:
if (vmblState->stackSize < 2) {
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
}
vmblState->stack[vmblState->stackSize - 2] -= vmblState->stack[vmblState->stackSize - 1];
vmblState->stackSize--;
break;
case INSTRUCTION_MUL:
if (vmblState->stackSize < 2) {
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
}
vmblState->stack[vmblState->stackSize - 2] *= vmblState->stack[vmblState->stackSize - 1];
vmblState->stackSize--;
break;
case INSTRUCTION_DIV:
if (vmblState->stackSize < 2) {
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
}
vmblState->stack[vmblState->stackSize - 2] /= vmblState->stack[vmblState->stackSize - 1];
vmblState->stackSize--;
break;
case INSTRUCTION_DUPLICATE:
if (vmblState->stackSize - instruction.opperand <= 0) {
if (vmblState->stackSize - instruction.opperands[0] <= 0) {
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
}
@@ -32,17 +56,17 @@ VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction i
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
}
if (instruction.opperand < 0) {
if (instruction.opperands[0] < 0) {
return (VMBL_Exception) { EXCEPTION_INVALID_OPPERAND };
}
vmblState->stack[vmblState->stackSize++] = vmblState->stack[vmblState->stackSize - 1 - instruction.opperand];
vmblState->stack[vmblState->stackSize++] = vmblState->stack[vmblState->stackSize - 1 - instruction.opperands[0]];
break;
case INSTRUCTION_JUMP:
vmblState->ip = instruction.opperand;
vmblState->ip = instruction.opperands[0];
break;
@@ -50,6 +74,44 @@ VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction i
vmblState->halted = true;
break;
case INSTRUCTION_EQUAL:
if (instruction.opperands[0] < 0 || instruction.opperands[1] < 0) {
return (VMBL_Exception) { EXCEPTION_INVALID_OPPERAND };
}
if (vmblState->stackSize >= VMBL_STACK_SIZE || instruction.opperands[0] > VMBL_STACK_SIZE || instruction.opperands[1] > VMBL_STACK_SIZE) {
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
}
vmblState->stack[vmblState->stackSize] = vmblState->stack[vmblState->stackSize-instruction.opperands[0]] == vmblState->stack[vmblState->stackSize-instruction.opperands[1]];
break;
case INSTRUCTION_EQUAL_TOP:
if (vmblState->stackSize >= VMBL_STACK_SIZE) {
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
}
vmblState->stack[vmblState->stackSize++] = vmblState->stack[vmblState->stackSize-1] == vmblState->stack[vmblState->stackSize-2];
break;
case INSTRUCTION_JUMP_CONDITIONAL:
if (instruction.opperands[0] < 0) {
return (VMBL_Exception) { EXCEPTION_INVALID_OPPERAND };
}
if (vmblState->stack[vmblState->stackSize--]) {
vmblState->ip = instruction.opperands[0];
}
break;
case INSTRUCTION_POP:
if (vmblState->stackSize <= 0) {
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
}
vmblState->stackSize--;
break;
default:
return (VMBL_Exception) { EXCEPTION_INVALID_OPCODE };
break;
@@ -64,7 +126,7 @@ void VMBL_Dump(VMBL_State vmblState, VMBL_Exception exception) {
if (vmblState.stackSize > 0) {
for (size_t i = 0; i < vmblState.stackSize; i++) {
fprintf(stderr, " 0x%lX: 0x%ld\n", i, vmblState.stack[i]);
fprintf(stderr, " 0x%lX: %ld\n", i, vmblState.stack[i]);
}
} else {
fprintf(stderr, " [empty]\n");
@@ -83,12 +145,12 @@ void VMBL_StartVM(VMBL_State *vmblState) {
VMBL_Instruction instruction = vmblState->program[vmblState->ip++];
printf("%s 0x%lx\n", instructionTypeToCStr(instruction.type), instruction.opperand);
//printf("%s 0x%lx, 0x%lx, 0x%lx\n", instructionTypeToCStr(instruction.type), instruction.opperands[0], instruction.opperands[1], instruction.opperands[2]);
VMBL_Exception exception = VBML_ExecuteInstruction(vmblState, instruction);
if (exception.type != EXCEPTION_NONE) {
VMBL_Dump(*vmblState, exception);
//VMBL_Dump(*vmblState, exception);
return;
}
@@ -108,7 +170,7 @@ void VMBL_LoadExecutable(VMBL_State *vmblState, VMBL_Instruction *program, size_
exit(1);
}
memcpy(vmblState->program, program, sizeof(program[0]) * programSize);
memcpy(&vmblState->program, program, sizeof(program) * programSize);
vmblState->programSize = programSize;
}
@@ -143,7 +205,7 @@ void VMBL_SaveExecutable(const char* filePath, VMBL_Instruction *program, size_t
exit(1);
}
fwrite(program, sizeof(program[0]), programSize, file);
fwrite(program, sizeof(program), programSize, file);
fclose(file);
}
@@ -170,6 +232,18 @@ char *instructionTypeToCStr(InstructionType type) {
case INSTRUCTION_HALT:
return "HALT";
break;
case INSTRUCTION_EQUAL:
return "EQ ";
break;
case INSTRUCTION_EQUAL_TOP:
return "EQT ";
break;
case INSTRUCTION_JUMP_CONDITIONAL:
return "JC ";
break;
default:
return "??? ";