#include "wren.h" #include #include #include #ifdef _WIN32 #include #else #include #endif // Helper to validate that the value in a slot is a string. static bool io_validate_string(WrenVM* vm, int slot, const char* name) { if (wrenGetSlotType(vm, slot) == WREN_TYPE_STRING) return true; // The error is placed in slot 0, which becomes the return value. wrenSetSlotString(vm, 0, "Argument must be a string."); wrenAbortFiber(vm, 0); return false; } // --- File Class Foreign Methods --- void fileExists(WrenVM* vm) { if (!io_validate_string(vm, 1, "path")) return; const char* path = wrenGetSlotString(vm, 1); #ifdef _WIN32 DWORD attrib = GetFileAttributes(path); wrenSetSlotBool(vm, 0, (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY))); #else struct stat buffer; wrenSetSlotBool(vm, 0, (stat(path, &buffer) == 0)); #endif } void fileDelete(WrenVM* vm) { if (!io_validate_string(vm, 1, "path")) return; const char* path = wrenGetSlotString(vm, 1); if (remove(path) == 0) { wrenSetSlotBool(vm, 0, true); } else { wrenSetSlotBool(vm, 0, false); } } void fileRead(WrenVM* vm) { if (!io_validate_string(vm, 1, "path")) return; const char* path = wrenGetSlotString(vm, 1); FILE* file = fopen(path, "rb"); if (file == NULL) { wrenSetSlotNull(vm, 0); return; } fseek(file, 0L, SEEK_END); size_t fileSize = ftell(file); rewind(file); char* buffer = (char*)malloc(fileSize + 1); if (buffer == NULL) { fclose(file); wrenSetSlotString(vm, 0, "Could not allocate memory to read file."); wrenAbortFiber(vm, 0); return; } size_t bytesRead = fread(buffer, sizeof(char), fileSize, file); if (bytesRead < fileSize) { free(buffer); fclose(file); wrenSetSlotString(vm, 0, "Could not read entire file."); wrenAbortFiber(vm, 0); return; } buffer[bytesRead] = '\0'; fclose(file); wrenSetSlotBytes(vm, 0, buffer, bytesRead); free(buffer); } void fileWrite(WrenVM* vm) { if (!io_validate_string(vm, 1, "path")) return; if (!io_validate_string(vm, 2, "contents")) return; const char* path = wrenGetSlotString(vm, 1); int length; const char* contents = wrenGetSlotBytes(vm, 2, &length); FILE* file = fopen(path, "wb"); if (file == NULL) { wrenSetSlotBool(vm, 0, false); return; } size_t bytesWritten = fwrite(contents, sizeof(char), length, file); fclose(file); wrenSetSlotBool(vm, 0, bytesWritten == (size_t)length); } // --- FFI Binding --- WrenForeignMethodFn bindIoForeignMethod(WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature) { if (strcmp(module, "io") != 0) return NULL; if (strcmp(className, "File") == 0 && isStatic) { if (strcmp(signature, "exists(_)") == 0) return fileExists; if (strcmp(signature, "delete(_)") == 0) return fileDelete; if (strcmp(signature, "read(_)") == 0) return fileRead; if (strcmp(signature, "write(_,_)") == 0) return fileWrite; } return NULL; }