54 Commits

Author SHA1 Message Date
02ecef4ce2 Add updated Makefile 2026-05-10 14:56:18 +10:00
e0869d526e Start work on inbuilt compiler debugger 2026-05-09 14:07:35 +10:00
cba5ec1fa2 Calling functions in nested objects 2026-05-05 09:12:58 +10:00
908af13d8f I forgot to remove the fixme lmao 2026-05-04 19:29:09 +10:00
10046703ed Nested object setting 2026-05-04 19:28:03 +10:00
ebfd1d5045 Add sizeof test 2026-05-04 11:51:31 +10:00
1e0abcc0b4 sizeof operator 2026-05-04 11:51:07 +10:00
c7bd6e7766 Working generics 2026-04-20 18:43:20 +10:00
68f5868538 use files rel. to current file's directory 2026-04-20 15:16:36 +10:00
692dd6b0db Fix static builds 2026-04-17 13:28:02 +10:00
8087a8150e Static build 2026-04-17 13:25:21 +10:00
53908d29e2 woops, lemme delete that 2026-04-17 12:43:23 +10:00
effad2920f removed conversions lib, use the 'as' from now on 2026-04-17 12:42:24 +10:00
ac13b7a0ae Update highlighting 2026-04-17 12:37:11 +10:00
8b40dbd563 Fix generic constructor issue 2026-04-17 12:27:59 +10:00
0cf63b034f Fix some things, may break others 2026-04-16 17:13:55 +10:00
ba6ec79a10 x as y 2026-04-16 12:59:49 +10:00
f261a1cd0e More generics stuff 2026-04-15 16:57:41 +10:00
00bf654882 IT SORTA WORKS 2026-04-15 11:25:52 +10:00
591adf79a4 More work on generics, still no worky 2026-04-15 11:13:38 +10:00
c7d4a7700e Further work on generics 2026-04-14 17:08:44 +10:00
d0d1dc7465 Parse generic initializations 2026-04-14 12:00:20 +10:00
f8afa2f564 Start work on codegen for generics 2026-04-14 11:32:05 +10:00
7a81a47986 finish parsing generics 2026-04-14 09:35:23 +10:00
f127c2f5ab Add generics example 2026-04-14 09:21:30 +10:00
23041c041a merge 2026-04-14 08:52:30 +10:00
0bb3741c66 "as" in struct 2026-04-14 08:49:57 +10:00
af97f1b712 added strings solstice wrapper 2026-04-13 20:02:14 +10:00
dfe37de5c0 Fix duplicators 2026-04-13 18:27:27 +10:00
5d9cb02e7e Parse and codegen duplicator 2026-04-13 14:02:47 +10:00
547488964a Fix an issue with constructors 2026-04-13 13:12:58 +10:00
f0692eb940 added solstice wrappers for fileio and collections 2026-04-13 12:15:47 +10:00
67ea6cc5fc Enums as return types 2026-04-13 12:06:56 +10:00
36030f01a2 Basic enum 2026-04-13 11:53:20 +10:00
f384e19c06 private and protected fields 2026-04-12 21:16:59 +10:00
d24462f844 Don't evaluate left of '=' 2026-04-12 19:35:56 +10:00
4351821d30 Destructor example 2026-04-11 20:42:14 +10:00
78f974e189 Destructors 2026-04-11 20:41:54 +10:00
1dedb30a87 Constructors 2026-04-11 17:05:20 +10:00
2e7b5b7480 Call methods inside objects 2026-04-11 12:03:10 +10:00
1cf995f7ac Fixes for structs 2026-04-10 19:38:26 +10:00
605d0a87b1 Update highlighting 2026-04-10 19:37:41 +10:00
16569d7355 Struct member writing 2026-04-10 14:57:01 +10:00
fd08b7cdb7 Struct field access (slightly buggy) 2026-04-10 10:14:23 +10:00
5841a7a999 Parse object member access 2026-04-10 10:00:24 +10:00
a2fc138ba1 'new' keyword 2026-04-09 19:00:40 +10:00
9b55b509f5 Fix struct interaction with type system 2026-04-09 17:13:51 +10:00
f694f50d70 Fix struct parsing 2026-04-09 17:13:13 +10:00
5b61a11f00 Codegen for structs 2026-04-09 16:04:53 +10:00
00d6ed83fb Parse structs 2026-04-09 15:39:17 +10:00
6988f314b0 Parse exprs in parens 2026-04-09 11:43:00 +10:00
70dc5eb5a0 Parse expressions in parens (3 + 2) * 4 2026-04-09 10:38:58 +10:00
1e3bd6c601 Division no longer becomes subtraction 2026-04-09 10:17:37 +10:00
f66464a7cc Stuff 2026-04-09 10:01:30 +10:00
26 changed files with 3386 additions and 232 deletions

View File

