diff --git a/makefile b/makefile index 8cbe545..9420ee9 100644 --- a/makefile +++ b/makefile @@ -2,6 +2,8 @@ # export CFLAGS+=-O2 -mtune=native -march=native # export CFLAGS+=-fsanitize=address,undefined +export CFLAGS+=-std=c18 -pedantic -Werror + export TOY_OUTDIR = out all: $(TOY_OUTDIR) repl diff --git a/repl/lib_runner.c b/repl/lib_runner.c index ee1c5ef..6ea1eba 100644 --- a/repl/lib_runner.c +++ b/repl/lib_runner.c @@ -514,8 +514,7 @@ int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Lit //load the dict with functions for (int i = 0; natives[i].name; i++) { Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name)); - Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); - func.type = TOY_LITERAL_FUNCTION_NATIVE; + Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn); Toy_setLiteralDictionary(dictionary, name, func); diff --git a/repl/lib_standard.c b/repl/lib_standard.c index b253286..bb427b7 100644 --- a/repl/lib_standard.c +++ b/repl/lib_standard.c @@ -59,8 +59,7 @@ int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L //load the dict with functions for (int i = 0; natives[i].name; i++) { Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name)); - Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); - func.type = TOY_LITERAL_FUNCTION_NATIVE; + Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn); Toy_setLiteralDictionary(dictionary, name, func); diff --git a/repl/lib_timer.c b/repl/lib_timer.c index 60a4c28..f0d3194 100644 --- a/repl/lib_timer.c +++ b/repl/lib_timer.c @@ -376,8 +376,7 @@ int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Lite //load the dict with functions for (int i = 0; natives[i].name; i++) { Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name)); - Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); - func.type = TOY_LITERAL_FUNCTION_NATIVE; + Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn); Toy_setLiteralDictionary(dictionary, name, func); diff --git a/source/toy_interpreter.c b/source/toy_interpreter.c index e89ae72..e428c07 100644 --- a/source/toy_interpreter.c +++ b/source/toy_interpreter.c @@ -42,9 +42,7 @@ bool Toy_injectNativeFn(Toy_Interpreter* interpreter, char* name, Toy_NativeFn f return false; } - Toy_Literal fn = TOY_TO_FUNCTION_LITERAL((void*)func, 0); - fn.type = TOY_LITERAL_FUNCTION_NATIVE; - + Toy_Literal fn = TOY_TO_FUNCTION_NATIVE_LITERAL(func); Toy_Literal type = TOY_TO_TYPE_LITERAL(fn.type, true); Toy_setLiteralDictionary(&interpreter->scope->variables, identifier, fn); @@ -72,9 +70,7 @@ bool Toy_injectNativeHook(Toy_Interpreter* interpreter, char* name, Toy_HookFn h return false; } - Toy_Literal fn = TOY_TO_FUNCTION_LITERAL((void*)hook, 0); - fn.type = TOY_LITERAL_FUNCTION_NATIVE; - + Toy_Literal fn = TOY_TO_FUNCTION_HOOK_LITERAL(hook); Toy_setLiteralDictionary(interpreter->hooks, identifier, fn); Toy_freeLiteral(identifier); @@ -1187,7 +1183,7 @@ static bool execFnCall(Toy_Interpreter* interpreter, bool looseFirstArgument) { Toy_freeLiteralArray(&arguments); //call the native function - ((Toy_NativeFn) TOY_AS_FUNCTION(func).bytecode )(interpreter, &correct); + TOY_AS_FUNCTION_NATIVE(func)(interpreter, &correct); Toy_freeLiteralArray(&correct); Toy_freeLiteral(identifier); @@ -1494,8 +1490,8 @@ static bool execImport(Toy_Interpreter* interpreter) { Toy_Literal func = Toy_getLiteralDictionary(interpreter->hooks, identifier); - if (!TOY_IS_FUNCTION_NATIVE(func)) { - interpreter->errorOutput("Expected native function for a hook: "); + if (!TOY_IS_FUNCTION_HOOK(func)) { + interpreter->errorOutput("Expected hook function, found: "); Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\"\n"); @@ -1505,9 +1501,7 @@ static bool execImport(Toy_Interpreter* interpreter) { return false; } - Toy_HookFn fn = (Toy_HookFn)TOY_AS_FUNCTION(func).bytecode; - - fn(interpreter, identifier, alias); + TOY_AS_FUNCTION_HOOK(func)(interpreter, identifier, alias); Toy_freeLiteral(func); Toy_freeLiteral(alias); diff --git a/source/toy_interpreter.h b/source/toy_interpreter.h index 9ab71c3..323627f 100644 --- a/source/toy_interpreter.h +++ b/source/toy_interpreter.h @@ -34,10 +34,7 @@ typedef struct Toy_Interpreter { } Toy_Interpreter; //native API -typedef int (*Toy_NativeFn)(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); TOY_API bool Toy_injectNativeFn(Toy_Interpreter* interpreter, char* name, Toy_NativeFn func); - -typedef int (*Toy_HookFn)(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias); TOY_API bool Toy_injectNativeHook(Toy_Interpreter* interpreter, char* name, Toy_HookFn hook); TOY_API bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_LiteralArray* arguments, Toy_LiteralArray* returns); diff --git a/source/toy_literal.c b/source/toy_literal.c index 74bff89..44f4a51 100644 --- a/source/toy_literal.c +++ b/source/toy_literal.c @@ -206,6 +206,7 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { case TOY_LITERAL_FUNCTION_INTERMEDIATE: //caries a compiler case TOY_LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_FUNCTION_HOOK: case TOY_LITERAL_INDEX_BLANK: //no copying possible return original; @@ -287,6 +288,7 @@ bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs) { case TOY_LITERAL_FUNCTION: case TOY_LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_FUNCTION_HOOK: return false; //functions are never equal break; @@ -384,6 +386,7 @@ int Toy_hashLiteral(Toy_Literal lit) { case TOY_LITERAL_FUNCTION: case TOY_LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_FUNCTION_HOOK: return 0; //can't hash these case TOY_LITERAL_IDENTIFIER: @@ -570,6 +573,7 @@ void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)) { case TOY_LITERAL_FUNCTION: case TOY_LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_FUNCTION_HOOK: printFn("(function)"); break; diff --git a/source/toy_literal.h b/source/toy_literal.h index cfded87..072bd5f 100644 --- a/source/toy_literal.h +++ b/source/toy_literal.h @@ -4,6 +4,13 @@ #include "toy_refstring.h" +//forward delcare stuff +struct Toy_Literal; +struct Toy_Interpreter; +struct Toy_LiteralArray; +typedef int (*Toy_NativeFn)(struct Toy_Interpreter* interpreter, struct Toy_LiteralArray* arguments); +typedef int (*Toy_HookFn)(struct Toy_Interpreter* interpreter, struct Toy_Literal identifier, struct Toy_Literal alias); + #include typedef enum { @@ -26,10 +33,11 @@ typedef enum { TOY_LITERAL_FUNCTION_INTERMEDIATE, //used to process functions in the compiler only TOY_LITERAL_FUNCTION_ARG_REST, //used to process function rest parameters only TOY_LITERAL_FUNCTION_NATIVE, //for handling native functions only + TOY_LITERAL_FUNCTION_HOOK, //for handling hook functions within literals only TOY_LITERAL_INDEX_BLANK, //for blank indexing i.e. arr[:] } Toy_LiteralType; -typedef struct { +typedef struct Toy_Literal { Toy_LiteralType type; union { bool boolean; @@ -45,6 +53,8 @@ typedef struct { struct { void* bytecode; + Toy_NativeFn native; //already a pointer + Toy_HookFn hook; //already a pointer void* scope; int length; } function; @@ -78,6 +88,7 @@ typedef struct { #define TOY_IS_DICTIONARY(value) ((value).type == TOY_LITERAL_DICTIONARY) #define TOY_IS_FUNCTION(value) ((value).type == TOY_LITERAL_FUNCTION) #define TOY_IS_FUNCTION_NATIVE(value) ((value).type == TOY_LITERAL_FUNCTION_NATIVE) +#define TOY_IS_FUNCTION_HOOK(value) ((value).type == TOY_LITERAL_FUNCTION_HOOK) #define TOY_IS_IDENTIFIER(value) ((value).type == TOY_LITERAL_IDENTIFIER) #define TOY_IS_TYPE(value) ((value).type == TOY_LITERAL_TYPE) #define TOY_IS_OPAQUE(value) ((value).type == TOY_LITERAL_OPAQUE) @@ -89,21 +100,25 @@ typedef struct { #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_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){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_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_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_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){ 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 }}) //BUGFIX: For blank indexing #define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK) diff --git a/source/toy_refstring.c b/source/toy_refstring.c index 6442283..08ccca0 100644 --- a/source/toy_refstring.c +++ b/source/toy_refstring.c @@ -20,7 +20,7 @@ void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn allocator) { //API Toy_RefString* Toy_createRefString(char* cstring) { - int length = strnlen(cstring, 4096); + int length = strlen(cstring); return Toy_createRefStringLength(cstring, length); } @@ -87,7 +87,7 @@ bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs) { bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring) { //get the rhs length - int length = strnlen(cstring, 4096); + int length = strlen(cstring); //different length if (lhs->length != length) {