Compare commits

...

2 Commits

Author SHA1 Message Date
SpookyDervish
bd07952569 make file added 2025-12-26 18:56:51 +11:00
SpookyDervish
b69a6c6eec makefile added 2025-12-26 18:56:47 +11:00
18 changed files with 220 additions and 474 deletions

3
.gitignore vendored
View File

@@ -52,3 +52,6 @@ Module.symvers
Mkfile.old Mkfile.old
dkms.conf dkms.conf
sasm
sylt
vmbl

24
Makefile Normal file
View File

@@ -0,0 +1,24 @@
CC=gcc
CFLAGS=-O3 -Wall
SRC=src
BIN=bin
VMBL_FILES=$(wildcard $(SRC)/vmbl/*.c)
SYLT_FILES=$(wildcard $(SRC)/sylt/*.c)
UTIL_FILES=$(wildcard $(SRC)/utils/*.c)
all: vmbl sylt
$(BIN)/vmbl: $(VMBL_FILES)
mkdir -p $(BIN)
$(CC) $(CFLAGS) $(UTIL_FILES) $(VMBL_FILES) -o $(BIN)/vmbl
vmbl: $(BIN)/vmbl
$(BIN)/sylt: $(SYLT_FILES)
mkdir -p $(BIN)
$(CC) $(CFLAGS) $(UTIL_FILES) $(SYLT_FILES) -o $(BIN)/sylt
sylt: $(BIN)/sylt
clean:
rm -r $(BIN)

View File

@@ -9,7 +9,7 @@
But uhh that's the name of the VM itself, the name of the programming language I made is Sylt, named after the German island. But uhh that's the name of the VM itself, the name of the programming language I made is Sylt, named after the German island.
To compile the VM for Linux: `gcc src/main.c src/vmbl.c src/exception.c src/file_utils.c -o vmbl -O3` To compile the VM for Linux: `gcc src/main.c src/vmbl.c src/exception.c src/file_utils.c -o vmbl -O3`
To compile the SYLT compiler for Linux: `gcc src/sylt/main.c src/file_utils.c src/sylt/lexer.c -o sylt -O3` To compile the SYLT compiler for Linux: `gcc src/sylt/main.c src/sylt/exception.c src/sylt/token.c src/file_utils.c src/sylt/lexer.c -o sylt -O3`
SASM and Sylt are written in Python for now as I'm too mentally challenged to write C code rn. SASM and Sylt are written in Python for now as I'm too mentally challenged to write C code rn.

BIN
sasm

Binary file not shown.

View File

@@ -1,39 +0,0 @@
#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;
case EXCEPTION_INVALID_OPPERAND:
return "EXCEPTION_INVALID_OPPERAND";
break;
case EXCEPTION_INVALID_INSTRUCTION_ACCESS:
return "EXCEPTION_INVALID_INSTRUCTION_ACCESS";
break;
case EXCEPTION_DIVIDE_BY_ZERO:
return "EXCEPTION_DIVIDE_BY_ZERO";
break;
default:
return "EXCEPTION_UNKOWN";
break;
}
}

View File

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

View File

@@ -1,23 +0,0 @@
#include "vmbl.h"
#include <stdio.h>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]));
VMBL_Instruction program[] = {
MAKE_INST_PUSH(0),
MAKE_INST_PUSH(1),
MAKE_INST_DUP(1),
MAKE_INST_DUP(1),
MAKE_INST_ADD,
MAKE_INST_JMP(2)
};
int main() {
VMBL_State vmblState = {};
VMBL_LoadExecutable(&vmblState, program, sizeof(program));
VMBL_SaveExecutable("fib.vmbl", program, sizeof(program));
VMBL_StartVM(&vmblState);
return 0;
}

View File

@@ -1,7 +1,9 @@
#include "lexer.h" #include "lexer.h"
#include "exception.h"
#include <string.h> #include <string.h>
#include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio,h> #include <stdio.h>
Lexer initLexer(char *source) { Lexer initLexer(char *source) {
Lexer newLexer = { Lexer newLexer = {
@@ -11,6 +13,7 @@ Lexer initLexer(char *source) {
.lineNumber = 1, .lineNumber = 1,
.currentChar = '\0' .currentChar = '\0'
}; };
readChar(&newLexer);
return newLexer; return newLexer;
} }
@@ -25,63 +28,134 @@ void readChar(Lexer *lexer) {
} }
void skipWhitespace(Lexer *lexer) { void skipWhitespace(Lexer *lexer) {
switch (lexer->currentChar) bool whitespace = true;
while (whitespace)
{ {
case ' ': switch (lexer->currentChar)
case '\t': {
case '\n': case ' ':
case '\r': case '\t':
if (lexer->currentChar == '\n') case '\n':
lexer->lineNumber++; case '\r':
if (lexer->currentChar == '\n')
lexer->lineNumber++;
readChar(lexer); readChar(lexer);
break; break;
default: default:
break; whitespace = false;
break;
}
} }
}
Token readNumber(Lexer *lexer) {
int startPos = lexer->position;
int dotCount = 0;
int strLength = 0;
size_t outputCap = 8;
char *output = malloc(outputCap);
if (!output) {
exceptionMessage(EXCEPTION_MEMORY_ALLOCATION_FAILURE, "Lexer failed to allocate memory.", lexer->lineNumber, lexer->position);
exit(1);
}
while (isdigit(lexer->currentChar) || lexer->currentChar == '.')
{
if (lexer->currentChar == '.') {
dotCount++;
if (dotCount > 1) {
exceptionMessage(EXCEPTION_MALFORMED_NUMBER, "Too many dots in decimal.", lexer->lineNumber, lexer->position);
char buffer[strLength+1];
strncpy(buffer, lexer->source + startPos, strLength+1);
buffer[strLength+1] = 0;
return NEW_TOKEN(lexer, TOKEN_ILLEGAL, buffer);
}
}
// allocate more memory if we reach the end of our buffer
if (strLength + 1 >= outputCap) {
char *temp = realloc(output, outputCap*=2);
if (!temp) {
exceptionMessage(EXCEPTION_MEMORY_ALLOCATION_FAILURE, "Lexer failed to allocate memory.", lexer->lineNumber, lexer->position);
exit(1);
}
output = temp;
}
output[strLength] = lexer->source[lexer->position];
strLength++;
readChar(lexer);
if (lexer->currentChar == '\0')
break;
}
output[strLength] = 0;
if (dotCount == 0)
return NEW_TOKEN(lexer, TOKEN_INT, output);
else
return NEW_TOKEN(lexer, TOKEN_FLOAT, output);
} }
Token nextToken(Lexer *lexer) { Token nextToken(Lexer *lexer) {
//Token tok; Token tok;
skipWhitespace(lexer); skipWhitespace(lexer);
switch (lexer->currentChar) switch (lexer->currentChar)
{ {
case '+': case '+':
return NEW_TOKEN(lexer, PLUS, "+"); tok = NEW_TOKEN(lexer, TOKEN_PLUS, "+");
break; break;
case '-': case '-':
return NEW_TOKEN(lexer, MINUS, "-"); tok = NEW_TOKEN(lexer, TOKEN_MINUS, "-");
break; break;
case '*': case '*':
return NEW_TOKEN(lexer, ASTERISK, "*"); tok = NEW_TOKEN(lexer, TOKEN_ASTERISK, "*");
break; break;
case '/': case '/':
return NEW_TOKEN(lexer, SLASH, "/"); tok = NEW_TOKEN(lexer, TOKEN_SLASH, "/");
break; break;
case '%': case '%':
return NEW_TOKEN(lexer, MODULUS, "%"); tok = NEW_TOKEN(lexer, TOKEN_MODULUS, "%");
break; break;
case '^': case '^':
return NEW_TOKEN(lexer, POW, "^"); tok = NEW_TOKEN(lexer, TOKEN_POW, "^");
break; break;
case '(': case '(':
return NEW_TOKEN(lexer, LPAREN, "("); tok = NEW_TOKEN(lexer, TOKEN_LPAREN, "(");
break; break;
case ')': case ')':
return NEW_TOKEN(lexer, RPAREN, ")"); tok = NEW_TOKEN(lexer, TOKEN_RPAREN, ")");
break; break;
case '\0':
return NEW_TOKEN(lexer, EOF, ""); case '\0': // EOF
tok = NEW_TOKEN(lexer, TOKEN_EOF, "EOF");
break; break;
default: default:
if (isdigit()) if (isdigit(lexer->currentChar)) {
tok = readNumber(lexer);
} else {
tok = NEW_TOKEN(lexer, TOKEN_ILLEGAL, &lexer->currentChar);
}
break; break;
} }
//return tok; readChar(lexer);
return tok;
} }

View File

@@ -17,6 +17,6 @@ Lexer initLexer(char *source);
void readChar(Lexer *lexer); void readChar(Lexer *lexer);
void skipWhitespace(Lexer *lexer); void skipWhitespace(Lexer *lexer);
Token nextToken(Lexer *lexer); Token nextToken(Lexer *lexer);
char *tokenToCStr(Token token); Token readNumber(Lexer *lexer);
#endif // !LEXER_H #endif // !LEXER_H

View File

@@ -1,10 +1,16 @@
#include "lexer.h" #include "lexer.h"
#include <stdio.h> #include <stdio.h>
#include "../file_utils.h" #include "../utils/file_utils.h"
#include "../utils/ansii.h"
int main() { int main() {
Lexer lexer = initLexer("const x, y = 1, 3\n"); Lexer lexer = initLexer("123 456.789 + - * / % ^ ()");
printf(nextToken(&lexer).literal);
while (lexer.currentChar != 0)
{
Token next = nextToken(&lexer);
printf("%s: %s\n", tokenTypeToCString(next.type), next.literal);
}
return 0; return 0;
} }

View File

@@ -3,24 +3,24 @@
typedef enum { typedef enum {
// Special Tokens // Special Tokens
EOF, TOKEN_EOF,
ILLEGAL, TOKEN_ILLEGAL,
// Data Types // Data Types
INT, TOKEN_INT,
FLOAT, TOKEN_FLOAT,
// Arithmetic Symbols // Arithmetic Symbols
PLUS, TOKEN_PLUS,
MINUS, TOKEN_MINUS,
ASTERISK, TOKEN_ASTERISK,
SLASH, TOKEN_SLASH,
POW, TOKEN_POW,
MODULUS, TOKEN_MODULUS,
// Symbols // Symbols
LPAREN, TOKEN_LPAREN,
RPAREN TOKEN_RPAREN
} TokenType; } TokenType;
typedef struct typedef struct
@@ -33,4 +33,6 @@ typedef struct
#define NEW_TOKEN(lexer, tokType, tokLiteral) (Token){ .type = (tokType), .literal = (tokLiteral), .lineNumber = (lexer->lineNumber), .position = (lexer->position) } #define NEW_TOKEN(lexer, tokType, tokLiteral) (Token){ .type = (tokType), .literal = (tokLiteral), .lineNumber = (lexer->lineNumber), .position = (lexer->position) }
char *tokenTypeToCString(TokenType type);
#endif // !TOKEN_H #endif // !TOKEN_H

67
src/utils/ansii.h Normal file
View File

@@ -0,0 +1,67 @@
// ansii.h - made by SpookyDervish
// version 1.0.0
// do with this whatever you want
//
// example usage with printf: printf(ESC_BOLD ESC_RED_FG "hi\n");
#ifndef ANSII_H
#define ANSII_H
#define ESC_RESET "\x1b[0m"
#define ESC_BOLD "\x1b[1m"
#define ESC_DIM "\x1b[2m"
#define ESC_ITALIC "\x1b[3m"
#define ESC_UNDERLINE "\x1b[4m"
#define ESC_BLINKING "\x1b[5m"
#define ESC_REVERSE "\x1b[7m"
#define ESC_HIDDEN "\x1b[8m"
#define ESC_STRIKETHROUGH "\x1b[8m"
#define ESC_TERMINAL_BELL "\a"
#define ESC_BLACK_FG "\x1b[30m"
#define ESC_RED_FG "\x1b[31m"
#define ESC_GREEN_FG "\x1b[32m"
#define ESC_YELLOW_FG "\x1b[33m"
#define ESC_BLUE_FG "\x1b[34m"
#define ESC_MAGENTA_FG "\x1b[35m"
#define ESC_CYAN_FG "\x1b[36m"
#define ESC_WHITE_FG "\x1b[37m"
#define ESC_BLACK_FG "\x1b[30m"
#define ESC_RED_FG "\x1b[31m"
#define ESC_GREEN_FG "\x1b[32m"
#define ESC_YELLOW_FG "\x1b[33m"
#define ESC_BLUE_FG "\x1b[34m"
#define ESC_MAGENTA_FG "\x1b[35m"
#define ESC_CYAN_FG "\x1b[36m"
#define ESC_WHITE_FG "\x1b[37m"
#define ESC_BRIGHT_BLACK_FG "\x1b[90m"
#define ESC_BRIGHT_RED_FG "\x1b[91m"
#define ESC_BRIGHT_GREEN_FG "\x1b[92m"
#define ESC_BRIGHT_YELLOW_FG "\x1b[93m"
#define ESC_BRIGHT_BLUE_FG "\x1b[94m"
#define ESC_BRIGHT_MAGENTA_FG "\x1b[95m"
#define ESC_BRIGHT_CYAN_FG "\x1b[96m"
#define ESC_BRIGHT_WHITE_FG "\x1b[97m"
#define ESC_BLACK_BG "\x1b[40m"
#define ESC_RED_BG "\x1b[41m"
#define ESC_GREEN_BG "\x1b[42m"
#define ESC_YELLOW_BG "\x1b[43m"
#define ESC_BLUE_BG "\x1b[44m"
#define ESC_MAGENTA_BG "\x1b[45m"
#define ESC_CYAN_BG "\x1b[46m"
#define ESC_WHITE_BG "\x1b[47m"
#define ESC_BRIGHT_BLACK_BG "\x1b[100m"
#define ESC_BRIGHT_RED_BG "\x1b[101m"
#define ESC_BRIGHT_GREEN_BG "\x1b[102m"
#define ESC_BRIGHT_YELLOW_BG "\x1b[103m"
#define ESC_BRIGHT_BLUE_BG "\x1b[104m"
#define ESC_BRIGHT_MAGENTA_BG "\x1b[105m"
#define ESC_BRIGHT_CYAN_BG "\x1b[106m"
#define ESC_BRIGHT_WHITE_BG "\x1b[107m"
#define ESC_DEFAULT_FG "\x1b[39m"
#endif // !ANSII_H

View File

@@ -1,260 +0,0 @@
#include "vmbl.h"
#include "file_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MATH_OP(vmblState, operation) \
do { \
if ((vmblState)->stackSize < 2) { \
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW }; \
} \
(vmblState)->stack[(vmblState)->stackSize - 2] = (vmblState)->stack[(vmblState)->stackSize - 2] operation (vmblState)->stack[(vmblState)->stackSize - 1]; \
(vmblState)->stackSize--; \
} while (0);
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.opperands[0];
break;
case INSTRUCTION_ADD:
MATH_OP(vmblState, +);
break;
case INSTRUCTION_SUB:
MATH_OP(vmblState, -);
break;
case INSTRUCTION_MUL:
MATH_OP(vmblState, *);
break;
case INSTRUCTION_DIV:
if (vmblState->stack[vmblState->stackSize-1] == 0) {
return (VMBL_Exception){ EXCEPTION_DIVIDE_BY_ZERO };
}
MATH_OP(vmblState, /);
break;
case INSTRUCTION_DUPLICATE:
if (vmblState->stackSize - instruction.opperands[0] <= 0) {
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
}
if (vmblState->stackSize >= VMBL_STACK_SIZE) {
return (VMBL_Exception){ EXCEPTION_STACK_OVERFLOW };
}
if (instruction.opperands[0] < 0) {
return (VMBL_Exception) { EXCEPTION_INVALID_OPPERAND };
}
vmblState->stack[vmblState->stackSize++] = vmblState->stack[vmblState->stackSize - 1 - instruction.opperands[0]];
break;
case INSTRUCTION_JUMP:
vmblState->ip = instruction.opperands[0];
break;
case INSTRUCTION_HALT:
vmblState->halted = true;
break;
case INSTRUCTION_EQUAL:
MATH_OP(vmblState, ==);
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_DROP:
if (vmblState->stackSize <= 0) {
return (VMBL_Exception){ EXCEPTION_STACK_UNDERFLOW };
}
vmblState->stackSize--;
break;
case INSTRUCTION_NOP:
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");
}
}
void VMBL_StartVM(VMBL_State *vmblState) {
for (;;)
{
// fetch next instruction
if (vmblState->ip >= VMBL_PROGRAM_SIZE) {
VMBL_Dump(*vmblState, (VMBL_Exception){ EXCEPTION_INVALID_INSTRUCTION_ACCESS});
return;
}
VMBL_Instruction instruction = vmblState->program[vmblState->ip++];
//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);
return;
}
if (vmblState->halted) {
return;
}
}
}
// executable operations
void VMBL_LoadExecutable(VMBL_State *vmblState, VMBL_Instruction *program, size_t programSize) {
if (programSize > VMBL_PROGRAM_SIZE) {
fprintf(stderr, "VMBL: failed to load program from memory because it is %ld words in size, while the max size is %d.", programSize, VMBL_PROGRAM_SIZE);
exit(1);
}
memcpy(&vmblState->program, program, programSize);
vmblState->programSize = programSize;
}
void VMBL_LoadExecutableFromFile(VMBL_State *vmblState, char* filePath) {
/*FILE *file = fopen(filePath, "rb");
if (file == NULL) {
perror("VMBL: Failed to open file");
exit(1);
}
fseek(file, 0, SEEK_END);
long size = ftell(file);
rewind(file);
size_t programSize = size / sizeof(vmblState->program[0]);
VMBL_Instruction program[programSize];
fread(program, sizeof(program[0]), programSize, file);*/
VMBL_Instruction *program = (VMBL_Instruction*)readStringFromFile(filePath);
VMBL_LoadExecutable(vmblState, program, sizeof(program));
//fclose(file);
}
void VMBL_SaveExecutable(const char* filePath, VMBL_Instruction *program, size_t programSize) {
FILE *file = fopen(filePath, "wb");
if (file == NULL) {
perror("VMBL: Failed to open file");
exit(1);
}
fwrite(program, sizeof(program), programSize, file);
fclose(file);
}
char *instructionTypeToCStr(InstructionType type) {
printf("%x\n", type);
switch (type)
{
case INSTRUCTION_PUSH:
return "PUSH";
break;
case INSTRUCTION_ADD:
return "ADD ";
break;
case INSTRUCTION_SUB:
return "SUB ";
break;
case INSTRUCTION_MUL:
return "MUL ";
break;
case INSTRUCTION_DIV:
return "DIV ";
break;
case INSTRUCTION_DUPLICATE:
return "DUP ";
break;
case INSTRUCTION_JUMP:
return "JMP ";
break;
case INSTRUCTION_HALT:
return "HALT";
break;
case INSTRUCTION_EQUAL:
return "EQ ";
break;
case INSTRUCTION_NOT_EQUAL:
return "NEQ ";
break;
case INSTRUCTION_GREATER_THAN:
return "GT ";
break;
case INSTRUCTION_GREATER_THAN_EQUAL:
return "GTE ";
break;
case INSTRUCTION_LESS_THAN:
return "LT ";
break;
case INSTRUCTION_LESS_THAN_EQUAL:
return "LTE ";
break;
case INSTRUCTION_JUMP_CONDITIONAL:
return "JC ";
break;
default:
return "??? ";
break;
}
}

