This commit is contained in:
SpookyDervish
2025-12-19 18:31:41 +11:00
parent 9f58ac9de5
commit f97ef75445
5 changed files with 150 additions and 0 deletions

26
src/exception.c Normal file
View File

@@ -0,0 +1,26 @@
#include "exception.h"
char* exceptionAsCString(VMBL_Exception exception)
{
switch (exception.type)
{
case EXCEPTION_NONE:
return "EXCEPTION_NONE";
break;
case EXCEPTION_STACK_OVERFLOW:
return "EXCEPTION_STACK_OVERFLOW";
break;
case EXCEPTION_STACK_UNDERFLOW:
return "EXCEPTION_STACK_UNDERFLOW";
break;
case EXCEPTION_INVALID_OPCODE:
return "EXCEPTION_INVALID_OPCODE";
break;
default:
break;
}
}

18
src/exception.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef EXCEPTION_H
#define EXCEPTION_H
typedef enum {
EXCEPTION_NONE,
EXCEPTION_STACK_OVERFLOW,
EXCEPTION_STACK_UNDERFLOW,
EXCEPTION_INVALID_OPCODE
} VMBL_ExceptionType;
typedef struct
{
VMBL_ExceptionType type;
} VMBL_Exception;
char* exceptionAsCString(VMBL_Exception exception);
#endif

24
src/main.c Normal file
View File

@@ -0,0 +1,24 @@
#include <stdio.h>
#include "vmbl.h"
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]));
VMBL_Instruction program[] = {
MAKE_INST_PUSH(69),
MAKE_INST_PUSH(420),
MAKE_INST_ADD,
};
int main() {
VMBL_State vmblState = {};
for (size_t i = 0; i < ARRAY_SIZE(program) i++) {
VMBL_Exception exception = VBML_ExecuteInstruction(&vmblState, program[i]);
if (exception.type != EXCEPTION_NONE) {
VMBL_Dump(vmblState, exception);
return 1;
}
}
return 0;
}

45
src/vmbl.c Normal file
View File

@@ -0,0 +1,45 @@
#include "vmbl.h"
#include <stdio.h>
VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction instruction) {
switch (instruction.type)
{
case INSTRUCTION_PUSH:
if (vmblState->stackSize >= VMBL_STACK_SIZE) {
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
}
vmblState->stack[vmblState->stackSize++] = instruction.opperand;
break;
case INSTRUCTION_ADD:
if (vmblState->stackSize < 2) {
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
}
vmblState->stack[vmblState->stackSize - 2] += vmblState->stack[vmblState->stackSize - 1];
vmblState->stackSize--;
break;
default:
return (VMBL_Exception) { EXCEPTION_INVALID_OPCODE };
break;
}
return (VMBL_Exception) { EXCEPTION_NONE };
}
void VMBL_Dump(VMBL_State vmblState, VMBL_Exception exception) {
fprintf(stderr, "EXCEPTION: %s\n\n", exceptionAsCString(exception));
fprintf(stderr, "Stack:\n");
if (vmblState.stackSize > 0) {
for (size_t i = 0; i < vmblState.stackSize; i++) {
fprintf(stderr, " 0x%lX: %ld\n", i, vmblState.stack[i]);
}
} else {
fprintf(stderr, " [empty]\n");
}
}

37
src/vmbl.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef VMBL_H
#define VMBL_H
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include "exception.h"
#define VMBL_STACK_SIZE 1024
typedef int64_t Word;
typedef enum
{
INSTRUCTION_PUSH,
INSTRUCTION_ADD
} InstructionType;
typedef struct
{
Word stack[VMBL_STACK_SIZE];
size_t stackSize;
} VMBL_State;
typedef struct
{
InstructionType type;
Word opperand;
} VMBL_Instruction;
#define MAKE_INST_PUSH(value) (VMBL_Instruction) { .type = INSTRUCTION_PUSH, .opperand = (value) }
#define MAKE_INST_ADD (VMBL_Instruction) { .type = INSTRUCTION_ADD }
VMBL_Exception VBML_ExecuteInstruction(VMBL_State *vmblState, VMBL_Instruction instruction);
void VMBL_Dump(VMBL_State vmblState, VMBL_Exception exception);
#endif // !VMBL_H