Implemented native C functions called from Toy scripts

There's only example functions for now, but I'll add type-specific
functions later.
This commit is contained in:
2026-04-16 21:14:42 +10:00
parent 3a0f11ebb4
commit 88100b128a
8 changed files with 93 additions and 4 deletions

View File

@@ -11,8 +11,20 @@ Toy_Function* Toy_createFunctionFromBytecode(Toy_Bucket** bucketHandle, unsigned
return fn;
}
Toy_Function* Toy_createFunctionFromCallback(Toy_Bucket** bucketHandle, Toy_nativeCallback callback) {
Toy_Function* fn = (Toy_Function*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Function));
fn->type = TOY_FUNCTION_NATIVE;
fn->native.callback = callback;
return fn;
}
TOY_API void Toy_freeFunction(Toy_Function* fn) {
if (fn->type == TOY_FUNCTION_CUSTOM) {
Toy_private_decrementScopeRefCount(fn->bytecode.parentScope);
}
else if (fn->type == TOY_FUNCTION_NATIVE) {
fn->native.callback = NULL;
}
}

View File

@@ -3,6 +3,11 @@
#include "toy_common.h"
#include "toy_bucket.h"
#include "toy_scope.h"
#include "toy_vm.h"
//forward declare
struct Toy_VM;
typedef void (*Toy_nativeCallback)(struct Toy_VM*);
typedef enum Toy_FunctionType {
TOY_FUNCTION_CUSTOM,
@@ -17,7 +22,7 @@ typedef struct Toy_FunctionBytecode {
typedef struct Toy_FunctionNative {
Toy_FunctionType type;
void* ptr; //TODO: replace with the native function pointer
Toy_nativeCallback callback;
} Toy_FunctionNative;
typedef union Toy_Function_t {
@@ -27,5 +32,6 @@ typedef union Toy_Function_t {
} Toy_Function;
TOY_API Toy_Function* Toy_createFunctionFromBytecode(Toy_Bucket** bucketHandle, unsigned char* bytecode, Toy_Scope* parentScope);
TOY_API Toy_Function* Toy_createFunctionFromCallback(Toy_Bucket** bucketHandle, Toy_nativeCallback callback);
TOY_API void Toy_freeFunction(Toy_Function* fn);

View File

@@ -71,7 +71,7 @@ static void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, T
static Toy_ScopeEntry* adjustScopeEntries(Toy_Scope* scope, unsigned int newCapacity) {
//allocate and zero a new Toy_ScopeEntry array in memory
Toy_ScopeEntry* newEntries = malloc(newCapacity * sizeof(Toy_ScopeEntry));
Toy_ScopeEntry* newEntries = malloc(newCapacity * sizeof(Toy_ScopeEntry)); //URGENT: could use a bucket instead?
if (newEntries == NULL) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate space for 'Toy_Scope' entries\n" TOY_CC_RESET);

View File

@@ -319,7 +319,7 @@ bool Toy_checkValuesAreEqual(Toy_Value left, Toy_Value right) {
return left.as.function->bytecode.code == right.as.function->bytecode.code;
}
else {
return left.as.function->native.ptr == right.as.function->native.ptr;
return left.as.function->native.callback == right.as.function->native.callback;
}
}
else {

View File

@@ -419,7 +419,12 @@ static void processInvoke(Toy_VM* vm) {
}
break;
case TOY_FUNCTION_NATIVE:
case TOY_FUNCTION_NATIVE: {
//NOTE: arguments are on the stack, leave results on the stack
fn->native.callback(vm);
}
break;
default:
Toy_error("Can't call an unknown function type");
break;