From 7abe9c8f9157878b2d666fa91e52813f1b8952a0 Mon Sep 17 00:00:00 2001 From: SpookyDervish <78246495+SpookyDervish@users.noreply.github.com> Date: Sat, 20 Dec 2025 16:55:40 +1100 Subject: [PATCH] start of conditionals --- fib.vmbl | Bin 1792 -> 1536 bytes src/main.c | 8 +++-- src/vmbl.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++------ src/vmbl.h | 44 ++++++++++++++++++++----- 4 files changed, 124 insertions(+), 22 deletions(-) diff --git a/fib.vmbl b/fib.vmbl index ec100392c8ad5bc36a8f471420a66ac3abbefd9e..d8dfbeb3ef45c8eb735a2c9dc8c4de154d54d6f2 100644 GIT binary patch literal 1536 zcmZQzAPz9%P{s-sCs!VqKA3eJPzDoB0F8cd%hQMeDjD`Tg5C8zz CmIL?z literal 1792 zcmZQzzz!Ip!c0&a7at}LGld1lfYQuR8fFffG{b|G>SJ2<=%Sstack[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 "??? "; diff --git a/src/vmbl.h b/src/vmbl.h index 5b337c1..333e57e 100644 --- a/src/vmbl.h +++ b/src/vmbl.h @@ -7,24 +7,46 @@ #include #include "exception.h" -#define VMBL_STACK_SIZE 1024 -#define VMBL_PROGRAM_SIZE 1024 +#define VMBL_STACK_SIZE 0x5E +#define VMBL_PROGRAM_SIZE 512 typedef int64_t Word; typedef enum { + // stack operations INSTRUCTION_PUSH, INSTRUCTION_ADD, + INSTRUCTION_SUB, + INSTRUCTION_MUL, + INSTRUCTION_DIV, INSTRUCTION_DUPLICATE, + INSTRUCTION_POP, + + // instruction pointer operations + INSTRUCTION_HALT, INSTRUCTION_JUMP, - INSTRUCTION_HALT + INSTRUCTION_JUMP_CONDITIONAL, + + // conditional operations + INSTRUCTION_NOT_EQUAL, + INSTRUCTION_NOT_EQUAL_TOP, + INSTRUCTION_EQUAL, + INSTRUCTION_EQUAL_TOP, + INSTRUCTION_LESS_THAN, + INSTRUCTION_LESS_THAN_TOP, + INSTRUCTION_LESS_THAN_EQUAL, + INSTRUCTION_LESS_THAN_EQUAL_TOP, + INSTRUCTION_GREATER_THAN, + INSTRUCTION_GREATER_THAN_TOP, + INSTRUCTION_GREATER_THAN_EQUAL, + INSTRUCTION_GREATER_THAN_EQUAL_TOP, } InstructionType; typedef struct { InstructionType type; - Word opperand; + Word opperands[3]; } VMBL_Instruction; typedef struct @@ -39,11 +61,15 @@ typedef struct bool halted; } VMBL_State; -#define MAKE_INST_PUSH(value) (VMBL_Instruction) { .type = INSTRUCTION_PUSH, .opperand = (value) } -#define MAKE_INST_ADD (VMBL_Instruction) { .type = INSTRUCTION_ADD, } -#define MAKE_INST_DUP(value) (VMBL_Instruction) { .type = INSTRUCTION_DUPLICATE, .opperand = (value) } -#define MAKE_INST_JMP(value) (VMBL_Instruction) { .type = INSTRUCTION_JUMP , .opperand = (value) } -#define MAKE_INST_HALT (VMBL_Instruction) { .type = INSTRUCTION_HALT } +#define MAKE_INST_PUSH(value) (VMBL_Instruction) { .type = INSTRUCTION_PUSH, .opperands[0] = (value) } +#define MAKE_INST_POP (VMBL_Instruction) { .type = INSTRUCTION_POP, } +#define MAKE_INST_ADD (VMBL_Instruction) { .type = INSTRUCTION_ADD } +#define MAKE_INST_DUP(value) (VMBL_Instruction) { .type = INSTRUCTION_DUPLICATE, .opperands[0] = (value) } +#define MAKE_INST_JMP(value) (VMBL_Instruction) { .type = INSTRUCTION_JUMP , .opperands[0] = (value) } +#define MAKE_INST_HALT (VMBL_Instruction) { .type = INSTRUCTION_HALT } +#define MAKE_INST_EQUAL(stack1, stack2) (VMBL_Instruction) { .type = INSTRUCTION_EQUAL, .opperands[0] = (stack1), .opperands[1] = (stack2) } +#define MAKE_INST_EQUAL_TOP (VMBL_Instruction) { .type = INSTRUCTION_EQUAL_TOP } +#define MAKE_INST_JUMP_CONDITIONAL(value) (VMBL_Instruction) { .type = INSTRUCTION_JUMP_CONDITIONAL, .opperands[0] = (value) } VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction instruction); void VMBL_Dump(VMBL_State vmblState, VMBL_Exception exception);