Compare commits

..

3 Commits

Author SHA1 Message Date
SpookyDervish
9da2bb5404 ast 2025-12-27 10:17:56 +11:00
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
25 changed files with 392 additions and 105 deletions

54
.gitignore vendored
View File

@@ -1,54 +0,0 @@
# ---> C
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

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.
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.

BIN
sasm

Binary file not shown.

1
src/sylt/ast.c Normal file
View File

@@ -0,0 +1 @@
#include "ast.h"

65
src/sylt/ast.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef AST_H
#define AST_H
#include <stdlib.h>
typedef enum {
NODE_PROGRAM,
// Statements
NODE_EXPRESSION_STATEMENT,
// Expressions
NODE_INFIX_EXPRESSION,
// Literals
NODE_INT_LITERAL,
NODE_FLOAT_LITERAL
} AST_Type;
typedef struct AST AST;
struct AST
{
AST_Type type;
char *(*to_json)(AST *node);
};
typedef struct
{
AST base;
AST **statements;
size_t statementCount;
} Program;
char *programToJSON(AST *node);
// statements
typedef struct
{
AST base;
AST *expr;
} ExpressionStatement;
char *expressionStatementToJSON(AST *node);
// expressions
typedef struct {
AST base;
AST *left;
char *operator;
AST *right;
} InfixExpression;
char *infixExpressionToJSON(AST *node);
// literals
typedef struct {
AST base;
int value;
} IntegerLiteral;
char *integerLiteralToJSON(AST *node);
typedef struct {
AST base;
double value;
} FloatLiteral;
char *floatLiteralToJSON(AST *node);
#endif // !AST_H

21
src/sylt/exception.c Normal file
View File

@@ -0,0 +1,21 @@
#include "exception.h"
#include <stdio.h>
#include "../utils/ansii.h"
char *exceptionTypeToCString(ExceptionType type) {
switch (type)
{
case EXCEPTION_MALFORMED_NUMBER:
return "MalformedNumberException";
case EXCEPTION_MEMORY_ALLOCATION_FAILURE:
return "MemoryAllocationFailException";
default:
return "UnkownException (fix me please)";
}
}
void exceptionMessage(ExceptionType type, char *message, int lineNumber, int position) {
printf(ESC_RED_FG ESC_BOLD "%s: %s" ESC_RESET "\n", exceptionTypeToCString(type), message);
}

12
src/sylt/exception.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef EXCEPTION_H
#define EXCEPTION_H
typedef enum {
EXCEPTION_MALFORMED_NUMBER,
EXCEPTION_MEMORY_ALLOCATION_FAILURE
} ExceptionType;
char *exceptionTypeToCString(ExceptionType type);
void exceptionMessage(ExceptionType type, char *message, int lineNumber, int position);
#endif // !EXCEPTION_H

View File

@@ -1,7 +1,9 @@
#include "lexer.h"
#include "exception.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio,h>
#include <stdio.h>
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;
}

View File

@@ -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

View File

@@ -1,10 +1,16 @@
#include "lexer.h"
#include <stdio.h>
#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;
}

1
src/sylt/parser.c Normal file
View File

@@ -0,0 +1 @@
#include "parser.h"

28
src/sylt/parser.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef PARSER_H
#define PARSER_H
#include "lexer.h"
#include "ast.h"
typedef enum {
PRECEDENCE_LOWEST = 0,
PRECEDENCE_EQUALS,
PRECEDENCE_LESSGREATER,
PRECEDENCE_SUM,
PRECEDENCE_PRODUCT,
PRECEDENCE_EXPONENT,
PRECEDENCE_PREFIX,
PRECEDENCE_CALL,
PRECEDENCE_INDEX,
} PrecedenceType;
PrecedenceType PRECEDENCES[] = {
[TOKEN_PLUS] = PRECEDENCE_SUM,
[TOKEN_MINUS] = PRECEDENCE_SUM,
[TOKEN_SLASH] = PRECEDENCE_PRODUCT,
[TOKEN_ASTERISK] = PRECEDENCE_PRODUCT,
[TOKEN_MODULUS] = PRECEDENCE_PRODUCT,
[TOKEN_POW] = PRECEDENCE_EXPONENT,
};
#endif // !PARSER_H

45
src/sylt/token.c Normal file
View File

@@ -0,0 +1,45 @@
#include "token.h"
char *tokenTypeToCString(TokenType type) {
switch (type)
{
case TOKEN_EOF:
return "TOKEN_EOF";
case TOKEN_ILLEGAL:
return "TOKEN_ILLEGAL";
case TOKEN_INT:
return "TOKEN_INT";
case TOKEN_FLOAT:
return "TOKEN_FLOAT";
case TOKEN_PLUS:
return "TOKEN_EOF";
case TOKEN_MINUS:
return "TOKEN_MINUS";
case TOKEN_ASTERISK:
return "TOKEN_ASTERISK";
case TOKEN_SLASH:
return "TOKEN_SLASH";
case TOKEN_POW:
return "TOKEN_POW";
case TOKEN_MODULUS:
return "TOKEN_MODULUS";
case TOKEN_LPAREN:
return "TOKEN_LPAREN";
case TOKEN_RPAREN:
return "TOKEN_RPAREN";
default:
return "UNKOWN (fix me please)";
}
}

View File

@@ -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

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

@@ -4,12 +4,7 @@
#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)
MAKE_INST_JMP(0)
};
int main() {

View File

@@ -1,5 +1,5 @@
#include "vmbl.h"
#include "file_utils.h"
#include "../utils/file_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

BIN
sylt

Binary file not shown.

BIN
vmbl

Binary file not shown.