@@ -1,5 +1,9 @@
CXX = gcc CXX = gcc
CXXFLAGS = -Wall -Wextra -pedantic -O3 -ggdb
GROUND_STATIC = /usr/local/lib/libgroundvm.a
GROUND_INCLUDE = /usr/local/include/
CXXFLAGS = -I$(GROUND_INCLUDE) -Wall -Wextra -pedantic -O3 -ggdb
LDFLAGS = -lgroundvm LDFLAGS = -lgroundvm
BUILD_DIR = build BUILD_DIR = build
@@ -10,7 +14,7 @@ PREFIX ?= /usr/local
BINDIR = $(PREFIX)/bin BINDIR = $(PREFIX)/bin
LIBDIR = /usr/lib LIBDIR = /usr/lib
SRCS = $(SRC_DIR)/main.c $(SRC_DIR)/codegen/SolsScope.c $(SRC_DIR)/codegen/codegen.c $(SRC_DIR)/lexer/SolsLiteral.c $(SRC_DIR)/lexer/SolsToken.c $(SRC_DIR)/lexer/SolsType.c $(SRC_DIR)/lexer/lexer.c $(SRC_DIR)/parser/SolsNode.c $(SRC_DIR)/parser/parser.c $(SRC_DIR)/typeparser/typeparser.c SRCS = $(SRC_DIR)/main.c $(SRC_DIR)/codegen/SolsScope.c $(SRC_DIR)/codegen/codegen.c $(SRC_DIR)/lexer/SolsLiteral.c $(SRC_DIR)/lexer/SolsToken.c $(SRC_DIR)/lexer/SolsType.c $(SRC_DIR)/lexer/lexer.c $(SRC_DIR)/parser/SolsNode.c $(SRC_DIR)/parser/parser.c $(SRC_DIR)/typeparser/typeparser.c $(SRC_DIR)/interactive/interactive.c
OBJS = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRCS)) OBJS = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRCS))
TARGET = solstice TARGET = solstice
@@ -29,6 +33,9 @@ install: $(TARGET)
install -d $(LIBDIR) install -d $(LIBDIR)
cp -r libs/* $(LIBDIR)/solstice cp -r libs/* $(LIBDIR)/solstice
static: $(OBJS)
$(CXX) $(OBJS) $(GROUND_STATIC) -o $(TARGET)
$(BUILD_DIR)/solstice.tar.gz: $(TARGET) $(LIBS_DIR) $(BUILD_DIR)/solstice.tar.gz: $(TARGET) $(LIBS_DIR)
mkdir -p $(BUILD_DIR)/pkg/bin $(BUILD_DIR)/pkg/lib/ mkdir -p $(BUILD_DIR)/pkg/bin $(BUILD_DIR)/pkg/lib/
cp $(TARGET) $(BUILD_DIR)/pkg/bin/solstice cp $(TARGET) $(BUILD_DIR)/pkg/bin/solstice
@@ -38,9 +45,12 @@ $(BUILD_DIR)/solstice.tar.gz: $(TARGET) $(LIBS_DIR)
package: $(BUILD_DIR)/solstice.tar.gz package: $(BUILD_DIR)/solstice.tar.gz
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $(BUILD_DIR) $(BUILD_DIR)/codegen $(BUILD_DIR)/lexer $(BUILD_DIR)/parser $(BUILD_DIR)/typeparser mkdir -p $(BUILD_DIR) $(BUILD_DIR)/codegen $(BUILD_DIR)/lexer $(BUILD_DIR)/parser $(BUILD_DIR)/typeparser $(BUILD_DIR)/interactive
clean: clean:
rm -rf $(BUILD_DIR) $(TARGET) rm -rf $(BUILD_DIR) $(TARGET)
.PHONY: all clean run: $(TARGET)
./$(TARGET)
.PHONY: all clean run

37
libs/collections.sols Normal file
View File

@@ -0,0 +1,37 @@
struct List {
protected size = 0
protected capacity = 0
protected memSize = 0
private ptr = 0
constructor(int length) {}
def append(int value) int {}
def insert(int value, int index) int {}
def remove(int index) int {}
def at(int index) int {}
def clear() int {}
def set(int value, int index) int {}
def isEmpty() bool {}
def contains(int value) bool {}
def reverse() int {}
def find(int value) int {}
def reserve(int n) int {}
}
struct Hashmap {
private ptr = 0
constructor() {}
def set(string key, int value) int {}
def get(string key) int {}
def getOr(string key, int fallback) int {}
def remove(string key) int {}
def removeIfPresent(string key) bool {}
}
ground {
extern "collections"
}

View File

@@ -1,15 +0,0 @@
def stringToInt(string in) int {
result = 0
ground {
stoi $in &result
}
return result
}
def intToString(int in) string {
result = ""
ground {
tostring $in &result
}
return result
}

View File

@@ -1,5 +1,18 @@
def file_Read(string file) string {} struct File {
def file_Write(string file, string content) {} private fileHandle = 0
protected filePath = ""
protected size = 0
protected tell = 0
constructor (string filePath) {}
def read() string {}
def write(string buffer) int {}
def append(string buffer) int {}
def flush() int {}
def seek(int offset) int {}
def seekEnd(int offset) int {}
}
ground { ground {
extern "fileio" extern "fileio"

28
libs/strings.sols Normal file
View File

@@ -0,0 +1,28 @@
def string_CharAt(string str, int index) string {}
def string_Upper(string str) string {}
def string_Lower(string str) string {}
def string_Trim(string str) string {}
def string_TrimLeft(string str) string {}
def string_TrimRight(string str) string {}
def string_Substring(string str, int start, int end) string {}
def string_Repeat(string str, int times) string {}
def string_Replace(string haystack, string needle) string {}
def string_Reverse(string str) string {}
def string_StartsWith(string str, string prefix) bool {}
def string_EndsWith(string str, string suffix) bool {}
def string_Contains(string haystack, string needle) bool {}
def string_Find(string haystack, string needle) int {}
def string_FindLast(string haystack, string needle) int {}
def string_Count(string haystack, string needle) int {}
def string_isAlpha(string str) bool {}
def string_isAlnum(string str) bool {}
def string_isDigit(string str) bool {}
def string_isSpace(string str) bool {}
ground {
extern "string"
}

View File

@@ -9,7 +9,13 @@ void addVariableToScope(SolsScope* scope, const char* name, SolsType type) {
strncpy(s->id, name, sizeof(s->id) - 1); strncpy(s->id, name, sizeof(s->id) - 1);
s->id[sizeof(s->id) - 1] = '\0'; s->id[sizeof(s->id) - 1] = '\0';
s->typeinfo = type; s->typeinfo = ({
ResultType(SolsType, charptr) _result = copySolsType(&type);
if (_result.error) {
return;
}
_result.as.success;
});
HASH_ADD_STR(scope->variables, id, s); HASH_ADD_STR(scope->variables, id, s);
} }

File diff suppressed because it is too large Load Diff

71
src/include/list.h Normal file
View File

@@ -0,0 +1,71 @@
// list.h - create a list of any kind in C
// append, pop, safely retrieve
// licenced to you under the MIT license
// example:
//
// #include "list.h"
//
// UseList(int);
//
// int main() {
// List(int) myList = newList(int);
// append(myList, 32);
// printf("%d\n", *get(myList, 0));
// pop(myList);
// destroy(myList);
// }
//
#ifndef LIST_H
#define LIST_H
#include <stdlib.h>
#include <stdio.h>
#define LIST_H_INIT_CAPACITY 32
#define UseList(type) struct __List_##type { type* pointer; size_t count; size_t capacity; size_t itemsize; }
#define List(type) struct __List_##type
#define newList(type) ({ \
List(type) __list_tmp = { .pointer = malloc(sizeof(type) * LIST_H_INIT_CAPACITY), .count = 0, .capacity = LIST_H_INIT_CAPACITY, .itemsize = sizeof(type) };\
if (__list_tmp.pointer == NULL) { \
printf("list.h:32 (newList(type)) - failed to allocate memory"); exit(1);\
}\
__list_tmp;\
})
#define append(list, item) {\
if (list.pointer == NULL) {\
printf("list.h:39 (append(list, item)) - list pointer is null (perhaps you accidently destroyed the list?)"); exit(1);\
}\
if (list.capacity < list.count + 1) {\
list.capacity *= 2;\
void* __tmp_ptr = realloc(list.pointer, list.capacity * list.itemsize);\
if (__tmp_ptr == NULL) {\
printf("list.h:45 (append(list, item)) - failed to allocate memory"); exit(1);\
}\
list.pointer = __tmp_ptr;\
}\
list.pointer[list.count] = item;\
list.count++;\
}
#define get(list, idx) ({\
if (list.pointer == NULL) {\
printf("list.h:55 (get(list, idx)) - list pointer is null (perhaps you accidently destroyed the list?)"); exit(1);\
}\
(idx >= list.count) ? NULL : &list.pointer[idx];\
})
#define pop(list) {\
if (list.pointer == NULL) {\
printf("list.h:65 (pop(list)) - list pointer is null (perhaps you accidently destroyed the list?)"); exit(1);\
}\
if (list.count > 0) list.count--;\
}
#define destroy(list) if (list.pointer != NULL) {\
free(list.pointer); list.pointer = NULL; \
}
#endif

View File

@@ -0,0 +1,77 @@
#include "interactive.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Interactive createInteractive() {
return (Interactive) {
.callbacks.at = malloc(sizeof(InteractiveCallback) * 16),
.callbacks.capacity = 16,
.callbacks.size = 0
};
}
void addCallback(Interactive* interactive, int (*function)(size_t, char**, void*), char* name) {
if (interactive->callbacks.size + 1 >= interactive->callbacks.capacity) {
interactive->callbacks.at = realloc(interactive->callbacks.at, (interactive->callbacks.capacity * 2) * sizeof(InteractiveCallback));
interactive->callbacks.capacity *= 2;
}
interactive->callbacks.at[interactive->callbacks.size].function = function;
interactive->callbacks.at[interactive->callbacks.size].name = name;
interactive->callbacks.size++;
}
typedef struct InteractiveCommand {
char* command;
size_t argc;
size_t capacity;
char** argv;
} InteractiveCommand;
static inline InteractiveCommand parseInteractiveCommand(char* input) {
InteractiveCommand command = {
.command = malloc(sizeof(char*) * 16),
.argc = 0,
.capacity = 16,
.argv = malloc(sizeof(char*) * 16)
};
for (size_t i = 0; i < command.capacity; i++) {
command.argv[i] = malloc(sizeof(char) * 64);
}
size_t len = strlen(input);
char** currentBuf = &command.command;
size_t currentLen = 0;
for (size_t i = 0; i < len; i++) {
if (input[i] == '\n') break;
if (input[i] == ' ' || currentLen == 63) {
if (command.argc + 1 >= command.capacity) {
command.capacity *= 2;
command.argv = realloc(command.argv, command.capacity * sizeof(char**));
}
currentBuf = &command.argv[command.argc];
command.argc++;
} else {
currentBuf[currentLen][i] = input[i];
}
}
return command;
}
void runInteractive(Interactive* interactive, void* ctx) {
for (;;) {
char buf[512];
printf("> ");
fgets(buf, sizeof(buf), stdin);
InteractiveCommand command = parseInteractiveCommand(buf);
if (strcmp(command.command, "exit") == 0) {
break;
}
for (size_t i = 0; i < interactive->callbacks.size; i++) {
if (strcmp(command.command, interactive->callbacks.at[i].name) == 0) {
interactive->callbacks.at[i].function(command.argc, command.argv, ctx);
}
}
}
}

View File

@@ -0,0 +1,26 @@
#ifndef INTERACTIVE_H
#define INTERACTIVE_H
#include <stdlib.h>
// Callback functions are of the form
// int callback(int argc, char** argv, void* ctx)
typedef struct InteractiveCallback {
int (*function)(size_t, char**, void*);
char* name;
} InteractiveCallback;
typedef struct Interactive {
struct {
InteractiveCallback* at;
size_t size;
size_t capacity;
} callbacks;
} Interactive;
Interactive createInteractive();
void addCallback(Interactive* interactive, int (*function)(size_t, char**, void*), char* name);
void runInteractive(Interactive* interactive, void* ctx);
#endif

View File

@@ -1,6 +1,8 @@
#include "SolsLiteral.h" #include "SolsLiteral.h"
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <inttypes.h>
#include <stdio.h>
ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...) { ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...) {
va_list args; va_list args;
@@ -47,5 +49,30 @@ ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...) {
void freeSolsLiteral(SolsLiteral* lit) { void freeSolsLiteral(SolsLiteral* lit) {
if (lit->type == SLT_STRING && lit->as.stringv != NULL) { if (lit->type == SLT_STRING && lit->as.stringv != NULL) {
free(lit->as.stringv); free(lit->as.stringv);
} }
}
void printSolsLiteral(SolsLiteral* lit) {
switch (lit->type) {
case SLT_INT: {
printf("%" PRId64, lit->as.intv);
break;
}
case SLT_DOUBLE: {
printf("%f", lit->as.doublev);
break;
}
case SLT_STRING: {
printf("%s", lit->as.stringv);
break;
}
case SLT_BOOL: {
printf(lit->as.boolv ? "true" : "false");
break;
}
case SLT_CHAR: {
printf("%c", lit->as.charv);
break;
}
}
} }

View File

@@ -43,4 +43,7 @@ ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...);
// Frees a SolsLiteral. Primarily concerned with freeing .as.stringv // Frees a SolsLiteral. Primarily concerned with freeing .as.stringv
void freeSolsLiteral(SolsLiteral* lit); void freeSolsLiteral(SolsLiteral* lit);
// Prints a SolsLiteral
void printSolsLiteral(SolsLiteral* lit);
#endif #endif

View File

@@ -10,7 +10,20 @@
#include "SolsLiteral.h" #include "SolsLiteral.h"
typedef enum SolsTokenType { typedef enum SolsTokenType {
STT_IDENTIFIER, STT_LITERAL, STT_TYPE, STT_DOT, STT_OPEN_CURLY, STT_CLOSE_CURLY, STT_OPEN_PAREN, STT_CLOSE_PAREN, STT_OP_ADD, STT_OP_SUB, STT_OP_MUL, STT_OP_DIV, STT_OP_ADDTO, STT_OP_SUBTO, STT_OP_MULTO, STT_OP_DIVTO, STT_OP_INCREMENT, STT_OP_DECREMENT, STT_OP_SET, STT_OP_GREATER, STT_OP_LESSER, STT_OP_EQUAL, STT_OP_INEQUAL, STT_OP_EQGREATER, STT_OP_EQLESSER, STT_KW_DEF, STT_KW_LAMBDA, STT_KW_RETURN, STT_KW_USE, STT_KW_STRUCT, STT_KW_PUTS, STT_KW_IF, STT_KW_WHILE, STT_KW_NEW, STT_KW_GROUND, STT_LINE_END, STT_COMMA STT_IDENTIFIER, STT_LITERAL, STT_TYPE, STT_DOT,
STT_OPEN_CURLY, STT_CLOSE_CURLY, STT_OPEN_PAREN, STT_CLOSE_PAREN,
STT_OP_ADD, STT_OP_SUB, STT_OP_MUL, STT_OP_DIV,
STT_OP_ADDTO, STT_OP_SUBTO, STT_OP_MULTO, STT_OP_DIVTO,
STT_OP_INCREMENT, STT_OP_DECREMENT, STT_OP_SET,
STT_OP_GREATER, STT_OP_LESSER, STT_OP_EQUAL, STT_OP_INEQUAL, STT_OP_EQGREATER, STT_OP_EQLESSER,
STT_KW_DEF, STT_KW_LAMBDA, STT_KW_RETURN,
STT_KW_USE, STT_KW_STRUCT, STT_KW_ENUM, STT_KW_CONSTRUCTOR, STT_KW_DESTRUCTOR, STT_KW_DUPLICATOR,
STT_KW_AS, STT_KW_SIZEOF,
STT_KW_PRIVATE, STT_KW_PROTECTED,
STT_KW_PUTS, STT_KW_IF, STT_KW_WHILE,
STT_KW_NEW, STT_KW_GROUND, STT_LINE_END, STT_COMMA,
STT_OPEN_SQUARE, STT_CLOSE_SQUARE,
STT_KW_PRAGMA,
} SolsTokenType; } SolsTokenType;
typedef char* charptr; typedef char* charptr;
@@ -57,7 +70,7 @@ void freeSolsToken(SolsToken* token);
// Represents a Solstice program, seperated into tokens. // Represents a Solstice program, seperated into tokens.
// .at is a pointer to the tokens // .at is a pointer to the tokens
// .count is how many tokens are currently being stored // .count is how many tokens are currently being stored
// .capacity is how many tokens worth of memory is allocated // .capacity is how many tokens worth of memory is allocated
typedef struct SolsTokens { typedef struct SolsTokens {
SolsToken* at; SolsToken* at;

View File

@@ -1,5 +1,4 @@
#include "SolsType.h" #include "SolsType.h"
#include "lexer.h"
#include "../include/error.h" #include "../include/error.h"
#include "../include/estr.h" #include "../include/estr.h"
#include <groundvm.h> #include <groundvm.h>
@@ -10,10 +9,116 @@ ResultType(SolsType, charptr) createSolsType(SolsTypeType in) {
if (ptr == NULL) { if (ptr == NULL) {
return Error(SolsType, charptr, "Couldn't allocate memory (in createSolsType() function)"); return Error(SolsType, charptr, "Couldn't allocate memory (in createSolsType() function)");
} }
SolsType type = { .type = in, .children.capacity = 32, .children.at = ptr }; SolsType type = {
.type = in == STT_GENERIC ? STT_TEMPLATE : in,
.identifierType = NULL,
.returnType = NULL,
.children.capacity = 32,
.children.count = 0,
.children.at = ptr,
.typeIsKnown = true,
.needsGroundStruct = false,
.metadata.isPrivate = false,
.metadata.isProtected = false,
.metadata.isEnum = false,
.metadata.isGenericField = in == STT_GENERIC,
.metadata.isGenericStruct = false,
.metadata.genericStructNode = NULL
};
return Success(SolsType, charptr, type); return Success(SolsType, charptr, type);
} }
ResultType(SolsType, charptr) createIdentifiedSolsType(char* in) {
char* copy = malloc(strlen(in) + 1);
if (copy == NULL) {
return Error(SolsType, charptr, "Couldn't allocate memory (in createIdentifiedSolsType() function)");
}
strcpy(copy, in);
return Success(SolsType, charptr, ((SolsType) {
.type = STT_UNKNOWN,
.identifierType = copy,
.returnType = NULL,
.children.capacity = 0,
.children.count = 0,
.children.at = NULL,
.typeIsKnown = false,
.needsGroundStruct = false,
.metadata.isPrivate = false,
.metadata.isProtected = false,
.metadata.isEnum = false,
.metadata.isGenericField = false,
.metadata.isGenericStruct = false,
.metadata.genericStructNode = NULL
}));
}
ResultType(SolsType, charptr) copySolsType(SolsType* type) {
SolsType ret = {
.type = type->type,
.identifierType = NULL,
.typeIsKnown = type->typeIsKnown,
.needsGroundStruct = type->needsGroundStruct,
.returnType = NULL,
.children.count = type->children.count,
.children.capacity = type->children.capacity,
.children.at = NULL,
.metadata = type->metadata
};
if (type->identifierType != NULL) {
ret.identifierType = malloc(strlen(type->identifierType) + 1);
if (ret.identifierType == NULL) {
return Error(SolsType, charptr, "Couldn't allocate memory (in copySolsType() function)");
}
strcpy(ret.identifierType, type->identifierType);
}
if (type->returnType != NULL && type->returnType->type != STT_NONE) {
ResultType(SolsType, charptr) copiedReturn = copySolsType(type->returnType);
if (copiedReturn.error) {
Estr err = CREATE_ESTR(copiedReturn.as.error);
APPEND_ESTR(err, " (in copySolsType() function)");
return Error(SolsType, charptr, err.str);
}
ret.returnType = malloc(sizeof(SolsType));
if (ret.returnType == NULL) {
return Error(SolsType, charptr, "Couldn't allocate memory (in copySolsType() function)");
}
*ret.returnType = copiedReturn.as.success;
}
if (type->children.capacity > 0) {
SolsTypeField* ptr = malloc(sizeof(SolsTypeField) * type->children.capacity);
if (ptr == NULL) {
return Error(SolsType, charptr, "Couldn't allocate memory (in copySolsType() function)");
}
ret.children.at = ptr;
}
for (size_t i = 0; i < type->children.count; i++) {
ResultType(SolsType, charptr) copied = copySolsType(&type->children.at[i].type);
if (copied.error) {
Estr err = CREATE_ESTR(copied.as.error);
APPEND_ESTR(err, " (in copySolsType() function)");
return Error(SolsType, charptr, err.str);
}
ret.children.at[i].type = copied.as.success;
if (type->children.at[i].name == NULL) {
ret.children.at[i].name = NULL;
} else {
ret.children.at[i].name = malloc(strlen(type->children.at[i].name) + 1);
if (ret.children.at[i].name == NULL) {
return Error(SolsType, charptr, "Couldn't allocate memory (in copySolsType() function)");
}
strcpy(ret.children.at[i].name, type->children.at[i].name);
}
}
return Success(SolsType, charptr, ret);
}
/*
ResultType(SolsType, charptr) copySolsType(SolsType* type) { ResultType(SolsType, charptr) copySolsType(SolsType* type) {
SolsType ret = { .type = type->type, .children.count = type->children.count, .children.capacity = type->children.capacity}; SolsType ret = { .type = type->type, .children.count = type->children.count, .children.capacity = type->children.capacity};
@@ -48,6 +153,7 @@ ResultType(SolsType, charptr) copySolsType(SolsType* type) {
} }
return Success(SolsType, charptr, ret); return Success(SolsType, charptr, ret);
} }
*/
ResultType(Nothing, charptr) addChildToSolsType(SolsType* type, SolsType child, const char* name) { ResultType(Nothing, charptr) addChildToSolsType(SolsType* type, SolsType child, const char* name) {
if (type->children.capacity < type->children.count + 1) { if (type->children.capacity < type->children.count + 1) {
@@ -144,7 +250,7 @@ bool compareTypes(SolsType* left, SolsType* right) {
} }
} }
ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type) { ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type, struct SolsScope* scope) {
switch (type->type) { switch (type->type) {
case STT_INT: { case STT_INT: {
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "int")); return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "int"));
@@ -168,9 +274,89 @@ ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type) {
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "struct")); return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "struct"));
} }
case STT_OBJECT: { case STT_OBJECT: {
// FIXME Do this later if (!type->needsGroundStruct) {
return Error(GroundArg, charptr, "FIXME"); return Success(GroundArg, charptr, groundCreateReference(TYPEREF, type->identifierType));
} else {
// FIXME do this later
return Error(GroundArg, charptr, "Anonymous structs are not supported yet");
}
}
case STT_UNKNOWN: {
if (!type->needsGroundStruct) {
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, type->identifierType));
} else {
// FIXME do this later
return Error(GroundArg, charptr, "Anonymous structs are not supported yet");
}
}
case STT_NONE: {
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "none"));
} }
} }
return Error(GroundArg, charptr, "How did we get here?"); return Error(GroundArg, charptr, "How did we get here?");
} }
ResultType(SolsType, charptr) findStructMemberType(SolsType* type, char* member) {
for (size_t i = 0; i < type->children.count; i++) {
if (strcmp(type->children.at[i].name, member) == 0) {
return Success(SolsType, charptr, type->children.at[i].type);
}
}
return Error(SolsType, charptr, "Could not find member");
}
void printSolsType(SolsType* type) {
printf("Type: ");
switch (type->type) {
case STT_INT:
printf("int");
break;
case STT_DOUBLE:
printf("double");
break;
case STT_STRING:
printf("string");
break;
case STT_BOOL:
printf("bool");
break;
case STT_CHAR:
printf("char");
break;
case STT_FUN:
printf("fun");
break;
case STT_TEMPLATE:
printf("template");
break;
case STT_OBJECT:
printf("object");
break;
case STT_UNKNOWN:
printf("(unknown)");
break;
case STT_NONE:
printf("(none)");
break;
case STT_GENERIC:
printf("(generic");
break;
}
if (type->returnType != NULL) {
printf("\nReturn type: ");
printSolsType(type->returnType);
}
if (type->children.count > 0) {
printf("\nChildren {");
for (size_t i = 0; i < type->children.count; i++) {
if (type->children.at[i].name != NULL) {
printf("\nName: %s", type->children.at[i].name);
}
printf("\nType: ");
printSolsType(&type->children.at[i].type);
}
printf("}");
}
}