View File

@@ -1,87 +0,0 @@
#ifndef VMBL_H
#define VMBL_H
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include "exception.h"
#define VMBL_STACK_SIZE 1024
#define VMBL_PROGRAM_SIZE 1024
typedef int64_t Word;
typedef enum
{
INSTRUCTION_NOP,
// stack operations
INSTRUCTION_PUSH,
INSTRUCTION_ADD,
INSTRUCTION_SUB,
INSTRUCTION_MUL,
INSTRUCTION_DIV,
INSTRUCTION_DUPLICATE,
INSTRUCTION_DROP,
// instruction pointer operations
INSTRUCTION_HALT,
INSTRUCTION_JUMP,
INSTRUCTION_JUMP_CONDITIONAL,
// conditional operations
INSTRUCTION_NOT_EQUAL,
INSTRUCTION_EQUAL,
INSTRUCTION_LESS_THAN,
INSTRUCTION_LESS_THAN_EQUAL,
INSTRUCTION_GREATER_THAN,
INSTRUCTION_GREATER_THAN_EQUAL
} InstructionType;
typedef struct
{
InstructionType type;
Word opperands[3];
} VMBL_Instruction;
typedef struct
{
Word stack[VMBL_STACK_SIZE];
size_t stackSize;
VMBL_Instruction program[VMBL_PROGRAM_SIZE];
size_t programSize;
long ip;
bool halted;
} VMBL_State;
#define MAKE_INST_PUSH(value) (VMBL_Instruction) { .type = INSTRUCTION_PUSH, .opperands[0] = (value) }
#define MAKE_INST_DROP (VMBL_Instruction) { .type = INSTRUCTION_POP }
#define MAKE_INST_ADD (VMBL_Instruction) { .type = INSTRUCTION_ADD }
#define MAKE_INST_SUB (VMBL_Instruction) { .type = INSTRUCTION_SUB }
#define MAKE_INST_MUL (VMBL_Instruction) { .type = INSTRUCTION_MUL }
#define MAKE_INST_DIV (VMBL_Instruction) { .type = INSTRUCTION_DIV }
#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 (VMBL_Instruction) { .type = INSTRUCTION_EQUAL }
#define MAKE_INST_NOT_EQUAL (VMBL_Instruction) { .type = INSTRUCTION_NOT_EQUAL }
#define MAKE_INST_LESS (VMBL_Instruction) { .type = INSTRUCTION_LESS_THAN }
#define MAKE_INST_LESS_EQUAL (VMBL_Instruction) { .type = INSTRUCTION_LESS_THAN_EQUAL }
#define MAKE_INST_GREATER (VMBL_Instruction) { .type = INSTRUCTION_GREATER_THAN }
#define MAKE_INST_GREATER_EQUAL (VMBL_Instruction) { .type = INSTRUCTION_GREATER_THAN_EQUAL }
#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);
void VMBL_StartVM(VMBL_State *vmblState);
void VMBL_LoadExecutable(VMBL_State *vmblState, VMBL_Instruction *program, size_t programSize);
void VMBL_LoadExecutableFromFile(VMBL_State *vmblState, char* filePath);
void VMBL_SaveExecutable(const char* filePath, VMBL_Instruction *program, size_t programSize);
char *instructionTypeToCStr(InstructionType type);
#endif // !VMBL_H

BIN
sylt

Binary file not shown.

BIN
vmbl

Binary file not shown.