forked from solstice/solstice
Compare commits
54 Commits
631b587d07
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 02ecef4ce2 | |||
| e0869d526e | |||
| cba5ec1fa2 | |||
| 908af13d8f | |||
| 10046703ed | |||
| ebfd1d5045 | |||
| 1e0abcc0b4 | |||
| c7bd6e7766 | |||
| 68f5868538 | |||
| 692dd6b0db | |||
| 8087a8150e | |||
| 53908d29e2 | |||
| effad2920f | |||
| ac13b7a0ae | |||
| 8b40dbd563 | |||
| 0cf63b034f | |||
| ba6ec79a10 | |||
| f261a1cd0e | |||
| 00bf654882 | |||
| 591adf79a4 | |||
| c7d4a7700e | |||
| d0d1dc7465 | |||
| f8afa2f564 | |||
| 7a81a47986 | |||
| f127c2f5ab | |||
| 23041c041a | |||
| 0bb3741c66 | |||
| af97f1b712 | |||
| dfe37de5c0 | |||
| 5d9cb02e7e | |||
| 547488964a | |||
| f0692eb940 | |||
| 67ea6cc5fc | |||
| 36030f01a2 | |||
| f384e19c06 | |||
| d24462f844 | |||
| 4351821d30 | |||
| 78f974e189 | |||
| 1dedb30a87 | |||
| 2e7b5b7480 | |||
| 1cf995f7ac | |||
| 605d0a87b1 | |||
| 16569d7355 | |||
| fd08b7cdb7 | |||
| 5841a7a999 | |||
| a2fc138ba1 | |||
| 9b55b509f5 | |||
| f694f50d70 | |||
| 5b61a11f00 | |||
| 00d6ed83fb | |||
| 6988f314b0 | |||
| 70dc5eb5a0 | |||
| 1e3bd6c601 | |||
| f66464a7cc |
18
Makefile
18
Makefile
@@ -1,5 +1,9 @@
|
||||
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
|
||||
|
||||
BUILD_DIR = build
|
||||
@@ -10,7 +14,7 @@ PREFIX ?= /usr/local
|
||||
BINDIR = $(PREFIX)/bin
|
||||
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))
|
||||
TARGET = solstice
|
||||
|
||||
@@ -29,6 +33,9 @@ install: $(TARGET)
|
||||
install -d $(LIBDIR)
|
||||
cp -r libs/* $(LIBDIR)/solstice
|
||||
|
||||
static: $(OBJS)
|
||||
$(CXX) $(OBJS) $(GROUND_STATIC) -o $(TARGET)
|
||||
|
||||
$(BUILD_DIR)/solstice.tar.gz: $(TARGET) $(LIBS_DIR)
|
||||
mkdir -p $(BUILD_DIR)/pkg/bin $(BUILD_DIR)/pkg/lib/
|
||||
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
|
||||
|
||||
$(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:
|
||||
rm -rf $(BUILD_DIR) $(TARGET)
|
||||
|
||||
.PHONY: all clean
|
||||
run: $(TARGET)
|
||||
./$(TARGET)
|
||||
|
||||
.PHONY: all clean run
|
||||
|
||||
37
libs/collections.sols
Normal file
37
libs/collections.sols
Normal 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"
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -1,5 +1,18 @@
|
||||
def file_Read(string file) string {}
|
||||
def file_Write(string file, string content) {}
|
||||
struct File {
|
||||
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 {
|
||||
extern "fileio"
|
||||
|
||||
28
libs/strings.sols
Normal file
28
libs/strings.sols
Normal 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"
|
||||
}
|
||||
@@ -9,7 +9,13 @@ void addVariableToScope(SolsScope* scope, const char* name, SolsType type) {
|
||||
strncpy(s->id, name, sizeof(s->id) - 1);
|
||||
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);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
71
src/include/list.h
Normal file
71
src/include/list.h
Normal 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
|
||||
77
src/interactive/interactive.c
Normal file
77
src/interactive/interactive.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/interactive/interactive.h
Normal file
26
src/interactive/interactive.h
Normal 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
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "SolsLiteral.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...) {
|
||||
va_list args;
|
||||
@@ -49,3 +51,28 @@ void freeSolsLiteral(SolsLiteral* lit) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,4 +43,7 @@ ResultType(SolsLiteral, charptr) createSolsLiteral(SolsLiteralType type, ...);
|
||||
// Frees a SolsLiteral. Primarily concerned with freeing .as.stringv
|
||||
void freeSolsLiteral(SolsLiteral* lit);
|
||||
|
||||
// Prints a SolsLiteral
|
||||
void printSolsLiteral(SolsLiteral* lit);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,20 @@
|
||||
#include "SolsLiteral.h"
|
||||
|
||||
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;
|
||||
|
||||
typedef char* charptr;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "SolsType.h"
|
||||
#include "lexer.h"
|
||||
#include "../include/error.h"
|
||||
#include "../include/estr.h"
|
||||
#include <groundvm.h>
|
||||
@@ -10,10 +9,116 @@ ResultType(SolsType, charptr) createSolsType(SolsTypeType in) {
|
||||
if (ptr == NULL) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
*/
|
||||
|
||||
ResultType(Nothing, charptr) addChildToSolsType(SolsType* type, SolsType child, const char* name) {
|
||||
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) {
|
||||
case STT_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"));
|
||||
}
|
||||
case STT_OBJECT: {
|
||||
// FIXME Do this later
|
||||
return Error(GroundArg, charptr, "FIXME");
|
||||
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_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?");
|
||||
}
|
||||
|
||||
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("}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
#include "../include/nothing.h"
|
||||
|
||||
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;
|
||||
|
||||
// Definition of charptr for Result() and ResultType() macros
|
||||
typedef char* charptr;
|
||||
|
||||
struct SolsTypeField;
|
||||
struct SolsNode; // for generic struct
|
||||
|
||||
// Holds type information for a struct, object or function.
|
||||
// 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
|
||||
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
|
||||
struct SolsType* returnType;
|
||||
|
||||
@@ -62,6 +69,18 @@ typedef struct SolsType {
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
} 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;
|
||||
|
||||
// Assists with holding child types in the SolsType struct.
|
||||
@@ -80,6 +99,10 @@ Result(SolsType, charptr);
|
||||
// Failure: char* detailing what went wrong (usually memory failure)
|
||||
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);
|
||||
|
||||
// Adds a child SolsType to a given SolsType.
|
||||
@@ -93,8 +116,10 @@ ResultType(SolsType, charptr) copySolsType(SolsType* type);
|
||||
|
||||
Result(GroundArg, charptr);
|
||||
|
||||
struct SolsScope;
|
||||
|
||||
// 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
|
||||
void freeSolsType(SolsType* type);
|
||||
@@ -102,4 +127,9 @@ void freeSolsType(SolsType* type);
|
||||
// Compares two SolsTypes
|
||||
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
|
||||
|
||||
@@ -15,11 +15,23 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
|
||||
{"return", STT_KW_RETURN},
|
||||
{"use", STT_KW_USE},
|
||||
{"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},
|
||||
{"new", STT_KW_NEW},
|
||||
{"as", STT_KW_AS},
|
||||
{"sizeof", STT_KW_SIZEOF},
|
||||
{"pragma", STT_KW_PRAGMA},
|
||||
{"{", STT_OPEN_CURLY},
|
||||
{"}", STT_CLOSE_CURLY},
|
||||
{"(", STT_OPEN_PAREN},
|
||||
{")", STT_CLOSE_PAREN},
|
||||
{"[", STT_OPEN_SQUARE},
|
||||
{"]", STT_CLOSE_SQUARE},
|
||||
{"+", STT_OP_ADD},
|
||||
{"-", STT_OP_SUB},
|
||||
{"*", STT_OP_MUL},
|
||||
@@ -62,6 +74,8 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
|
||||
{"subtracts", STT_OP_SUBTO},
|
||||
{"multiplies", STT_OP_MULTO},
|
||||
{"divides", STT_OP_DIVTO},
|
||||
{"class", STT_KW_STRUCT},
|
||||
{"compilerpleasedothisforme", STT_KW_PRAGMA}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -584,6 +598,8 @@ ResultType(Nothing, charptr) lex(SolsLexer* lexer) {
|
||||
case ',':
|
||||
case ':':
|
||||
case ';':
|
||||
case '[':
|
||||
case ']':
|
||||
case '\n':
|
||||
{
|
||||
ResultType(Nothing, charptr) res = identifyAndAdd(lexer, &buf, &lineNum, ¤tLine, chr.as.success, &skipDelimiter);
|
||||
|
||||
54
src/main.c
54
src/main.c
@@ -7,13 +7,19 @@
|
||||
#include "include/estr.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
#include <groundvm.h>
|
||||
|
||||
extern bool groundDisableTypeChecking;
|
||||
|
||||
char* fileDir = NULL;
|
||||
|
||||
typedef enum SolsAction {
|
||||
SA_PRINT, SA_EXEC, SA_BYTECODE, SA_COMPILE, SA_EXIT, SA_EXITOK
|
||||
} SolsAction;
|
||||
@@ -91,41 +97,12 @@ Args parseArgs(int argc, char** argv) {
|
||||
return args;
|
||||
}
|
||||
|
||||
char* getFileContents(const char* filename) {
|
||||
// https://stackoverflow.com/questions/3747086/reading-the-whole-text-file-into-a-char-array-in-c
|
||||
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;
|
||||
}
|
||||
// Use ground's getFileContents
|
||||
char* getFileContents(const char* filename);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
groundDisableTypeChecking = true;
|
||||
|
||||
Args args = parseArgs(argc, argv);
|
||||
|
||||
if (args.action == SA_EXIT) {
|
||||
@@ -135,6 +112,17 @@ int main(int argc, char** argv) {
|
||||
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);
|
||||
|
||||
if (fileContents == NULL) {
|
||||
|
||||
@@ -68,3 +68,198 @@ SolsNode deepCopySolsNode(SolsNode node) {
|
||||
}
|
||||
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");
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,21 @@
|
||||
#include "../lexer/SolsToken.h"
|
||||
|
||||
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;
|
||||
|
||||
struct SolsNode;
|
||||
@@ -59,6 +73,8 @@ ResultType(SolsNode, charptr) createSolsNode(SolsNodeType type, ...);
|
||||
// Failure: char* detailing what went wrong (usually memory failure)
|
||||
ResultType(Nothing, charptr) addChildToSolsNode(SolsNode* parent, SolsNode child);
|
||||
|
||||
void printSolsNode(SolsNode* node);
|
||||
|
||||
// Deep copies a SolsNode
|
||||
SolsNode deepCopySolsNode(SolsNode node);
|
||||
|
||||
|
||||
1005
src/parser/parser.c
1005
src/parser/parser.c
File diff suppressed because it is too large
Load Diff
11
tests/enum.sols
Normal file
11
tests/enum.sols
Normal 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
46
tests/generics.sols
Normal 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
23
tests/nested-object.sols
Normal 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
7
tests/sizeof.sols
Normal file
@@ -0,0 +1,7 @@
|
||||
puts sizeof "dingleing"
|
||||
|
||||
struct MyStruct {
|
||||
size = 32
|
||||
}
|
||||
|
||||
puts sizeof new MyStruct
|
||||
@@ -1,18 +1,42 @@
|
||||
use io
|
||||
struct Person {
|
||||
protected name = ""
|
||||
private age = 0
|
||||
|
||||
struct dingus {
|
||||
x = 5
|
||||
y = "dingus"
|
||||
def greet() string {
|
||||
return "Hello, " + self.name + "!"
|
||||
}
|
||||
|
||||
e = new dingus
|
||||
puts e
|
||||
puts dingus
|
||||
def dance() string {
|
||||
return "Dancing..."
|
||||
}
|
||||
|
||||
puts e.x
|
||||
println(e.y)
|
||||
constructor(string name, int age) {
|
||||
self.name = name
|
||||
self.age = age
|
||||
}
|
||||
|
||||
e.x = 7
|
||||
e.y = "heheheha"
|
||||
puts e.x
|
||||
println(e.y)
|
||||
destructor {
|
||||
// We don't need to do anything here.
|
||||
}
|
||||
|
||||
duplicator {
|
||||
puts "Duplicator called!"
|
||||
// Also nothing here
|
||||
}
|
||||
|
||||
as string {
|
||||
return "dingus"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
max = Person("Max", 16)
|
||||
|
||||
puts max
|
||||
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)
|
||||
|
||||
max.dance()
|
||||
|
||||
@@ -5,37 +5,41 @@ if exists("b:current_syntax")
|
||||
endif
|
||||
|
||||
" Keywords
|
||||
syn keyword solsticeConditional if
|
||||
syn keyword solsticeRepeat while
|
||||
syn keyword solsticeKeyword def struct return use
|
||||
syn keyword solsticeType int string bool double char
|
||||
syn keyword solsticeBoolean true false
|
||||
syn keyword solsKeyword puts if while def lambda return use struct new private protected constructor destructor duplicator as ground
|
||||
syn keyword solsBool true false
|
||||
|
||||
" Built-in functions
|
||||
syn keyword solsticeBuiltin puts print println input
|
||||
" Types
|
||||
syn keyword solsType int double string char bool fun template object
|
||||
|
||||
" Data Types
|
||||
syn match solsticeNumber "\d\+\(\.\d\+\)\="
|
||||
syn region solsticeString start=/"/ end=/"/
|
||||
syn match solsticeCharacter /'[^']'/
|
||||
" Strings and chars
|
||||
syn region solsString start=/"/ skip=/\\"/ end=/"/
|
||||
syn region solsChar start=/'/ skip=/\\'/ end=/'/
|
||||
|
||||
" Numbers
|
||||
syn match solsFloat /\<[0-9]\+\.[0-9]*\>/
|
||||
syn match solsInt /\<[0-9]\+\>/
|
||||
|
||||
" Operators
|
||||
syn match solsticeOperator "==\|!=\|>=\|<=\|++\|--\|+\=\|-\=\|\*=\|\/="
|
||||
syn match solsticeOperator "[><=+\-*/]"
|
||||
syn match solsOperator /+\|-\|\*\|\/\|=\|!\|>\|<\|+=\|-=\|\*=\|\/=\|++\|--\|==\|!=\|>=\|<=/
|
||||
|
||||
" Delimiters
|
||||
syn match solsticeDelimiter "[{()}]"
|
||||
syn match solsDelimiter /[{}(),;\[\]]/
|
||||
|
||||
hi def link solsticeConditional Conditional
|
||||
hi def link solsticeRepeat Repeat
|
||||
hi def link solsticeKeyword Keyword
|
||||
hi def link solsticeType Type
|
||||
hi def link solsticeBoolean Boolean
|
||||
hi def link solsticeBuiltin Function
|
||||
hi def link solsticeNumber Number
|
||||
hi def link solsticeString String
|
||||
hi def link solsticeCharacter Character
|
||||
hi def link solsticeOperator Operator
|
||||
hi def link solsticeDelimiter Delimiter
|
||||
" Comments
|
||||
syn match solsComment /\/\/.*$/
|
||||
syn match solsComment /#.*$/
|
||||
|
||||
" Highlight links
|
||||
hi def link solsKeyword Keyword
|
||||
hi def link solsBool Boolean
|
||||
hi def link solsType Type
|
||||
hi def link solsString String
|
||||
hi def link solsChar Character
|
||||
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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user