mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Working on refactoring, read more
The main program segfaults, but right now I'm working on the tests, mainly.
This commit is contained in:
5
makefile
5
makefile
@@ -20,13 +20,14 @@ ifeq ($(findstring CYGWIN, $(shell uname)),CYGWIN)
|
|||||||
find . -type f -name '*.lib' -exec rm -f -r -v {} \;
|
find . -type f -name '*.lib' -exec rm -f -r -v {} \;
|
||||||
find . -type f -name '*.so' -exec rm -f -r -v {} \;
|
find . -type f -name '*.so' -exec rm -f -r -v {} \;
|
||||||
find . -empty -type d -delete
|
find . -empty -type d -delete
|
||||||
else ifeq ($(shell uname), Linux)
|
else ifeq ($(shell uname),Linux)
|
||||||
find . -type f -name '*.o' -exec rm -f -r -v {} \;
|
find . -type f -name '*.o' -exec rm -f -r -v {} \;
|
||||||
find . -type f -name '*.a' -exec rm -f -r -v {} \;
|
find . -type f -name '*.a' -exec rm -f -r -v {} \;
|
||||||
find . -type f -name '*.exe' -exec rm -f -r -v {} \;
|
find . -type f -name '*.exe' -exec rm -f -r -v {} \;
|
||||||
find . -type f -name '*.dll' -exec rm -f -r -v {} \;
|
find . -type f -name '*.dll' -exec rm -f -r -v {} \;
|
||||||
find . -type f -name '*.lib' -exec rm -f -r -v {} \;
|
find . -type f -name '*.lib' -exec rm -f -r -v {} \;
|
||||||
find . -type f -name '*.so' -exec rm -f -r -v {} \;
|
find . -type f -name '*.so' -exec rm -f -r -v {} \;
|
||||||
|
rm -rf out
|
||||||
find . -empty -type d -delete
|
find . -empty -type d -delete
|
||||||
else ifeq ($(OS),Windows_NT)
|
else ifeq ($(OS),Windows_NT)
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
@@ -34,4 +35,4 @@ else
|
|||||||
@echo "Deletion failed - what platform is this?"
|
@echo "Deletion failed - what platform is this?"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
rebuild: clean all
|
rebuild: clean all
|
||||||
|
|||||||
@@ -855,7 +855,7 @@ static unsigned char* collateCompilerHeaderOpt(Compiler* compiler, int* size, bo
|
|||||||
case LITERAL_FUNCTION_INTERMEDIATE: {
|
case LITERAL_FUNCTION_INTERMEDIATE: {
|
||||||
//extract the compiler
|
//extract the compiler
|
||||||
Literal fn = compiler->literalCache.literals[i];
|
Literal fn = compiler->literalCache.literals[i];
|
||||||
void* fnCompiler = AS_FUNCTION(fn);
|
void* fnCompiler = AS_FUNCTION(fn).bytecode; //store the compiler here for now
|
||||||
|
|
||||||
//collate the function into bytecode (without header)
|
//collate the function into bytecode (without header)
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|||||||
@@ -335,23 +335,6 @@ void initInterpreter(Interpreter* interpreter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void freeInterpreter(Interpreter* interpreter) {
|
void freeInterpreter(Interpreter* interpreter) {
|
||||||
//since these are dynamically allocated, free them manually
|
|
||||||
for (int i = 0; i < interpreter->literalCache.count; i++) {
|
|
||||||
if (IS_ARRAY(interpreter->literalCache.literals[i]) || IS_DICTIONARY(interpreter->literalCache.literals[i]) || IS_TYPE(interpreter->literalCache.literals[i])) {
|
|
||||||
|
|
||||||
if (IS_TYPE(interpreter->literalCache.literals[i]) && AS_TYPE(interpreter->literalCache.literals[i]).capacity > 0) {
|
|
||||||
FREE_ARRAY(Literal, AS_TYPE(interpreter->literalCache.literals[i]).subtypes, AS_TYPE(interpreter->literalCache.literals[i]).capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
freeLiteral(interpreter->literalCache.literals[i]);
|
|
||||||
|
|
||||||
interpreter->literalCache.literals[i] = TO_NULL_LITERAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_FUNCTION(interpreter->literalCache.literals[i])) {
|
|
||||||
FREE_ARRAY(unsigned char, interpreter->literalCache.literals[i].as.function.ptr, interpreter->literalCache.literals[i].as.function.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
freeLiteralArray(&interpreter->literalCache);
|
freeLiteralArray(&interpreter->literalCache);
|
||||||
|
|
||||||
interpreter->scope = popScope(interpreter->scope);
|
interpreter->scope = popScope(interpreter->scope);
|
||||||
@@ -1071,7 +1054,7 @@ static bool execFnCall(Interpreter* interpreter) {
|
|||||||
freeLiteralArray(&arguments);
|
freeLiteralArray(&arguments);
|
||||||
|
|
||||||
//call the native function
|
//call the native function
|
||||||
((NativeFn) AS_FUNCTION(func) )(interpreter, &correct);
|
((NativeFn) AS_FUNCTION(func).bytecode )(interpreter, &correct);
|
||||||
|
|
||||||
freeLiteralArray(&correct);
|
freeLiteralArray(&correct);
|
||||||
return true;
|
return true;
|
||||||
@@ -1083,7 +1066,7 @@ static bool execFnCall(Interpreter* interpreter) {
|
|||||||
//init the inner interpreter manually
|
//init the inner interpreter manually
|
||||||
initLiteralArray(&inner.literalCache);
|
initLiteralArray(&inner.literalCache);
|
||||||
inner.scope = pushScope(func.as.function.scope);
|
inner.scope = pushScope(func.as.function.scope);
|
||||||
inner.bytecode = AS_FUNCTION(func);
|
inner.bytecode = AS_FUNCTION(func).bytecode;
|
||||||
inner.length = func.as.function.length;
|
inner.length = func.as.function.length;
|
||||||
inner.count = 0;
|
inner.count = 0;
|
||||||
initLiteralArray(&inner.stack);
|
initLiteralArray(&inner.stack);
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include "literal.h"
|
#include "literal.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
#include "literal_array.h"
|
||||||
|
#include "literal_dictionary.h"
|
||||||
|
|
||||||
#include "console_colors.h"
|
#include "console_colors.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -31,6 +34,16 @@ void freeLiteral(Literal literal) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ARRAY(literal)) {
|
||||||
|
freeLiteralArray(AS_ARRAY(literal));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_DICTIONARY(literal)) {
|
||||||
|
freeLiteralDictionary(AS_DICTIONARY(literal));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_IDENTIFIER(literal)) {
|
if (IS_IDENTIFIER(literal)) {
|
||||||
FREE_ARRAY(char, AS_IDENTIFIER(literal), literal.as.identifier.length);
|
FREE_ARRAY(char, AS_IDENTIFIER(literal), literal.as.identifier.length);
|
||||||
return;
|
return;
|
||||||
@@ -40,6 +53,7 @@ void freeLiteral(Literal literal) {
|
|||||||
for (int i = 0; i < AS_TYPE(literal).count; i++) {
|
for (int i = 0; i < AS_TYPE(literal).count; i++) {
|
||||||
freeLiteral(((Literal*)(AS_TYPE(literal).subtypes))[i]);
|
freeLiteral(((Literal*)(AS_TYPE(literal).subtypes))[i]);
|
||||||
}
|
}
|
||||||
|
FREE_ARRAY(Literal, AS_TYPE(literal).subtypes, AS_TYPE(literal).capacity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ typedef struct {
|
|||||||
void* dictionary;
|
void* dictionary;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
void* ptr;
|
void* bytecode;
|
||||||
void* scope;
|
void* scope;
|
||||||
int length;
|
int length;
|
||||||
} function;
|
} function;
|
||||||
@@ -78,7 +78,7 @@ typedef struct {
|
|||||||
#define AS_STRING(value) ((value).as.string.ptr)
|
#define AS_STRING(value) ((value).as.string.ptr)
|
||||||
#define AS_ARRAY(value) ((LiteralArray*)((value).as.array))
|
#define AS_ARRAY(value) ((LiteralArray*)((value).as.array))
|
||||||
#define AS_DICTIONARY(value) ((LiteralDictionary*)((value).as.dictionary))
|
#define AS_DICTIONARY(value) ((LiteralDictionary*)((value).as.dictionary))
|
||||||
#define AS_FUNCTION(value) ((value).as.function.ptr)
|
#define AS_FUNCTION(value) ((value).as.function)
|
||||||
#define AS_IDENTIFIER(value) ((value).as.identifier.ptr)
|
#define AS_IDENTIFIER(value) ((value).as.identifier.ptr)
|
||||||
#define AS_TYPE(value) ((value).as.type)
|
#define AS_TYPE(value) ((value).as.type)
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ typedef struct {
|
|||||||
#define TO_STRING_LITERAL(value, l) _toStringLiteral(value, l)
|
#define TO_STRING_LITERAL(value, l) _toStringLiteral(value, l)
|
||||||
#define TO_ARRAY_LITERAL(value) ((Literal){LITERAL_ARRAY, { .array = value }})
|
#define TO_ARRAY_LITERAL(value) ((Literal){LITERAL_ARRAY, { .array = value }})
|
||||||
#define TO_DICTIONARY_LITERAL(value) ((Literal){LITERAL_DICTIONARY, { .dictionary = value }})
|
#define TO_DICTIONARY_LITERAL(value) ((Literal){LITERAL_DICTIONARY, { .dictionary = value }})
|
||||||
#define TO_FUNCTION_LITERAL(value, l) ((Literal){LITERAL_FUNCTION, { .function.ptr = value, .function.scope = NULL, .function.length = l }})
|
#define TO_FUNCTION_LITERAL(value, l) ((Literal){LITERAL_FUNCTION, { .function.bytecode = value, .function.scope = NULL, .function.length = l }})
|
||||||
#define TO_IDENTIFIER_LITERAL(value, l) _toIdentifierLiteral(value, l)
|
#define TO_IDENTIFIER_LITERAL(value, l) _toIdentifierLiteral(value, l)
|
||||||
#define TO_TYPE_LITERAL(value, c) ((Literal){ LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
#define TO_TYPE_LITERAL(value, c) ((Literal){ LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
||||||
|
|
||||||
|
|||||||
@@ -20,15 +20,7 @@ int pushLiteralArray(LiteralArray* array, Literal literal) {
|
|||||||
array->literals = GROW_ARRAY(Literal, array->literals, oldCapacity, array->capacity);
|
array->literals = GROW_ARRAY(Literal, array->literals, oldCapacity, array->capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if it's a string or an identifier, make a local copy
|
array->literals[array->count] = copyLiteral(literal);
|
||||||
if (IS_STRING(literal)) {
|
|
||||||
literal = TO_STRING_LITERAL(copyString(AS_STRING(literal), strlen( AS_STRING(literal) )), strlen( AS_STRING(literal) ));
|
|
||||||
}
|
|
||||||
if (IS_IDENTIFIER(literal)) {
|
|
||||||
literal = TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(literal), strlen( AS_IDENTIFIER(literal) )), strlen( AS_IDENTIFIER(literal) ));
|
|
||||||
}
|
|
||||||
|
|
||||||
array->literals[array->count] = literal;
|
|
||||||
return array->count++;
|
return array->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,4 +67,4 @@ void printLiteralArray(LiteralArray* array, const char* delim) {
|
|||||||
printLiteral(array->literals[i]);
|
printLiteral(array->literals[i]);
|
||||||
printf("%s", delim);
|
printf("%s", delim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,51 +8,12 @@
|
|||||||
|
|
||||||
//util functions
|
//util functions
|
||||||
static void setEntryValues(_entry* entry, Literal key, Literal value) {
|
static void setEntryValues(_entry* entry, Literal key, Literal value) {
|
||||||
//free the original string/identifier and overwrite it
|
//much simpler now
|
||||||
if (IS_STRING(entry->key) || IS_IDENTIFIER(entry->key)) {
|
freeLiteral(entry->key);
|
||||||
freeLiteral(entry->key);
|
entry->key = copyLiteral(key);
|
||||||
}
|
|
||||||
|
|
||||||
//take ownership of the copied string
|
|
||||||
if (IS_STRING(key)) {
|
|
||||||
entry->key = TO_STRING_LITERAL( copyString(AS_STRING(key), strlen(AS_STRING(key)) ), strlen(AS_STRING(key)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//OR take ownership of the copied identifier
|
|
||||||
else if (IS_IDENTIFIER(key)) {
|
|
||||||
entry->key = TO_IDENTIFIER_LITERAL( copyString(AS_IDENTIFIER(key), strlen( AS_IDENTIFIER(key))), strlen(AS_IDENTIFIER(key)) );
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
freeLiteral(entry->key); //for types
|
|
||||||
entry->key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
//values
|
|
||||||
freeLiteral(entry->value);
|
freeLiteral(entry->value);
|
||||||
|
entry->value = copyLiteral(value);
|
||||||
//take ownership of the copied string
|
|
||||||
if (IS_STRING(value)) {
|
|
||||||
char* buffer = ALLOCATE(char, strlen(AS_STRING(value)) + 1);
|
|
||||||
strncpy(buffer, AS_STRING(value), strlen(AS_STRING(value)));
|
|
||||||
buffer[strlen(AS_STRING(value))] = '\0';
|
|
||||||
entry->value = TO_STRING_LITERAL(buffer, strlen(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
//OR take ownership of the copied function
|
|
||||||
else if (IS_FUNCTION(value)) {
|
|
||||||
unsigned char* buffer = ALLOCATE(unsigned char, value.as.function.length);
|
|
||||||
memcpy(buffer, AS_FUNCTION(value), value.as.function.length);
|
|
||||||
|
|
||||||
entry->value = TO_FUNCTION_LITERAL(buffer, value.as.function.length);
|
|
||||||
|
|
||||||
//save the scope
|
|
||||||
entry->value.as.function.scope = value.as.function.scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
entry->value = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static _entry* getEntryArray(_entry* array, int capacity, Literal key, unsigned int hash, bool mustExist) {
|
static _entry* getEntryArray(_entry* array, int capacity, Literal key, unsigned int hash, bool mustExist) {
|
||||||
@@ -123,21 +84,6 @@ static bool setEntryArray(_entry** dictionaryHandle, int* capacityPtr, int conta
|
|||||||
|
|
||||||
_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false);
|
_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false);
|
||||||
|
|
||||||
//if it's a string or an identifier, make a local copy
|
|
||||||
if (IS_STRING(key)) {
|
|
||||||
key = TO_STRING_LITERAL(copyString(AS_STRING(key), strlen(AS_STRING(key)) ), strlen(AS_STRING(key)));
|
|
||||||
}
|
|
||||||
if (IS_IDENTIFIER(key)) {
|
|
||||||
key = TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(key), strlen(AS_IDENTIFIER(key)) ), strlen(AS_IDENTIFIER(key)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_STRING(value)) {
|
|
||||||
key = TO_STRING_LITERAL(copyString(AS_STRING(value), strlen(AS_STRING(value)) ), strlen(AS_STRING(value)));
|
|
||||||
}
|
|
||||||
if (IS_IDENTIFIER(value)) {
|
|
||||||
key = TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(value), strlen(AS_IDENTIFIER(value)) ), strlen(AS_IDENTIFIER(value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//true = contains increase
|
//true = contains increase
|
||||||
if (IS_NULL(entry->key)) {
|
if (IS_NULL(entry->key)) {
|
||||||
setEntryValues(entry, key, value);
|
setEntryValues(entry, key, value);
|
||||||
@@ -237,4 +183,4 @@ bool existsLiteralDictionary(LiteralDictionary* dictionary, Literal key) {
|
|||||||
//null & not tombstoned
|
//null & not tombstoned
|
||||||
_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, hashLiteral(key), false);
|
_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, hashLiteral(key), false);
|
||||||
return !(IS_NULL(entry->key) && IS_NULL(entry->value));
|
return !(IS_NULL(entry->key) && IS_NULL(entry->value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,86 @@
|
|||||||
|
|
||||||
#include "literal_array.h"
|
#include "literal_array.h"
|
||||||
#include "literal_dictionary.h"
|
#include "literal_dictionary.h"
|
||||||
|
#include "scope.h"
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "console_colors.h"
|
#include "console_colors.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
Literal copyLiteral(Literal original) {
|
||||||
|
switch(original.type) {
|
||||||
|
case LITERAL_NULL:
|
||||||
|
case LITERAL_BOOLEAN:
|
||||||
|
case LITERAL_INTEGER:
|
||||||
|
case LITERAL_FLOAT:
|
||||||
|
//no copying needed
|
||||||
|
return original;
|
||||||
|
|
||||||
|
case LITERAL_STRING: {
|
||||||
|
return TO_STRING_LITERAL(copyString(AS_STRING(original), strlen(AS_STRING(original)) ), strlen(AS_STRING(original)));
|
||||||
|
}
|
||||||
|
|
||||||
|
case LITERAL_ARRAY: {
|
||||||
|
LiteralArray* array = ALLOCATE(LiteralArray, 1);
|
||||||
|
initLiteralArray(array);
|
||||||
|
|
||||||
|
//copy each element
|
||||||
|
for (int i = 0; i < AS_ARRAY(original)->count; i++) {
|
||||||
|
pushLiteralArray(array, copyLiteral(AS_ARRAY(original)->literals[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TO_ARRAY_LITERAL(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
case LITERAL_DICTIONARY: {
|
||||||
|
LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1);
|
||||||
|
initLiteralDictionary(dictionary);
|
||||||
|
|
||||||
|
//copy each entry
|
||||||
|
for (int i = 0; i < AS_DICTIONARY(original)->capacity; i++) {
|
||||||
|
if ( !IS_NULL(AS_DICTIONARY(original)->entries[i].key) ) {
|
||||||
|
setLiteralDictionary(dictionary, copyLiteral(AS_DICTIONARY(original)->entries[i].key), copyLiteral(AS_DICTIONARY(original)->entries[i].value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TO_DICTIONARY_LITERAL(dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
case LITERAL_FUNCTION: {
|
||||||
|
unsigned char* buffer = ALLOCATE(unsigned char, AS_FUNCTION(original).length);
|
||||||
|
memcpy(buffer, AS_FUNCTION(original).bytecode, AS_FUNCTION(original).length);
|
||||||
|
|
||||||
|
Literal literal = TO_FUNCTION_LITERAL(buffer, AS_FUNCTION(original).length);
|
||||||
|
AS_FUNCTION(literal).scope = copyScope(AS_FUNCTION(original).scope);
|
||||||
|
|
||||||
|
return literal;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LITERAL_IDENTIFIER: {
|
||||||
|
return TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(original), strlen(AS_IDENTIFIER(original)) ), strlen(AS_IDENTIFIER(original)));
|
||||||
|
}
|
||||||
|
|
||||||
|
case LITERAL_TYPE: {
|
||||||
|
Literal lit = TO_TYPE_LITERAL(AS_TYPE(original).typeOf, AS_TYPE(original).constant);
|
||||||
|
|
||||||
|
for (int i = 0; i < AS_TYPE(original).count; i++) {
|
||||||
|
TYPE_PUSH_SUBTYPE(&lit, copyLiteral( ((Literal*)(AS_TYPE(original).subtypes))[i] ));
|
||||||
|
}
|
||||||
|
|
||||||
|
return lit;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LITERAL_FUNCTION_NATIVE:
|
||||||
|
//no copying possible
|
||||||
|
return original;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, ERROR "ERROR: Can't copy that literal type: %d\n" RESET, original.type);
|
||||||
|
return TO_NULL_LITERAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char* copyString(char* original, int length) {
|
char* copyString(char* original, int length) {
|
||||||
//make a local copy of the char array
|
//make a local copy of the char array
|
||||||
char* buffer = ALLOCATE(char, length + 1);
|
char* buffer = ALLOCATE(char, length + 1);
|
||||||
@@ -495,4 +569,4 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) {
|
|||||||
//should never be seen
|
//should never be seen
|
||||||
fprintf(stderr, ERROR "[internal] Unrecognized literal type in print: %d\n" RESET, literal.type);
|
fprintf(stderr, ERROR "[internal] Unrecognized literal type in print: %d\n" RESET, literal.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "literal.h"
|
#include "literal.h"
|
||||||
|
|
||||||
|
Literal copyLiteral(Literal original);
|
||||||
char* copyString(char* original, int length);
|
char* copyString(char* original, int length);
|
||||||
bool literalsAreEqual(Literal lhs, Literal rhs);
|
bool literalsAreEqual(Literal lhs, Literal rhs);
|
||||||
int hashLiteral(Literal lit);
|
int hashLiteral(Literal lit);
|
||||||
@@ -9,4 +10,3 @@ int hashLiteral(Literal lit);
|
|||||||
void printLiteral(Literal literal);
|
void printLiteral(Literal literal);
|
||||||
void printLiteralCustom(Literal literal, void (printFn)(const char*));
|
void printLiteralCustom(Literal literal, void (printFn)(const char*));
|
||||||
|
|
||||||
//TODO: copy literal (to be used in dictionaries and arrays, as well)
|
|
||||||
|
|||||||
@@ -5,12 +5,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static int allocatedMemoryCount = 0;
|
|
||||||
|
|
||||||
void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
|
void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
|
||||||
allocatedMemoryCount -= oldSize;
|
|
||||||
allocatedMemoryCount += newSize;
|
|
||||||
|
|
||||||
if (newSize == 0) {
|
if (newSize == 0) {
|
||||||
free(pointer);
|
free(pointer);
|
||||||
|
|
||||||
@@ -27,6 +22,3 @@ void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
|
|||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getAllocatedMemoryCount() {
|
|
||||||
return allocatedMemoryCount;
|
|
||||||
}
|
|
||||||
@@ -12,4 +12,3 @@
|
|||||||
|
|
||||||
void* reallocate(void* pointer, size_t oldSize, size_t newSize);
|
void* reallocate(void* pointer, size_t oldSize, size_t newSize);
|
||||||
|
|
||||||
int getAllocatedMemoryCount();
|
|
||||||
@@ -153,10 +153,6 @@ void repl() {
|
|||||||
initInterpreter(&interpreter);
|
initInterpreter(&interpreter);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (command.verbose) {
|
|
||||||
//print the used memory footprint
|
|
||||||
printf("%d ", getAllocatedMemoryCount());
|
|
||||||
}
|
|
||||||
printf("> ");
|
printf("> ");
|
||||||
fgets(input, size, stdin);
|
fgets(input, size, stdin);
|
||||||
|
|
||||||
|
|||||||
@@ -128,6 +128,30 @@ Scope* popScope(Scope* scope) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scope* copyScope(Scope* original) {
|
||||||
|
Scope* scope = ALLOCATE(Scope, 1);
|
||||||
|
scope->ancestor = original->ancestor;
|
||||||
|
initLiteralDictionary(&scope->variables);
|
||||||
|
initLiteralDictionary(&scope->types);
|
||||||
|
|
||||||
|
//tick up all scope reference counts
|
||||||
|
scope->references = 0;
|
||||||
|
for (Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) {
|
||||||
|
ptr->references++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy the contents of the dictionaries
|
||||||
|
for (int i = 0; i < original->variables.capacity; i++) {
|
||||||
|
setLiteralDictionary(&scope->variables, original->variables.entries[i].key, original->variables.entries[i].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < original->variables.capacity; i++) {
|
||||||
|
setLiteralDictionary(&scope->types, original->types.entries[i].key, original->types.entries[i].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
//returns false if error
|
//returns false if error
|
||||||
bool declareScopeVariable(Scope* scope, Literal key, Literal type) {
|
bool declareScopeVariable(Scope* scope, Literal key, Literal type) {
|
||||||
//don't redefine a variable within this scope
|
//don't redefine a variable within this scope
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ typedef struct Scope {
|
|||||||
|
|
||||||
Scope* pushScope(Scope* scope);
|
Scope* pushScope(Scope* scope);
|
||||||
Scope* popScope(Scope* scope);
|
Scope* popScope(Scope* scope);
|
||||||
|
Scope* copyScope(Scope* original);
|
||||||
|
|
||||||
//returns false if error
|
//returns false if error
|
||||||
bool declareScopeVariable(Scope* scope, Literal key, Literal type);
|
bool declareScopeVariable(Scope* scope, Literal key, Literal type);
|
||||||
@@ -21,4 +22,4 @@ bool isDelcaredScopeVariable(Scope* scope, Literal key);
|
|||||||
bool setScopeVariable(Scope* scope, Literal key, Literal value, bool constCheck);
|
bool setScopeVariable(Scope* scope, Literal key, Literal value, bool constCheck);
|
||||||
bool getScopeVariable(Scope* scope, Literal key, Literal* value);
|
bool getScopeVariable(Scope* scope, Literal key, Literal* value);
|
||||||
|
|
||||||
Literal getScopeType(Scope* scope, Literal key);
|
Literal getScopeType(Scope* scope, Literal key);
|
||||||
|
|||||||
@@ -9,11 +9,17 @@ TARGETS = $(filter-out $(wildcard ../source/*main.c),$(wildcard ../source/*.c))
|
|||||||
TESTS = $(wildcard *.c)
|
TESTS = $(wildcard *.c)
|
||||||
OBJ = $(addprefix $(ODIR)/,$(TARGETS:../source/%.c=%.o)) $(addprefix $(ODIR)/,$(TESTS:.c=.o))
|
OBJ = $(addprefix $(ODIR)/,$(TARGETS:../source/%.c=%.o)) $(addprefix $(ODIR)/,$(TESTS:.c=.o))
|
||||||
|
|
||||||
|
.PRECIOUS: $(TESTS:%.c=../$(OUTDIR)/%.exe)
|
||||||
|
|
||||||
all: $(OBJ) $(TESTS:%.c=../$(OUTDIR)/%.exe)
|
all: $(OBJ) $(TESTS:%.c=../$(OUTDIR)/%.exe)
|
||||||
|
|
||||||
../$(OUTDIR)/%.exe: $(ODIR)/%.o
|
../$(OUTDIR)/%.exe: $(ODIR)/%.o
|
||||||
@$(CC) -o $@ $< $(TARGETS:../source/%.c=$(ODIR)/%.o) $(CFLAGS) $(LIBS)
|
@$(CC) -o $@ $< $(TARGETS:../source/%.c=$(ODIR)/%.o) $(CFLAGS) $(LIBS)
|
||||||
$@
|
ifeq ($(shell uname),Linux)
|
||||||
|
valgrind $@
|
||||||
|
else
|
||||||
|
@echo please run these tests with valgrind on linux
|
||||||
|
endif
|
||||||
|
|
||||||
$(OBJ): | $(ODIR)
|
$(OBJ): | $(ODIR)
|
||||||
|
|
||||||
@@ -29,4 +35,4 @@ $(ODIR)/%.o: ../source/%.c
|
|||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(ODIR)
|
$(RM) $(ODIR)
|
||||||
|
|||||||
@@ -49,12 +49,6 @@ int main() {
|
|||||||
freeLiteral(literal);
|
freeLiteral(literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
//check allocated memory
|
|
||||||
if (getAllocatedMemoryCount() != 0) {
|
|
||||||
fprintf(stderr, ERROR "ERROR: Dangling memory detected: %d byes\n" RESET, getAllocatedMemoryCount());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(NOTICE "All good\n" RESET);
|
printf(NOTICE "All good\n" RESET);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,12 +67,6 @@ int main() {
|
|||||||
freeLiteralArray(&array);
|
freeLiteralArray(&array);
|
||||||
}
|
}
|
||||||
|
|
||||||
//check allocated memory
|
|
||||||
if (getAllocatedMemoryCount() != 0) {
|
|
||||||
fprintf(stderr, ERROR "ERROR: Dangling memory detected: %d byes\n" RESET, getAllocatedMemoryCount());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(NOTICE "All good\n" RESET);
|
printf(NOTICE "All good\n" RESET);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ int main() {
|
|||||||
int* integer = ALLOCATE(int, 1);
|
int* integer = ALLOCATE(int, 1);
|
||||||
|
|
||||||
FREE(int, integer);
|
FREE(int, integer);
|
||||||
|
|
||||||
if (getAllocatedMemoryCount() != 0) {
|
|
||||||
fprintf(stderr, ERROR "ERROR: integer failed to be allocated and freed correctly\n" RESET);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -22,11 +17,6 @@ int main() {
|
|||||||
int* array = ALLOCATE(int, 10);
|
int* array = ALLOCATE(int, 10);
|
||||||
|
|
||||||
FREE_ARRAY(int, array, 10);
|
FREE_ARRAY(int, array, 10);
|
||||||
|
|
||||||
if (getAllocatedMemoryCount() != 0) {
|
|
||||||
fprintf(stderr, ERROR "ERROR: integer array failed to be allocated and freed correctly\n" RESET);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -36,11 +26,6 @@ int main() {
|
|||||||
|
|
||||||
FREE_ARRAY(int, array1, 10);
|
FREE_ARRAY(int, array1, 10);
|
||||||
FREE_ARRAY(int, array2, 10);
|
FREE_ARRAY(int, array2, 10);
|
||||||
|
|
||||||
if (getAllocatedMemoryCount() != 0) {
|
|
||||||
fprintf(stderr, ERROR "ERROR: integer array failed to be allocated and freed correctly\n" RESET);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(NOTICE "All good\n" RESET);
|
printf(NOTICE "All good\n" RESET);
|
||||||
|
|||||||
Reference in New Issue
Block a user