View File

@@ -8,13 +8,14 @@
#include "../include/nothing.h" #include "../include/nothing.h"
typedef enum SolsTypeType { typedef enum SolsTypeType {
STT_INT, STT_STRING, STT_DOUBLE, STT_BOOL, STT_CHAR, STT_FUN, STT_TEMPLATE, STT_OBJECT STT_INT, STT_STRING, STT_DOUBLE, STT_BOOL, STT_CHAR, STT_FUN, STT_TEMPLATE, STT_OBJECT, STT_UNKNOWN, STT_GENERIC, STT_NONE
} SolsTypeType; } SolsTypeType;
// Definition of charptr for Result() and ResultType() macros // Definition of charptr for Result() and ResultType() macros
typedef char* charptr; typedef char* charptr;
struct SolsTypeField; struct SolsTypeField;
struct SolsNode; // for generic struct
// Holds type information for a struct, object or function. // Holds type information for a struct, object or function.
// Say, for example, your type signature looks like this: // Say, for example, your type signature looks like this:
@@ -53,6 +54,12 @@ typedef struct SolsType {
// For use when type is identified with a name // For use when type is identified with a name
char* identifierType; char* identifierType;
// If type is identified with a name, record whether we have found the actual type
bool typeIsKnown;
// If using anonymous struct, record whether we need to generate a Ground struct
bool needsGroundStruct;
// For use in functions // For use in functions
struct SolsType* returnType; struct SolsType* returnType;
@@ -62,6 +69,18 @@ typedef struct SolsType {
size_t count; size_t count;
size_t capacity; size_t capacity;
} children; } children;
struct {
bool isPrivate;
bool isProtected;
bool isEnum;
bool isGenericField;
bool isGenericStruct;
// For use by generic struct
// We will codegen this where required
struct SolsNode* genericStructNode;
} metadata;
} SolsType; } SolsType;
// Assists with holding child types in the SolsType struct. // Assists with holding child types in the SolsType struct.
@@ -73,16 +92,20 @@ typedef struct SolsTypeField {
Result(SolsType, charptr); Result(SolsType, charptr);
// Creates a SolsType, with the provided type type. // Creates a SolsType, with the provided type type.
// Use the "addChildToSolsType()" function to add children, in case this type has children. // Use the "addChildToSolsType()" function to add children, in case this type has children.
// Returns: // Returns:
// Success: The constructed SolsType // Success: The constructed SolsType
// Failure: char* detailing what went wrong (usually memory failure) // Failure: char* detailing what went wrong (usually memory failure)
ResultType(SolsType, charptr) createSolsType(SolsTypeType in); ResultType(SolsType, charptr) createSolsType(SolsTypeType in);
// Creates a SolsType which is identified by a name.
// The type details are not known yet, so the type is marked as unknown.
ResultType(SolsType, charptr) createIdentifiedSolsType(char* in);
Result(Nothing, charptr); Result(Nothing, charptr);
// Adds a child SolsType to a given SolsType. // Adds a child SolsType to a given SolsType.
// Returns: // Returns:
// Success: Nothing // Success: Nothing
// Failure: char* detailing what went wrong (usually memory failure) // Failure: char* detailing what went wrong (usually memory failure)
@@ -93,8 +116,10 @@ ResultType(SolsType, charptr) copySolsType(SolsType* type);
Result(GroundArg, charptr); Result(GroundArg, charptr);
struct SolsScope;
// Represents a SolsType as a GroundArg (in typeref form) // Represents a SolsType as a GroundArg (in typeref form)
ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type); ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type, struct SolsScope* scope);
// Frees a SolsType // Frees a SolsType
void freeSolsType(SolsType* type); void freeSolsType(SolsType* type);
@@ -102,4 +127,9 @@ void freeSolsType(SolsType* type);
// Compares two SolsTypes // Compares two SolsTypes
bool compareTypes(SolsType* left, SolsType* right); bool compareTypes(SolsType* left, SolsType* right);
// Finds the type of a struct member. Errors if the member is not found.
ResultType(SolsType, charptr) findStructMemberType(SolsType* type, char* member);
void printSolsType(SolsType* type);
#endif #endif

