Move IO into a separate module.

This commit is contained in:
Bob Nystrom
2014-02-04 08:44:59 -08:00
parent ba06a4fd8a
commit 36df70dba1
13 changed files with 182 additions and 96 deletions
+3 -28
View File
@@ -40,22 +40,8 @@
return PRIM_ERROR; \
} while (0);
// This string literal is generated automatically from corelib.wren using
// make_corelib. Do not edit here.
const char* coreLibSource =
"class IO {\n"
" static print(obj) {\n"
" IO.writeString_(obj.toString)\n"
" IO.writeString_(\"\n\")\n"
" return obj\n"
" }\n"
"\n"
" static write(obj) {\n"
" IO.writeString_(obj.toString)\n"
" return obj\n"
" }\n"
"}\n"
"\n"
// This string literal is generated automatically from core. Do not edit.
static const char* libSource =
"class List {\n"
" toString {\n"
" var result = \"[\"\n"
@@ -68,7 +54,6 @@ const char* coreLibSource =
" }\n"
"}\n";
// Validates that the given argument in [args] is a Num. Returns true if it is.
// If not, reports an error and returns false.
static bool validateNum(WrenVM* vm, Value* args, int index, const char* argName)
@@ -746,13 +731,6 @@ DEF_NATIVE(string_subscript)
RETURN_VAL(value);
}
DEF_NATIVE(io_writeString)
{
if (!validateString(vm, args, 1, "Argument")) return PRIM_ERROR;
wrenPrintValue(args[1]);
RETURN_NULL;
}
DEF_NATIVE(os_clock)
{
double time = (double)clock() / CLOCKS_PER_SEC;
@@ -924,7 +902,7 @@ void wrenInitializeCore(WrenVM* vm)
ObjClass* osClass = defineClass(vm, "OS");
NATIVE(osClass->metaclass, "clock", os_clock);
wrenInterpret(vm, "Wren core library", coreLibSource);
wrenInterpret(vm, "Wren core library", libSource);
vm->listClass = AS_CLASS(findGlobal(vm, "List"));
NATIVE(vm->listClass, "add ", list_add);
@@ -941,7 +919,4 @@ void wrenInitializeCore(WrenVM* vm)
// IEEE 754 even though they have different bit representations.
NATIVE(vm->numClass, "== ", num_eqeq);
NATIVE(vm->numClass, "!= ", num_bangeq);
ObjClass* ioClass = AS_CLASS(findGlobal(vm, "IO"));
NATIVE(ioClass->metaclass, "writeString_ ", io_writeString);
}
+31
View File
@@ -0,0 +1,31 @@
#include <stdio.h>
#include "wren_io.h"
// This string literal is generated automatically from io.wren. Do not edit.
static const char* libSource =
"class IO {\n"
" static print(obj) {\n"
" IO.writeString_(obj.toString)\n"
" IO.writeString_(\"\n\")\n"
" return obj\n"
" }\n"
"\n"
" static write(obj) {\n"
" IO.writeString_(obj.toString)\n"
" return obj\n"
" }\n"
"}\n";
static void writeString(WrenVM* vm)
{
const char* s = wrenGetArgumentString(vm, 1);
// TODO: Check for null.
printf("%s", s);
}
void wrenLoadIOLibrary(WrenVM* vm)
{
wrenInterpret(vm, "Wren IO library", libSource);
wrenDefineStaticMethod(vm, "IO", "writeString_", 1, writeString);
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef wren_io_h
#define wren_io_h
#include "wren.h"
// This module defines the IO class and its associated methods. They are
// implemented using the C standard library.
void wrenLoadIOLibrary(WrenVM* vm);
#endif
+36 -8
View File
@@ -9,6 +9,8 @@
// TODO: This is used for printing the stack trace on an error. This should be
// behind a flag so that you can use Wren with all debugging info stripped out.
#include "wren_debug.h"
// TODO: Put this behind a flag so users can disable the IO library.
#include "wren_io.h"
#include "wren_vm.h"
#if WREN_TRACE_MEMORY || WREN_TRACE_GC
@@ -76,6 +78,8 @@ WrenVM* wrenNewVM(WrenConfiguration* configuration)
vm->foreignCallNumArgs = 0;
wrenInitializeCore(vm);
wrenLoadIOLibrary(vm);
return vm;
}
@@ -288,9 +292,7 @@ static void callForeign(WrenVM* vm, ObjFiber* fiber,
WrenForeignMethodFn foreign, int numArgs)
{
vm->foreignCallSlot = &fiber->stack[fiber->stackSize - numArgs];
// Don't include the receiver.
vm->foreignCallNumArgs = numArgs - 1;
vm->foreignCallNumArgs = numArgs;
foreign(vm);
@@ -1061,9 +1063,9 @@ void wrenUnpinObj(WrenVM* vm)
vm->pinned = vm->pinned->previous;
}
void wrenDefineMethod(WrenVM* vm, const char* className,
const char* methodName, int numParams,
WrenForeignMethodFn methodFn)
static void defineMethod(WrenVM* vm, const char* className,
const char* methodName, int numParams,
WrenForeignMethodFn methodFn, bool isStatic)
{
ASSERT(className != NULL, "Must provide class name.");
@@ -1119,18 +1121,44 @@ void wrenDefineMethod(WrenVM* vm, const char* className,
Method method;
method.type = METHOD_FOREIGN;
method.foreign = methodFn;
if (isStatic) classObj = classObj->metaclass;
wrenBindMethod(vm, classObj, methodSymbol, method);
}
void wrenDefineMethod(WrenVM* vm, const char* className,
const char* methodName, int numParams,
WrenForeignMethodFn methodFn)
{
defineMethod(vm, className, methodName, numParams, methodFn, false);
}
void wrenDefineStaticMethod(WrenVM* vm, const char* className,
const char* methodName, int numParams,
WrenForeignMethodFn methodFn)
{
defineMethod(vm, className, methodName, numParams, methodFn, true);
}
double wrenGetArgumentDouble(WrenVM* vm, int index)
{
ASSERT(vm->foreignCallSlot != NULL, "Must be in foreign call.");
ASSERT(index >= 0, "index cannot be negative.");
ASSERT(index < vm->foreignCallNumArgs, "Not that many arguments.");
// + 1 to shift past the receiver.
// TODO: Check actual value type first.
return AS_NUM(*(vm->foreignCallSlot + index + 1));
return AS_NUM(*(vm->foreignCallSlot + index));
}
const char* wrenGetArgumentString(WrenVM* vm, int index)
{
ASSERT(vm->foreignCallSlot != NULL, "Must be in foreign call.");
ASSERT(index >= 0, "index cannot be negative.");
ASSERT(index < vm->foreignCallNumArgs, "Not that many arguments.");
// TODO: Check actual value type first.
return AS_CSTRING(*(vm->foreignCallSlot + index));
}
void wrenReturnDouble(WrenVM* vm, double value)