From bd0795256941511f7cca10dc2f47979362055b95 Mon Sep 17 00:00:00 2001 From: SpookyDervish <78246495+SpookyDervish@users.noreply.github.com> Date: Fri, 26 Dec 2025 18:56:51 +1100 Subject: [PATCH] make file added --- Makefile | 24 ++++ README.md | 2 +- sasm | Bin 16848 -> 0 bytes src/exception.c | 39 ------ src/exception.h | 21 --- src/main.c | 23 ---- src/sylt/lexer.c | 128 +++++++++++++---- src/sylt/lexer.h | 2 +- src/sylt/main.c | 12 +- src/sylt/token.h | 26 ++-- src/utils/ansii.h | 67 +++++++++ src/{ => utils}/file_utils.c | 0 src/{ => utils}/file_utils.h | 0 src/vmbl.c | 260 ----------------------------------- src/vmbl.h | 87 ------------ sylt | Bin 16744 -> 0 bytes vmbl | Bin 21592 -> 0 bytes 17 files changed, 217 insertions(+), 474 deletions(-) create mode 100644 Makefile delete mode 100644 sasm delete mode 100644 src/exception.c delete mode 100644 src/exception.h delete mode 100644 src/main.c create mode 100644 src/utils/ansii.h rename src/{ => utils}/file_utils.c (100%) rename src/{ => utils}/file_utils.h (100%) delete mode 100644 src/vmbl.c delete mode 100644 src/vmbl.h delete mode 100644 sylt delete mode 100644 vmbl diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1b33e0f --- /dev/null +++ b/Makefile @@ -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) \ No newline at end of file diff --git a/README.md b/README.md index 5965386..482594f 100644 --- a/README.md +++ b/README.md @@ -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. 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. diff --git a/sasm b/sasm deleted file mode 100644 index 6426bcd1ecf8db8b4fca46fcaca7ccb67e62768e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16848 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 diff --git a/src/exception.c b/src/exception.c deleted file mode 100644 index a30d0f5..0000000 --- a/src/exception.c +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/src/exception.h b/src/exception.h deleted file mode 100644 index 3d979ec..0000000 --- a/src/exception.h +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 2be0106..0000000 --- a/src/main.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "vmbl.h" -#include - -#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; -} \ No newline at end of file diff --git a/src/sylt/lexer.c b/src/sylt/lexer.c index 84a7c09..5553cdb 100644 --- a/src/sylt/lexer.c +++ b/src/sylt/lexer.c @@ -1,7 +1,9 @@ #include "lexer.h" +#include "exception.h" #include +#include #include -#include +#include Lexer initLexer(char *source) { Lexer newLexer = { @@ -11,6 +13,7 @@ Lexer initLexer(char *source) { .lineNumber = 1, .currentChar = '\0' }; + readChar(&newLexer); return newLexer; } @@ -25,63 +28,134 @@ void readChar(Lexer *lexer) { } void skipWhitespace(Lexer *lexer) { - switch (lexer->currentChar) - { - case ' ': - case '\t': - case '\n': - case '\r': - if (lexer->currentChar == '\n') - lexer->lineNumber++; + bool whitespace = true; - readChar(lexer); - break; - - default: - break; + while (whitespace) + { + switch (lexer->currentChar) + { + case ' ': + case '\t': + case '\n': + case '\r': + if (lexer->currentChar == '\n') + lexer->lineNumber++; + + readChar(lexer); + break; + + default: + 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 tok; + Token tok; skipWhitespace(lexer); switch (lexer->currentChar) { case '+': - return NEW_TOKEN(lexer, PLUS, "+"); + tok = NEW_TOKEN(lexer, TOKEN_PLUS, "+"); break; case '-': - return NEW_TOKEN(lexer, MINUS, "-"); + tok = NEW_TOKEN(lexer, TOKEN_MINUS, "-"); break; case '*': - return NEW_TOKEN(lexer, ASTERISK, "*"); + tok = NEW_TOKEN(lexer, TOKEN_ASTERISK, "*"); break; case '/': - return NEW_TOKEN(lexer, SLASH, "/"); + tok = NEW_TOKEN(lexer, TOKEN_SLASH, "/"); break; case '%': - return NEW_TOKEN(lexer, MODULUS, "%"); + tok = NEW_TOKEN(lexer, TOKEN_MODULUS, "%"); break; case '^': - return NEW_TOKEN(lexer, POW, "^"); + tok = NEW_TOKEN(lexer, TOKEN_POW, "^"); break; case '(': - return NEW_TOKEN(lexer, LPAREN, "("); + tok = NEW_TOKEN(lexer, TOKEN_LPAREN, "("); break; case ')': - return NEW_TOKEN(lexer, RPAREN, ")"); + tok = NEW_TOKEN(lexer, TOKEN_RPAREN, ")"); break; - case '\0': - return NEW_TOKEN(lexer, EOF, ""); + + case '\0': // EOF + tok = NEW_TOKEN(lexer, TOKEN_EOF, "EOF"); break; default: - if (isdigit()) + if (isdigit(lexer->currentChar)) { + tok = readNumber(lexer); + } else { + tok = NEW_TOKEN(lexer, TOKEN_ILLEGAL, &lexer->currentChar); + } break; } - //return tok; + readChar(lexer); + return tok; } \ No newline at end of file diff --git a/src/sylt/lexer.h b/src/sylt/lexer.h index e7e986d..970f3da 100644 --- a/src/sylt/lexer.h +++ b/src/sylt/lexer.h @@ -17,6 +17,6 @@ Lexer initLexer(char *source); void readChar(Lexer *lexer); void skipWhitespace(Lexer *lexer); Token nextToken(Lexer *lexer); -char *tokenToCStr(Token token); +Token readNumber(Lexer *lexer); #endif // !LEXER_H diff --git a/src/sylt/main.c b/src/sylt/main.c index 0a76d32..267e316 100644 --- a/src/sylt/main.c +++ b/src/sylt/main.c @@ -1,10 +1,16 @@ #include "lexer.h" #include -#include "../file_utils.h" +#include "../utils/file_utils.h" +#include "../utils/ansii.h" int main() { - Lexer lexer = initLexer("const x, y = 1, 3\n"); - printf(nextToken(&lexer).literal); + Lexer lexer = initLexer("123 456.789 + - * / % ^ ()"); + + while (lexer.currentChar != 0) + { + Token next = nextToken(&lexer); + printf("%s: %s\n", tokenTypeToCString(next.type), next.literal); + } return 0; } \ No newline at end of file diff --git a/src/sylt/token.h b/src/sylt/token.h index 85e7cd5..8571835 100644 --- a/src/sylt/token.h +++ b/src/sylt/token.h @@ -3,24 +3,24 @@ typedef enum { // Special Tokens - EOF, - ILLEGAL, + TOKEN_EOF, + TOKEN_ILLEGAL, // Data Types - INT, - FLOAT, + TOKEN_INT, + TOKEN_FLOAT, // Arithmetic Symbols - PLUS, - MINUS, - ASTERISK, - SLASH, - POW, - MODULUS, + TOKEN_PLUS, + TOKEN_MINUS, + TOKEN_ASTERISK, + TOKEN_SLASH, + TOKEN_POW, + TOKEN_MODULUS, // Symbols - LPAREN, - RPAREN + TOKEN_LPAREN, + TOKEN_RPAREN } TokenType; 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) } +char *tokenTypeToCString(TokenType type); + #endif // !TOKEN_H \ No newline at end of file diff --git a/src/utils/ansii.h b/src/utils/ansii.h new file mode 100644 index 0000000..aaa4f84 --- /dev/null +++ b/src/utils/ansii.h @@ -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 \ No newline at end of file diff --git a/src/file_utils.c b/src/utils/file_utils.c similarity index 100% rename from src/file_utils.c rename to src/utils/file_utils.c diff --git a/src/file_utils.h b/src/utils/file_utils.h similarity index 100% rename from src/file_utils.h rename to src/utils/file_utils.h diff --git a/src/vmbl.c b/src/vmbl.c deleted file mode 100644 index c7fe64b..0000000 --- a/src/vmbl.c +++ /dev/null @@ -1,260 +0,0 @@ -#include "vmbl.h" -#include "file_utils.h" -#include -#include -#include - - -#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; - } -} \ No newline at end of file diff --git a/src/vmbl.h b/src/vmbl.h deleted file mode 100644 index 445b2a2..0000000 --- a/src/vmbl.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef VMBL_H -#define VMBL_H - -#include -#include -#include -#include -#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 diff --git a/sylt b/sylt deleted file mode 100644 index 71c2ca543427de9eb8a043f3e65b62e87a0dbd1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16744 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 diff --git a/vmbl b/vmbl deleted file mode 100644 index e1a9164ee0303a24c498ad9f874a0953cb4bb276..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21592 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