View File

@@ -15,11 +15,23 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
{"return", STT_KW_RETURN}, {"return", STT_KW_RETURN},
{"use", STT_KW_USE}, {"use", STT_KW_USE},
{"struct", STT_KW_STRUCT}, {"struct", STT_KW_STRUCT},
{"enum", STT_KW_ENUM},
{"constructor", STT_KW_CONSTRUCTOR},
{"destructor", STT_KW_DESTRUCTOR},
{"duplicator", STT_KW_DUPLICATOR},
{"private", STT_KW_PRIVATE},
{"protected", STT_KW_PROTECTED},
{"ground", STT_KW_GROUND}, {"ground", STT_KW_GROUND},
{"new", STT_KW_NEW},
{"as", STT_KW_AS},
{"sizeof", STT_KW_SIZEOF},
{"pragma", STT_KW_PRAGMA},
{"{", STT_OPEN_CURLY}, {"{", STT_OPEN_CURLY},
{"}", STT_CLOSE_CURLY}, {"}", STT_CLOSE_CURLY},
{"(", STT_OPEN_PAREN}, {"(", STT_OPEN_PAREN},
{")", STT_CLOSE_PAREN}, {")", STT_CLOSE_PAREN},
{"[", STT_OPEN_SQUARE},
{"]", STT_CLOSE_SQUARE},
{"+", STT_OP_ADD}, {"+", STT_OP_ADD},
{"-", STT_OP_SUB}, {"-", STT_OP_SUB},
{"*", STT_OP_MUL}, {"*", STT_OP_MUL},
@@ -42,7 +54,7 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
{",", STT_COMMA}, {",", STT_COMMA},
// Shh, this is our little secret // Shh, this is our little secret
// Your reward for actually reading the source code // Your reward for actually reading the source code
// Enable this by adding -DSUPER_SILLY_MODE to your // Enable this by adding -DSUPER_SILLY_MODE to your
// compile flags (not recommended for production) // compile flags (not recommended for production)
#ifdef SUPER_SILLY_MODE #ifdef SUPER_SILLY_MODE
{"plus", STT_OP_ADD}, {"plus", STT_OP_ADD},
@@ -62,6 +74,8 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
{"subtracts", STT_OP_SUBTO}, {"subtracts", STT_OP_SUBTO},
{"multiplies", STT_OP_MULTO}, {"multiplies", STT_OP_MULTO},
{"divides", STT_OP_DIVTO}, {"divides", STT_OP_DIVTO},
{"class", STT_KW_STRUCT},
{"compilerpleasedothisforme", STT_KW_PRAGMA}
#endif #endif
}; };
@@ -577,13 +591,15 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
} }
// These characters require themselves added seperately from the previous token. // These characters require themselves added seperately from the previous token.
case '{': case '{':
case '}': case '}':
case '(': case '(':
case ')': case ')':
case ',': case ',':
case ':': case ':':
case ';': case ';':
case '[':
case ']':
case '\n': case '\n':
{ {
ResultType(Nothing, charptr) res = identifyAndAdd(lexer, &buf, &lineNum, &currentLine, chr.as.success, &skipDelimiter); ResultType(Nothing, charptr) res = identifyAndAdd(lexer, &buf, &lineNum, &currentLine, chr.as.success, &skipDelimiter);
@@ -593,7 +609,7 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
DESTROY_ESTR(currentLine); DESTROY_ESTR(currentLine);
return Error(Nothing, charptr, err); return Error(Nothing, charptr, err);
} }
if (skipDelimiter) break; if (skipDelimiter) break;
char tmp[] = {chr.as.success, '\0'}; char tmp[] = {chr.as.success, '\0'};
@@ -613,7 +629,7 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
return Error(Nothing, charptr, err); return Error(Nothing, charptr, err);
} }
strcpy(result.as.success.line.content, currentLine.str); strcpy(result.as.success.line.content, currentLine.str);
addTokenToSolsTokens(&lexer->output, result.as.success); addTokenToSolsTokens(&lexer->output, result.as.success);
break; break;
} }
@@ -694,7 +710,7 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
addTokenToSolsTokens(&lexer->output, result.as.success); addTokenToSolsTokens(&lexer->output, result.as.success);
lexerConsume(lexer); lexerConsume(lexer);
} }
break; break;
} }
// These characters may be followed by an equals sign, or nothing else. // These characters may be followed by an equals sign, or nothing else.

