start of conditionals
This commit is contained in:
@@ -9,14 +9,16 @@ VMBL_Instruction program[] = {
|
|||||||
MAKE_INST_DUP(1),
|
MAKE_INST_DUP(1),
|
||||||
MAKE_INST_DUP(1),
|
MAKE_INST_DUP(1),
|
||||||
MAKE_INST_ADD,
|
MAKE_INST_ADD,
|
||||||
MAKE_INST_JMP(2)
|
|
||||||
|
MAKE_INST_JMP(2),
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
VMBL_State vmblState = {};
|
VMBL_State vmblState = {};
|
||||||
|
|
||||||
VMBL_LoadExecutable(&vmblState, program, sizeof(program));
|
VMBL_LoadExecutable(&vmblState, program, sizeof(program));
|
||||||
//VMBL_SaveExecutable("fib.vmbl", program, sizeof(program));
|
VMBL_SaveExecutable("fib.vmbl", program, sizeof(program));
|
||||||
//VMBL_LoadExecutableFromFile(&vmblState, "fib.vmbl");
|
VMBL_LoadExecutableFromFile(&vmblState, "fib.vmbl");
|
||||||
VMBL_StartVM(&vmblState);
|
VMBL_StartVM(&vmblState);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
94
src/vmbl.c
94
src/vmbl.c
@@ -11,7 +11,7 @@ VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction i
|
|||||||
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
|
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
|
||||||
}
|
}
|
||||||
|
|
||||||
vmblState->stack[vmblState->stackSize++] = instruction.opperand;
|
vmblState->stack[vmblState->stackSize++] = instruction.opperands[0];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INSTRUCTION_ADD:
|
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->stack[vmblState->stackSize - 2] += vmblState->stack[vmblState->stackSize - 1];
|
||||||
vmblState->stackSize--;
|
vmblState->stackSize--;
|
||||||
break;
|
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:
|
case INSTRUCTION_DUPLICATE:
|
||||||
if (vmblState->stackSize - instruction.opperand <= 0) {
|
if (vmblState->stackSize - instruction.opperands[0] <= 0) {
|
||||||
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
|
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 };
|
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instruction.opperand < 0) {
|
if (instruction.opperands[0] < 0) {
|
||||||
return (VMBL_Exception) { EXCEPTION_INVALID_OPPERAND };
|
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;
|
break;
|
||||||
|
|
||||||
case INSTRUCTION_JUMP:
|
case INSTRUCTION_JUMP:
|
||||||
|
|
||||||
vmblState->ip = instruction.opperand;
|
vmblState->ip = instruction.opperands[0];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -50,6 +74,44 @@ VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction i
|
|||||||
vmblState->halted = true;
|
vmblState->halted = true;
|
||||||
break;
|
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:
|
default:
|
||||||
return (VMBL_Exception) { EXCEPTION_INVALID_OPCODE };
|
return (VMBL_Exception) { EXCEPTION_INVALID_OPCODE };
|
||||||
break;
|
break;
|
||||||
@@ -64,7 +126,7 @@ void VMBL_Dump(VMBL_State vmblState, VMBL_Exception exception) {
|
|||||||
|
|
||||||
if (vmblState.stackSize > 0) {
|
if (vmblState.stackSize > 0) {
|
||||||
for (size_t i = 0; i < vmblState.stackSize; i++) {
|
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 {
|
} else {
|
||||||
fprintf(stderr, " [empty]\n");
|
fprintf(stderr, " [empty]\n");
|
||||||
@@ -83,12 +145,12 @@ void VMBL_StartVM(VMBL_State *vmblState) {
|
|||||||
|
|
||||||
|
|
||||||
VMBL_Instruction instruction = vmblState->program[vmblState->ip++];
|
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);
|
VMBL_Exception exception = VBML_ExecuteInstruction(vmblState, instruction);
|
||||||
|
|
||||||
if (exception.type != EXCEPTION_NONE) {
|
if (exception.type != EXCEPTION_NONE) {
|
||||||
VMBL_Dump(*vmblState, exception);
|
//VMBL_Dump(*vmblState, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +170,7 @@ void VMBL_LoadExecutable(VMBL_State *vmblState, VMBL_Instruction *program, size_
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(vmblState->program, program, sizeof(program[0]) * programSize);
|
memcpy(&vmblState->program, program, sizeof(program) * programSize);
|
||||||
|
|
||||||
vmblState->programSize = programSize;
|
vmblState->programSize = programSize;
|
||||||
}
|
}
|
||||||
@@ -143,7 +205,7 @@ void VMBL_SaveExecutable(const char* filePath, VMBL_Instruction *program, size_t
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(program, sizeof(program[0]), programSize, file);
|
fwrite(program, sizeof(program), programSize, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,6 +232,18 @@ char *instructionTypeToCStr(InstructionType type) {
|
|||||||
case INSTRUCTION_HALT:
|
case INSTRUCTION_HALT:
|
||||||
return "HALT";
|
return "HALT";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case INSTRUCTION_EQUAL:
|
||||||
|
return "EQ ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INSTRUCTION_EQUAL_TOP:
|
||||||
|
return "EQT ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INSTRUCTION_JUMP_CONDITIONAL:
|
||||||
|
return "JC ";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "??? ";
|
return "??? ";
|
||||||
|
|||||||
44
src/vmbl.h
44
src/vmbl.h
@@ -7,24 +7,46 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
|
||||||
#define VMBL_STACK_SIZE 1024
|
#define VMBL_STACK_SIZE 0x5E
|
||||||
#define VMBL_PROGRAM_SIZE 1024
|
#define VMBL_PROGRAM_SIZE 512
|
||||||
|
|
||||||
typedef int64_t Word;
|
typedef int64_t Word;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
// stack operations
|
||||||
INSTRUCTION_PUSH,
|
INSTRUCTION_PUSH,
|
||||||
INSTRUCTION_ADD,
|
INSTRUCTION_ADD,
|
||||||
|
INSTRUCTION_SUB,
|
||||||
|
INSTRUCTION_MUL,
|
||||||
|
INSTRUCTION_DIV,
|
||||||
INSTRUCTION_DUPLICATE,
|
INSTRUCTION_DUPLICATE,
|
||||||
|
INSTRUCTION_POP,
|
||||||
|
|
||||||
|
// instruction pointer operations
|
||||||
|
INSTRUCTION_HALT,
|
||||||
INSTRUCTION_JUMP,
|
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;
|
} InstructionType;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
InstructionType type;
|
InstructionType type;
|
||||||
Word opperand;
|
Word opperands[3];
|
||||||
} VMBL_Instruction;
|
} VMBL_Instruction;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -39,11 +61,15 @@ typedef struct
|
|||||||
bool halted;
|
bool halted;
|
||||||
} VMBL_State;
|
} VMBL_State;
|
||||||
|
|
||||||
#define MAKE_INST_PUSH(value) (VMBL_Instruction) { .type = INSTRUCTION_PUSH, .opperand = (value) }
|
#define MAKE_INST_PUSH(value) (VMBL_Instruction) { .type = INSTRUCTION_PUSH, .opperands[0] = (value) }
|
||||||
#define MAKE_INST_ADD (VMBL_Instruction) { .type = INSTRUCTION_ADD, }
|
#define MAKE_INST_POP (VMBL_Instruction) { .type = INSTRUCTION_POP, }
|
||||||
#define MAKE_INST_DUP(value) (VMBL_Instruction) { .type = INSTRUCTION_DUPLICATE, .opperand = (value) }
|
#define MAKE_INST_ADD (VMBL_Instruction) { .type = INSTRUCTION_ADD }
|
||||||
#define MAKE_INST_JMP(value) (VMBL_Instruction) { .type = INSTRUCTION_JUMP , .opperand = (value) }
|
#define MAKE_INST_DUP(value) (VMBL_Instruction) { .type = INSTRUCTION_DUPLICATE, .opperands[0] = (value) }
|
||||||
#define MAKE_INST_HALT (VMBL_Instruction) { .type = INSTRUCTION_HALT }
|
#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);
|
VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction instruction);
|
||||||
void VMBL_Dump(VMBL_State vmblState, VMBL_Exception exception);
|
void VMBL_Dump(VMBL_State vmblState, VMBL_Exception exception);
|
||||||
|
|||||||
Reference in New Issue
Block a user