set up
This commit is contained in:
26
src/exception.c
Normal file
26
src/exception.c
Normal 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
18
src/exception.h
Normal 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
24
src/main.c
Normal 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
45
src/vmbl.c
Normal 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
37
src/vmbl.h
Normal 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
|
||||||
Reference in New Issue
Block a user