View File

@@ -7,13 +7,19 @@
#include "include/estr.h" #include "include/estr.h"
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#ifdef _WIN32 #ifdef _WIN32
#include <direct.h> #include <direct.h>
#else #else
#include <sys/stat.h> #include <sys/stat.h>
#include <libgen.h>
#endif #endif
#include <groundvm.h> #include <groundvm.h>
extern bool groundDisableTypeChecking;
char* fileDir = NULL;
typedef enum SolsAction { typedef enum SolsAction {
SA_PRINT, SA_EXEC, SA_BYTECODE, SA_COMPILE, SA_EXIT, SA_EXITOK SA_PRINT, SA_EXEC, SA_BYTECODE, SA_COMPILE, SA_EXIT, SA_EXITOK
} SolsAction; } SolsAction;
@@ -91,41 +97,12 @@ Args parseArgs(int argc, char** argv) {
return args; return args;
} }
char* getFileContents(const char* filename) { // Use ground's getFileContents
// https://stackoverflow.com/questions/3747086/reading-the-whole-text-file-into-a-char-array-in-c char* getFileContents(const char* filename);
FILE* fp;
long lSize;
char* file;
fp = fopen(filename, "rb");
if (!fp) {
perror(filename);
return NULL;
}
fseek(fp, 0L, SEEK_END);
lSize = ftell(fp);
rewind(fp);
file = calloc(1, lSize + 1);
if (!file) {
fclose(fp);
return NULL;
}
if (1!=fread(file, lSize, 1, fp)) {
fclose(fp);
free(file);
return NULL;
}
// we done
fclose(fp);
return file;
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
groundDisableTypeChecking = true;
Args args = parseArgs(argc, argv); Args args = parseArgs(argc, argv);
if (args.action == SA_EXIT) { if (args.action == SA_EXIT) {
@@ -135,6 +112,17 @@ int main(int argc, char** argv) {
return 0; return 0;
} }
#ifdef _WIN32
fileDir = NULL;
#else
{
char tmp[FILENAME_MAX];
char pwd[FILENAME_MAX];
getcwd(pwd, sizeof(pwd));
snprintf(tmp, FILENAME_MAX, "%s/%s", pwd, args.inputFile);
fileDir = dirname(tmp);
}
#endif
char* fileContents = getFileContents(args.inputFile); char* fileContents = getFileContents(args.inputFile);
if (fileContents == NULL) { if (fileContents == NULL) {

View File

@@ -68,3 +68,198 @@ SolsNode deepCopySolsNode(SolsNode node) {
} }
return copy; return copy;
} }
void printSolsNodeType(SolsNodeType type) {
switch (type) {
case SNT_IDENTIFIER:
printf("Identifier");
break;
case SNT_LITERAL:
printf("Literal");
break;
case SNT_TYPE:
printf("Type");
break;
case SNT_CODE_BLOCK:
printf("Code Block");
break;
case SNT_OP_ADD:
printf("+");
break;
case SNT_OP_SUB:
printf("-");
break;
case SNT_OP_MUL:
printf("*");
break;
case SNT_OP_DIV:
printf("/");
break;
case SNT_OP_ADDTO:
printf("+=");
break;
case SNT_OP_SUBTO:
printf("-=");
break;
case SNT_OP_MULTO:
printf("*=");
break;
case SNT_OP_DIVTO:
printf("/=");
break;
case SNT_OP_INCREMENT:
printf("++");
break;
case SNT_OP_DECREMENT:
printf("--");
break;
case SNT_OP_SET:
printf("=");
break;
case SNT_OP_GREATER:
printf(">");
break;
case SNT_OP_LESSER:
printf("<");
break;
case SNT_OP_EQUAL:
printf("==");
break;
case SNT_OP_INEQUAL:
printf("!=");
break;
case SNT_OP_EQGREATER:
printf(">=");
break;
case SNT_OP_EQLESSER:
printf("<=");
break;
case SNT_DEF:
printf("def");
break;
case SNT_LAMBDA:
printf("lambda");
break;
case SNT_FUNCTION_CALL:
printf("Function call");
break;
case SNT_RETURN:
printf("return");
break;
case SNT_SET_PRIVATE:
printf("Private =");
break;
case SNT_SET_PROTECTED:
printf("Protected =");
break;
case SNT_DEF_PRIVATE:
printf("Private def");
break;
case SNT_DEF_PROTECTED:
printf("Protected def");
break;
case SNT_USE:
printf("use");
break;
case SNT_LOCAL_USE:
printf("Local use");
break;
case SNT_STRUCT:
printf("struct");
break;
case SNT_ENUM:
printf("enum");
break;
case SNT_CONSTRUCTOR:
printf("constructor");
break;
case SNT_DESTRUCTOR:
printf("destructor");
break;
case SNT_DUPLICATOR:
printf("duplicator");
break;
case SNT_STRUCT_AS:
printf("struct as");
break;
case SNT_AS:
printf("as");
break;
case SNT_SIZE_OF:
printf("sizeof");
break;
case SNT_PUTS:
printf("puts");
break;
case SNT_IF:
printf("if");
break;
case SNT_WHILE:
printf("while");
break;
case SNT_NEW:
printf("new");
break;
case SNT_GROUND:
printf("ground");
break;
case SNT_ROOT:
printf("Root node");
break;
case SNT_EXPR_IN_PAREN:
printf("Parenthases");
break;
case SNT_DOT:
printf(".");
break;
case SNT_GENERIC:
printf("Generic");
break;
case SNT_GENERIC_INIT:
printf("Generic init");
break;
case SNT_PRAGMA:
printf("pragma");
break;
}
}
void printSolsNode(SolsNode* node) {
printf("Node (\nNodeType: ");
printSolsNodeType(node->type);
printf("\n");
printf("Line: num: %zu, content: %s",node->line.num, node->line.content);
switch (node->type) {
case SNT_IDENTIFIER: {
printf("\nIdentifier name: '%s'", node->as.idName);
break;
}
case SNT_GROUND: {
printf("\nInline Ground: '%s'", node->as.inlineGround);
break;
}
case SNT_LITERAL: {
printf("\nLiteral: ");
printSolsLiteral(&node->as.literal);
break;
}
case SNT_TYPE: {
printf("\nType: ");
printSolsType(&node->as.type);
break;
}
}
printf("\nChildren count: %zu", node->children.count);
if (node->children.count > 0) {
printf("\nChildren: (\n");
for (size_t i = 0; i < node->children.count; i++) {
printSolsNode(&node->children.at[i]);
}
printf("\n)");
}
printf("\n)\n");
}

View File

@@ -11,7 +11,21 @@
#include "../lexer/SolsToken.h" #include "../lexer/SolsToken.h"
typedef enum SolsNodeType { typedef enum SolsNodeType {
SNT_IDENTIFIER, SNT_LITERAL, SNT_TYPE, SNT_CODE_BLOCK, SNT_OP_ADD, SNT_OP_SUB, SNT_OP_MUL, SNT_OP_DIV, SNT_OP_ADDTO, SNT_OP_SUBTO, SNT_OP_MULTO, SNT_OP_DIVTO, SNT_OP_INCREMENT, SNT_OP_DECREMENT, SNT_OP_SET, SNT_OP_GREATER, SNT_OP_LESSER, SNT_OP_EQUAL, SNT_OP_INEQUAL, SNT_OP_EQGREATER, SNT_OP_EQLESSER, SNT_DEF, SNT_LAMBDA, SNT_FUNCTION_CALL, SNT_RETURN, SNT_USE, SNT_STRUCT, SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW, SNT_GROUND, SNT_ROOT SNT_IDENTIFIER, SNT_LITERAL, SNT_TYPE,
SNT_CODE_BLOCK,
SNT_OP_ADD, SNT_OP_SUB, SNT_OP_MUL, SNT_OP_DIV,
SNT_OP_ADDTO, SNT_OP_SUBTO, SNT_OP_MULTO, SNT_OP_DIVTO,
SNT_OP_INCREMENT, SNT_OP_DECREMENT,
SNT_OP_SET,
SNT_OP_GREATER, SNT_OP_LESSER, SNT_OP_EQUAL, SNT_OP_INEQUAL, SNT_OP_EQGREATER, SNT_OP_EQLESSER,
SNT_DEF, SNT_LAMBDA, SNT_FUNCTION_CALL, SNT_RETURN,
SNT_SET_PRIVATE, SNT_SET_PROTECTED, SNT_DEF_PRIVATE, SNT_DEF_PROTECTED,
SNT_USE, SNT_LOCAL_USE, SNT_STRUCT, SNT_ENUM, SNT_CONSTRUCTOR, SNT_DESTRUCTOR, SNT_DUPLICATOR,
SNT_STRUCT_AS, SNT_AS, SNT_SIZE_OF,
SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW,
SNT_GROUND, SNT_ROOT, SNT_EXPR_IN_PAREN, SNT_DOT,
SNT_GENERIC, SNT_GENERIC_INIT,
SNT_PRAGMA
} SolsNodeType; } SolsNodeType;
struct SolsNode; struct SolsNode;
@@ -59,6 +73,8 @@ ResultType(SolsNode, charptr) createSolsNode(SolsNodeType type, ...);
// Failure: char* detailing what went wrong (usually memory failure) // Failure: char* detailing what went wrong (usually memory failure)
ResultType(Nothing, charptr) addChildToSolsNode(SolsNode* parent, SolsNode child); ResultType(Nothing, charptr) addChildToSolsNode(SolsNode* parent, SolsNode child);
void printSolsNode(SolsNode* node);
// Deep copies a SolsNode // Deep copies a SolsNode
SolsNode deepCopySolsNode(SolsNode node); SolsNode deepCopySolsNode(SolsNode node);

File diff suppressed because it is too large Load Diff

11
tests/enum.sols Normal file
View File

@@ -0,0 +1,11 @@
enum Food {
Apple, Banana, Orange,
}
def function(Food food) Food {
return food
}
puts Food
puts function(Food.Banana)

46
tests/generics.sols Normal file
View File

@@ -0,0 +1,46 @@
struct Hash {
protected hashstr = ""
}
struct Person {
age = 0
name = ""
constructor(int age, string name) {
self.age = age
self.name = name
}
as Hash {
// hash the Person here
}
}
struct HashTable<Key can Hash, Value> {
private ptr = 0
protected size = 0
private capacity = 0
def find(Key key) {
hash = key as Hash
// find in table using hash
}
def set(Key key, Value value) {
hash = key as Hash
// store Value in the table
}
constructor() {
// malloc the pointer and set up hash information
}
duplicator {
// copy all contents
}
destructor {
// free the ptr
}
}

23
tests/nested-object.sols Normal file
View File

@@ -0,0 +1,23 @@
struct x {
a = 5
def modifyA(int a) int {
self.a = a
return a
}
}
struct y {
b = new x
}
z = new y
puts z
puts z.b
puts z.b.a
z.b.a = 10
puts z
z.b.modifyA(15)
puts z

7
tests/sizeof.sols Normal file
View File

@@ -0,0 +1,7 @@
puts sizeof "dingleing"
struct MyStruct {
size = 32
}
puts sizeof new MyStruct

View File

@@ -1,18 +1,42 @@
use io struct Person {
protected name = ""
private age = 0
def greet() string {
return "Hello, " + self.name + "!"
}
def dance() string {
return "Dancing..."
}
constructor(string name, int age) {
self.name = name
self.age = age
}
destructor {
// We don't need to do anything here.
}
duplicator {
puts "Duplicator called!"
// Also nothing here
}
as string {
return "dingus"
}
struct dingus {
x = 5
y = "dingus"
} }
e = new dingus max = Person("Max", 16)
puts e
puts dingus
puts e.x puts max
println(e.y) puts max.greet()
puts max.name
puts max as string
// puts max.age (causes compile time error, age is private)
// max.name = "Maximilian" (causes compile time error, name is protected)
e.x = 7 max.dance()
e.y = "heheheha"
puts e.x
println(e.y)

View File

@@ -5,37 +5,41 @@ if exists("b:current_syntax")
endif endif
" Keywords " Keywords
syn keyword solsticeConditional if syn keyword solsKeyword puts if while def lambda return use struct new private protected constructor destructor duplicator as ground
syn keyword solsticeRepeat while syn keyword solsBool true false
syn keyword solsticeKeyword def struct return use
syn keyword solsticeType int string bool double char
syn keyword solsticeBoolean true false
" Built-in functions " Types
syn keyword solsticeBuiltin puts print println input syn keyword solsType int double string char bool fun template object
" Data Types " Strings and chars
syn match solsticeNumber "\d\+\(\.\d\+\)\=" syn region solsString start=/"/ skip=/\\"/ end=/"/
syn region solsticeString start=/"/ end=/"/ syn region solsChar start=/'/ skip=/\\'/ end=/'/
syn match solsticeCharacter /'[^']'/
" Numbers
syn match solsFloat /\<[0-9]\+\.[0-9]*\>/
syn match solsInt /\<[0-9]\+\>/
" Operators " Operators
syn match solsticeOperator "==\|!=\|>=\|<=\|++\|--\|+\=\|-\=\|\*=\|\/=" syn match solsOperator /+\|-\|\*\|\/\|=\|!\|>\|<\|+=\|-=\|\*=\|\/=\|++\|--\|==\|!=\|>=\|<=/
syn match solsticeOperator "[><=+\-*/]"
" Delimiters " Delimiters
syn match solsticeDelimiter "[{()}]" syn match solsDelimiter /[{}(),;\[\]]/
hi def link solsticeConditional Conditional " Comments
hi def link solsticeRepeat Repeat syn match solsComment /\/\/.*$/
hi def link solsticeKeyword Keyword syn match solsComment /#.*$/
hi def link solsticeType Type
hi def link solsticeBoolean Boolean " Highlight links
hi def link solsticeBuiltin Function hi def link solsKeyword Keyword
hi def link solsticeNumber Number hi def link solsBool Boolean
hi def link solsticeString String hi def link solsType Type
hi def link solsticeCharacter Character hi def link solsString String
hi def link solsticeOperator Operator hi def link solsChar Character
hi def link solsticeDelimiter Delimiter hi def link solsFloat Float
hi def link solsInt Number
hi def link solsOperator Operator
hi def link solsDelimiter Delimiter
hi def link solsComment Comment
let b:current_syntax = "solstice" let b:current_syntax = "solstice"