Add "io" module with beginnings of a File class.

This commit is contained in:
Bob Nystrom
2015-09-16 07:34:49 -07:00
parent 251752fcfb
commit dc527c8d86
10 changed files with 143 additions and 2 deletions

View File

@ -22,6 +22,10 @@
29205C9F1AB4E6430073018D /* wren_vm.c in Sources */ = {isa = PBXBuildFile; fileRef = 29205C981AB4E6430073018D /* wren_vm.c */; };
29512C811B91F8EB008C10E6 /* libuv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29512C801B91F8EB008C10E6 /* libuv.a */; };
29512C821B91F901008C10E6 /* libuv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29512C801B91F8EB008C10E6 /* libuv.a */; };
29729F311BA70A620099CA20 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 29729F2E1BA70A620099CA20 /* io.c */; };
29729F321BA70A620099CA20 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 29729F2E1BA70A620099CA20 /* io.c */; };
29729F331BA70A620099CA20 /* io.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29729F301BA70A620099CA20 /* io.wren.inc */; };
29729F341BA70A620099CA20 /* io.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29729F301BA70A620099CA20 /* io.wren.inc */; };
2986F6D71ACF93BA00BCE26C /* wren_primitive.c in Sources */ = {isa = PBXBuildFile; fileRef = 2986F6D51ACF93BA00BCE26C /* wren_primitive.c */; };
29C8A9331AB71FFF00DEC81D /* vm.c in Sources */ = {isa = PBXBuildFile; fileRef = 29C8A9311AB71FFF00DEC81D /* vm.c */; };
29DE39531AC3A50A00987D41 /* wren_meta.c in Sources */ = {isa = PBXBuildFile; fileRef = 29DE39511AC3A50A00987D41 /* wren_meta.c */; };
@ -75,6 +79,9 @@
29512C7F1B91F86E008C10E6 /* api_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = api_test; sourceTree = BUILT_PRODUCTS_DIR; };
29512C801B91F8EB008C10E6 /* libuv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libuv.a; path = ../../build/libuv.a; sourceTree = "<group>"; };
296371B31AC713D000079FDA /* wren_opcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wren_opcodes.h; path = ../../src/vm/wren_opcodes.h; sourceTree = "<group>"; };
29729F2E1BA70A620099CA20 /* io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = io.c; path = ../../src/module/io.c; sourceTree = "<group>"; };
29729F2F1BA70A620099CA20 /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = io.h; path = ../../src/module/io.h; sourceTree = "<group>"; };
29729F301BA70A620099CA20 /* io.wren.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = io.wren.inc; path = ../../src/module/io.wren.inc; sourceTree = "<group>"; };
2986F6D51ACF93BA00BCE26C /* wren_primitive.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wren_primitive.c; path = ../../src/vm/wren_primitive.c; sourceTree = "<group>"; };
2986F6D61ACF93BA00BCE26C /* wren_primitive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wren_primitive.h; path = ../../src/vm/wren_primitive.h; sourceTree = "<group>"; };
29AB1F061816E3AD004B501E /* wren */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = wren; sourceTree = BUILT_PRODUCTS_DIR; };
@ -114,6 +121,9 @@
2901D7611B74F3E20083A2C8 /* module */ = {
isa = PBXGroup;
children = (
29729F2F1BA70A620099CA20 /* io.h */,
29729F2E1BA70A620099CA20 /* io.c */,
29729F301BA70A620099CA20 /* io.wren.inc */,
291647C31BA5EA45006142EE /* scheduler.h */,
291647C21BA5EA45006142EE /* scheduler.c */,
291647CD1BA5ED26006142EE /* scheduler.wren.inc */,
@ -284,10 +294,12 @@
291647C71BA5EC5E006142EE /* modules.c in Sources */,
29205C9A1AB4E6430073018D /* wren_core.c in Sources */,
2901D7641B74F4050083A2C8 /* timer.c in Sources */,
29729F331BA70A620099CA20 /* io.wren.inc in Sources */,
29C8A9331AB71FFF00DEC81D /* vm.c in Sources */,
291647C41BA5EA45006142EE /* scheduler.c in Sources */,
29205C9B1AB4E6430073018D /* wren_debug.c in Sources */,
29205C9D1AB4E6430073018D /* wren_utils.c in Sources */,
29729F311BA70A620099CA20 /* io.c in Sources */,
29205C9E1AB4E6430073018D /* wren_value.c in Sources */,
29205C9F1AB4E6430073018D /* wren_vm.c in Sources */,
29DE39531AC3A50A00987D41 /* wren_meta.c in Sources */,
@ -299,7 +311,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
29729F341BA70A620099CA20 /* io.wren.inc in Sources */,
291647C81BA5EC5E006142EE /* modules.c in Sources */,
29729F321BA70A620099CA20 /* io.c in Sources */,
291647D21BA5ED26006142EE /* timer.wren.inc in Sources */,
291647D01BA5ED26006142EE /* scheduler.wren.inc in Sources */,
);

View File

@ -3,9 +3,11 @@
#include "modules.h"
#include "io.wren.inc"
#include "scheduler.wren.inc"
#include "timer.wren.inc"
#include "io.h"
#include "scheduler.h"
#include "timer.h"
@ -30,8 +32,9 @@ typedef struct
// The array of built-in modules.
static BuiltInModule modules[] =
{
{"io", &ioModuleSource, ioBindForeign, NULL},
{"scheduler", &schedulerModuleSource, schedulerBindForeign, NULL},
{"timer", &timerModuleSource, timerBindForeign, NULL},
{"timer", &timerModuleSource, timerBindForeign, NULL},
// Sentinel marking the end of the list.
{NULL, NULL, NULL, NULL}

View File

@ -2,8 +2,8 @@
#include <string.h>
#include "modules.h"
#include "vm.h"
#include "scheduler.h"
#include "vm.h"
#define MAX_LINE_LENGTH 1024 // TODO: Something less arbitrary.

51
src/module/io.c Normal file
View File

@ -0,0 +1,51 @@
#include <stdlib.h>
#include <string.h>
#include "uv.h"
#include "io.h"
#include "scheduler.h"
#include "vm.h"
#include "wren.h"
#include <stdio.h>
// Called by libuv when the stat call for size completes.
static void sizeCallback(uv_fs_t* request)
{
WrenValue* fiber = (WrenValue*)request->data;
if (request->result != 0)
{
schedulerResumeString(fiber, uv_strerror((int)request->result));
uv_fs_req_cleanup(request);
return;
}
double size = (double)request->statbuf.st_size;
uv_fs_req_cleanup(request);
schedulerResumeDouble(fiber, size);
}
static void startSize(WrenVM* vm)
{
const char* path = wrenGetArgumentString(vm, 1);
WrenValue* fiber = wrenGetArgumentValue(vm, 2);
// Store the fiber to resume when the request completes.
uv_fs_t* request = (uv_fs_t*)malloc(sizeof(uv_fs_t));
request->data = fiber;
uv_fs_stat(getLoop(), request, path, sizeCallback);
}
WrenForeignMethodFn ioBindForeign(
WrenVM* vm, const char* className, bool isStatic, const char* signature)
{
if (strcmp(className, "File") != 0) return NULL;
if (isStatic && strcmp(signature, "startSize_(_,_)") == 0) return startSize;
return NULL;
}

9
src/module/io.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef io_h
#define io_h
#include "wren.h"
WrenForeignMethodFn ioBindForeign(
WrenVM* vm, const char* className, bool isStatic, const char* signature);
#endif

15
src/module/io.wren Normal file
View File

@ -0,0 +1,15 @@
import "scheduler" for Scheduler
class File {
static size(path) {
if (!(path is String)) Fiber.abort("Path must be a string.")
startSize_(path, Fiber.current)
var result = Scheduler.runNextScheduled_()
if (result is String) Fiber.abort(result)
return result
}
foreign static startSize_(path, fiber)
}

17
src/module/io.wren.inc Normal file
View File

@ -0,0 +1,17 @@
// Generated automatically from src/module/io.wren. Do not edit.
static const char* ioModuleSource =
"import \"scheduler\" for Scheduler\n"
"\n"
"class File {\n"
" static size(path) {\n"
" if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n"
"\n"
" startSize_(path, Fiber.current)\n"
" var result = Scheduler.runNextScheduled_()\n"
" if (result is String) Fiber.abort(result)\n"
"\n"
" return result\n"
" }\n"
"\n"
" foreign static startSize_(path, fiber)\n"
"}\n";

View File

@ -35,6 +35,18 @@ void schedulerResume(WrenValue* fiber)
wrenReleaseValue(getVM(), fiber);
}
void schedulerResumeDouble(WrenValue* fiber, double value)
{
wrenCall(getVM(), resumeWithArg, NULL, "vd", fiber, value);
wrenReleaseValue(getVM(), fiber);
}
void schedulerResumeString(WrenValue* fiber, const char* text)
{
wrenCall(getVM(), resumeWithArg, NULL, "vs", fiber, text);
wrenReleaseValue(getVM(), fiber);
}
void schedulerReleaseMethods()
{
if (resume != NULL) wrenReleaseValue(getVM(), resume);

View File

@ -7,6 +7,8 @@ WrenForeignMethodFn schedulerBindForeign(
WrenVM* vm, const char* className, bool isStatic, const char* signature);
void schedulerResume(WrenValue* fiber);
void schedulerResumeDouble(WrenValue* fiber, double value);
void schedulerResumeString(WrenValue* fiber, const char* text);
void schedulerReleaseMethods();

18
test/io/file/size.wren Normal file
View File

@ -0,0 +1,18 @@
import "io" for File
import "scheduler" for Scheduler
System.print(File.size("test/io/file/size.wren")) // expect: 401
// Runs asynchronously.
Scheduler.add {
System.print("async")
}
System.print(File.size("test/io/file/size.wren"))
// expect: async
// expect: 401
var error = Fiber.new {
System.print(File.size("nonexistent"))
}.try()
System.print(error) // expect: no such file or directory