diff --git a/makefile b/makefile index 9420ee9..a4387a5 100644 --- a/makefile +++ b/makefile @@ -10,10 +10,10 @@ all: $(TOY_OUTDIR) repl #repl builds repl: $(TOY_OUTDIR) library - $(MAKE) -C repl + $(MAKE) -j8 -C repl repl-static: $(TOY_OUTDIR) static - $(MAKE) -C repl + $(MAKE) -j8 -C repl repl-release: clean $(TOY_OUTDIR) library-release $(MAKE) -C repl release diff --git a/source/toy_common.h b/source/toy_common.h index dad72cf..cc5905d 100644 --- a/source/toy_common.h +++ b/source/toy_common.h @@ -6,7 +6,7 @@ #define TOY_VERSION_MAJOR 0 #define TOY_VERSION_MINOR 8 -#define TOY_VERSION_PATCH 2 +#define TOY_VERSION_PATCH 3 #define TOY_VERSION_BUILD __DATE__ " " __TIME__ //platform-specific specifications diff --git a/source/toy_compiler.c b/source/toy_compiler.c index 38786fb..7da1992 100644 --- a/source/toy_compiler.c +++ b/source/toy_compiler.c @@ -1167,7 +1167,7 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size case TOY_LITERAL_FUNCTION_INTERMEDIATE: { //extract the compiler Toy_Literal fn = compiler->literalCache.literals[i]; - void* fnCompiler = TOY_AS_FUNCTION(fn).bytecode; //store the compiler here for now + void* fnCompiler = TOY_AS_FUNCTION(fn).inner.bytecode; //store the compiler here for now //collate the function into bytecode (without header) int size = 0; diff --git a/source/toy_interpreter.c b/source/toy_interpreter.c index 3994b32..3c21dff 100644 --- a/source/toy_interpreter.c +++ b/source/toy_interpreter.c @@ -1254,8 +1254,8 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter //init the inner interpreter manually Toy_initLiteralArray(&inner.literalCache); inner.scope = Toy_pushScope(func.as.function.scope); - inner.bytecode = TOY_AS_FUNCTION(func).bytecode; - inner.length = TOY_AS_FUNCTION(func).length; + inner.bytecode = TOY_AS_FUNCTION(func).inner.bytecode; + inner.length = TOY_AS_FUNCTION_BYTECODE_LENGTH(func); inner.count = 0; inner.codeStart = -1; inner.depth = interpreter->depth + 1; diff --git a/source/toy_literal.c b/source/toy_literal.c index bde9c85..35be37b 100644 --- a/source/toy_literal.c +++ b/source/toy_literal.c @@ -58,7 +58,7 @@ void Toy_freeLiteral(Toy_Literal literal) { if (TOY_IS_FUNCTION(literal)) { Toy_popScope(TOY_AS_FUNCTION(literal).scope); TOY_AS_FUNCTION(literal).scope = NULL; - TOY_FREE_ARRAY(unsigned char, TOY_AS_FUNCTION(literal).bytecode, TOY_AS_FUNCTION(literal).length); + TOY_FREE_ARRAY(unsigned char, TOY_AS_FUNCTION(literal).inner.bytecode, TOY_AS_FUNCTION_BYTECODE_LENGTH(literal)); } if (TOY_IS_TYPE(literal)) { @@ -84,11 +84,11 @@ bool Toy_private_isTruthy(Toy_Literal x) { } Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr) { - return ((Toy_Literal){TOY_LITERAL_STRING, { .string.ptr = ptr }}); + return ((Toy_Literal){{ .string.ptr = ptr },TOY_LITERAL_STRING, 0}); } Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr) { - return ((Toy_Literal){TOY_LITERAL_IDENTIFIER,{ .identifier.ptr = ptr, .identifier.hash = hashString(Toy_toCString(ptr), Toy_lengthRefString(ptr)) }}); + return ((Toy_Literal){{ .identifier.ptr = ptr, .identifier.hash = hashString(Toy_toCString(ptr), Toy_lengthRefString(ptr)) },TOY_LITERAL_IDENTIFIER, 0}); } Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype) { @@ -145,10 +145,10 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { } case TOY_LITERAL_FUNCTION: { - unsigned char* buffer = TOY_ALLOCATE(unsigned char, TOY_AS_FUNCTION(original).length); - memcpy(buffer, TOY_AS_FUNCTION(original).bytecode, TOY_AS_FUNCTION(original).length); + unsigned char* buffer = TOY_ALLOCATE(unsigned char, TOY_AS_FUNCTION_BYTECODE_LENGTH(original)); + memcpy(buffer, TOY_AS_FUNCTION(original).inner.bytecode, TOY_AS_FUNCTION_BYTECODE_LENGTH(original)); - Toy_Literal literal = TOY_TO_FUNCTION_LITERAL(buffer, TOY_AS_FUNCTION(original).length); + Toy_Literal literal = TOY_TO_FUNCTION_LITERAL(buffer, TOY_AS_FUNCTION_BYTECODE_LENGTH(original)); TOY_AS_FUNCTION(literal).scope = Toy_copyScope(TOY_AS_FUNCTION(original).scope); return literal; diff --git a/source/toy_literal.h b/source/toy_literal.h index 302e98e..f13d043 100644 --- a/source/toy_literal.h +++ b/source/toy_literal.h @@ -39,45 +39,49 @@ typedef enum { } Toy_LiteralType; typedef struct Toy_Literal { - Toy_LiteralType type; union { - bool boolean; - int integer; - float number; + bool boolean; //1 + int integer; //4 + float number;//4 + struct { - Toy_RefString* ptr; + Toy_RefString* ptr; //8 //string hash? - } string; + } string; //8 - void* array; - void* dictionary; + void* array; //8 + void* dictionary; //8 struct { - void* bytecode; - Toy_NativeFn native; //already a pointer - Toy_HookFn hook; //already a pointer - void* scope; - int length; - } function; + union { + void* bytecode; //8 + Toy_NativeFn native; //8 + Toy_HookFn hook; //8 + } inner; //8 + void* scope; //8 + } function; //16 struct { //for variable names - Toy_RefString* ptr; - int hash; - } identifier; + Toy_RefString* ptr; //8 + int hash; //4 + } identifier; //16 struct { - Toy_LiteralType typeOf; - bool constant; - void* subtypes; //for nested types caused by compounds - int capacity; - int count; - } type; + void* subtypes; //8 + Toy_LiteralType typeOf; //4 + unsigned char capacity; //1 + unsigned char count; //1 + bool constant; //1 + } type; //16 struct { - void* ptr; - int tag; - } opaque; - } as; + void* ptr; //8 + int tag; //4 + } opaque; //16 + } as; //16 + + Toy_LiteralType type; //4 + int bytecodeLength; //4 - shenanigans with byte alignment reduces the size of Toy_Literal } Toy_Literal; #define TOY_IS_NULL(value) ((value).type == TOY_LITERAL_NULL) @@ -101,34 +105,36 @@ typedef struct Toy_Literal { #define TOY_AS_ARRAY(value) ((Toy_LiteralArray*)((value).as.array)) #define TOY_AS_DICTIONARY(value) ((Toy_LiteralDictionary*)((value).as.dictionary)) #define TOY_AS_FUNCTION(value) ((value).as.function) -#define TOY_AS_FUNCTION_NATIVE(value) ((value).as.function.native) -#define TOY_AS_FUNCTION_HOOK(value) ((value).as.function.hook) +#define TOY_AS_FUNCTION_NATIVE(value) ((value).as.function.inner.native) +#define TOY_AS_FUNCTION_HOOK(value) ((value).as.function.inner.hook) #define TOY_AS_IDENTIFIER(value) ((value).as.identifier.ptr) #define TOY_AS_TYPE(value) ((value).as.type) #define TOY_AS_OPAQUE(value) ((value).as.opaque.ptr) -#define TOY_TO_NULL_LITERAL ((Toy_Literal){TOY_LITERAL_NULL, { .integer = 0 }}) -#define TOY_TO_BOOLEAN_LITERAL(value) ((Toy_Literal){TOY_LITERAL_BOOLEAN, { .boolean = value }}) -#define TOY_TO_INTEGER_LITERAL(value) ((Toy_Literal){TOY_LITERAL_INTEGER, { .integer = value }}) -#define TOY_TO_FLOAT_LITERAL(value) ((Toy_Literal){TOY_LITERAL_FLOAT, { .number = value }}) +#define TOY_TO_NULL_LITERAL ((Toy_Literal){{ .integer = 0 }, TOY_LITERAL_NULL, 0}) +#define TOY_TO_BOOLEAN_LITERAL(value) ((Toy_Literal){{ .boolean = value }, TOY_LITERAL_BOOLEAN, 0}) +#define TOY_TO_INTEGER_LITERAL(value) ((Toy_Literal){{ .integer = value }, TOY_LITERAL_INTEGER, 0}) +#define TOY_TO_FLOAT_LITERAL(value) ((Toy_Literal){{ .number = value }, TOY_LITERAL_FLOAT, 0}) #define TOY_TO_STRING_LITERAL(value) Toy_private_toStringLiteral(value) -#define TOY_TO_ARRAY_LITERAL(value) ((Toy_Literal){TOY_LITERAL_ARRAY, { .array = value }}) -#define TOY_TO_DICTIONARY_LITERAL(value) ((Toy_Literal){TOY_LITERAL_DICTIONARY, { .dictionary = value }}) -#define TOY_TO_FUNCTION_LITERAL(value, l) ((Toy_Literal){TOY_LITERAL_FUNCTION, { .function.bytecode = value, .function.scope = NULL, .function.length = l }}) -#define TOY_TO_FUNCTION_NATIVE_LITERAL(value) ((Toy_Literal){TOY_LITERAL_FUNCTION_NATIVE, { .function.native = value, .function.scope = NULL, .function.length = 0 }}) -#define TOY_TO_FUNCTION_HOOK_LITERAL(value) ((Toy_Literal){TOY_LITERAL_FUNCTION_HOOK, { .function.hook = value, .function.scope = NULL, .function.length = 0 }}) +#define TOY_TO_ARRAY_LITERAL(value) ((Toy_Literal){{ .array = value }, TOY_LITERAL_ARRAY, 0}) +#define TOY_TO_DICTIONARY_LITERAL(value) ((Toy_Literal){{ .dictionary = value }, TOY_LITERAL_DICTIONARY, 0}) +#define TOY_TO_FUNCTION_LITERAL(value, l) ((Toy_Literal){{ .function.inner.bytecode = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION, l}) +#define TOY_TO_FUNCTION_NATIVE_LITERAL(value) ((Toy_Literal){{ .function.inner.native = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION_NATIVE, 0}) +#define TOY_TO_FUNCTION_HOOK_LITERAL(value) ((Toy_Literal){{ .function.inner.hook = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION_HOOK, 0}) #define TOY_TO_IDENTIFIER_LITERAL(value) Toy_private_toIdentifierLiteral(value) -#define TOY_TO_TYPE_LITERAL(value, c) ((Toy_Literal){ TOY_LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }}) -#define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){ TOY_LITERAL_OPAQUE, { .opaque.ptr = value, .opaque.tag = t }}) +#define TOY_TO_TYPE_LITERAL(value, c) ((Toy_Literal){{ .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }, TOY_LITERAL_TYPE, 0}) +#define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){{ .opaque.ptr = value, .opaque.tag = t }, TOY_LITERAL_OPAQUE, 0}) //BUGFIX: For blank indexing #define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK) -#define TOY_TO_INDEX_BLANK_LITERAL ((Toy_Literal){TOY_LITERAL_INDEX_BLANK, { .integer = 0 }}) +#define TOY_TO_INDEX_BLANK_LITERAL ((Toy_Literal){{ .integer = 0 }, TOY_LITERAL_INDEX_BLANK, 0}) TOY_API void Toy_freeLiteral(Toy_Literal literal); #define TOY_IS_TRUTHY(x) Toy_private_isTruthy(x) +#define TOY_AS_FUNCTION_BYTECODE_LENGTH(lit) ((lit).bytecodeLength) + #define TOY_MAX_STRING_LENGTH 4096 #define TOY_HASH_I(lit) ((lit).as.identifier.hash) #define TOY_TYPE_PUSH_SUBTYPE(lit, subtype) Toy_private_typePushSubtype(lit, subtype)