"IO" -> "System".

Get rid of the separate opt-in IO class and replace it with a core
System class.

- Remove wren_io.c, wren_io.h, and io.wren.
- Remove the flags that disable it.
- Remove the overloads for print() with different arity. (It was an
  experiment, but I don't think it's that useful.)
- Remove IO.read(). That will reappear using libuv in the CLI at some
  point.
- Remove IO.time. Doesn't seem to have been used.
- Update all of the tests, docs, etc.

I'm sorry for all the breakage this causes, but I think "System" is a
better name for this class (it makes it natural to add things like
"System.gc()") and frees up "IO" for referring to the CLI's IO module.
This commit is contained in:
Bob Nystrom
2015-09-15 07:46:09 -07:00
parent 66b89a493f
commit 58e4d26648
491 changed files with 3285 additions and 3544 deletions
-7
View File
@@ -44,13 +44,6 @@
#endif
#endif
// If true, loads the "IO" class in the standard library.
//
// Defaults to on.
#ifndef WREN_USE_LIB_IO
#define WREN_USE_LIB_IO 1
#endif
// If true, loads the "Meta" class in the standard library.
//
// Defaults to on.
+16
View File
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "wren_common.h"
#include "wren_core.h"
@@ -1041,6 +1042,17 @@ DEF_PRIMITIVE(string_toString)
RETURN_VAL(args[0]);
}
DEF_PRIMITIVE(system_clock)
{
RETURN_NUM((double)clock() / CLOCKS_PER_SEC);
}
DEF_PRIMITIVE(system_writeString)
{
printf("%s", AS_CSTRING(args[1]));
RETURN_VAL(args[1]);
}
// Creates either the Object or Class class in the core library with [name].
static ObjClass* defineClass(WrenVM* vm, ObjModule* module, const char* name)
{
@@ -1254,6 +1266,10 @@ void wrenInitializeCore(WrenVM* vm)
PRIMITIVE(vm->rangeClass, "iteratorValue(_)", range_iteratorValue);
PRIMITIVE(vm->rangeClass, "toString", range_toString);
ObjClass* systemClass = AS_CLASS(wrenFindVariable(vm, coreModule, "System"));
PRIMITIVE(systemClass->obj.classObj, "clock", system_clock);
PRIMITIVE(systemClass->obj.classObj, "writeString_(_)", system_writeString);
// While bootstrapping the core types and running the core library, a number
// of string objects have been created, many of which were instantiated
// before stringClass was stored in the VM. Some of them *must* be created
+36 -1
View File
@@ -214,4 +214,39 @@ static const char* coreModuleSource =
" iteratorValue(iterator) { _map.valueIteratorValue_(iterator) }\n"
"}\n"
"\n"
"class Range is Sequence {}\n";
"class Range is Sequence {}\n"
"\n"
"class System {\n"
" static print() {\n"
" writeString_(\"\n\")\n"
" }\n"
"\n"
" static print(obj) {\n"
" writeObject_(obj)\n"
" writeString_(\"\n\")\n"
" return obj\n"
" }\n"
"\n"
" static printAll(sequence) {\n"
" for (object in sequence) writeObject_(object)\n"
" writeString_(\"\n\")\n"
" }\n"
"\n"
" static write(obj) {\n"
" writeObject_(obj)\n"
" return obj\n"
" }\n"
"\n"
" static writeAll(sequence) {\n"
" for (object in sequence) writeObject_(object)\n"
" }\n"
"\n"
" static writeObject_(obj) {\n"
" var string = obj.toString\n"
" if (string is String) {\n"
" writeString_(string)\n"
" } else {\n"
" writeString_(\"[invalid toString]\")\n"
" }\n"
" }\n"
"}\n";
-59
View File
@@ -1,59 +0,0 @@
#include "wren_io.h"
#if WREN_USE_LIB_IO
#include <stdio.h>
#include <string.h>
#include <time.h>
// TODO: This is an arbitrary limit. Do something smarter.
#define MAX_READ_LEN 1024
#include "wren_io.wren.inc"
static void ioWriteString(WrenVM* vm)
{
const char* s = wrenGetArgumentString(vm, 1);
// TODO: Check for null.
printf("%s", s);
}
static void ioRead(WrenVM* vm)
{
char buffer[MAX_READ_LEN];
char* result = fgets(buffer, MAX_READ_LEN, stdin);
if (result != NULL)
{
wrenReturnString(vm, buffer, (int)strlen(buffer));
}
}
static void ioClock(WrenVM* vm)
{
wrenReturnDouble(vm, (double)clock() / CLOCKS_PER_SEC);
}
static void ioTime(WrenVM* vm)
{
wrenReturnDouble(vm, (double)time(NULL));
}
void wrenLoadIOLibrary(WrenVM* vm)
{
wrenInterpret(vm, "", ioModuleSource);
}
WrenForeignMethodFn wrenBindIOForeignMethod(WrenVM* vm, const char* className,
const char* signature)
{
if (strcmp(className, "IO") != 0) return NULL;
if (strcmp(signature, "writeString_(_)") == 0) return ioWriteString;
if (strcmp(signature, "clock") == 0) return ioClock;
if (strcmp(signature, "time") == 0) return ioTime;
if (strcmp(signature, "read()") == 0) return ioRead;
return NULL;
}
#endif
-18
View File
@@ -1,18 +0,0 @@
#ifndef wren_io_h
#define wren_io_h
#include "wren.h"
#include "wren_common.h"
// This module defines the IO class and its associated methods. They are
// implemented using the C standard library.
#if WREN_USE_LIB_IO
void wrenLoadIOLibrary(WrenVM* vm);
WrenForeignMethodFn wrenBindIOForeignMethod(WrenVM* vm, const char* className,
const char* signature);
#endif
#endif
-103
View File
@@ -1,103 +0,0 @@
// Generated automatically from builtin/io.wren. Do not edit.
static const char* ioModuleSource =
"class IO {\n"
" static print {\n"
" writeString_(\"\n\")\n"
" }\n"
"\n"
" static print(obj) {\n"
" writeObject_(obj)\n"
" writeString_(\"\n\")\n"
" return obj\n"
" }\n"
"\n"
" static print(a1, a2) {\n"
" printAll([a1, a2])\n"
" }\n"
"\n"
" static print(a1, a2, a3) {\n"
" printAll([a1, a2, a3])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4) {\n"
" printAll([a1, a2, a3, a4])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5) {\n"
" printAll([a1, a2, a3, a4, a5])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6) {\n"
" printAll([a1, a2, a3, a4, a5, a6])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) {\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16])\n"
" }\n"
"\n"
" static printAll(sequence) {\n"
" for (object in sequence) writeObject_(object)\n"
" writeString_(\"\n\")\n"
" }\n"
"\n"
" static write(obj) {\n"
" writeObject_(obj)\n"
" return obj\n"
" }\n"
"\n"
" static read(prompt) {\n"
" if (!(prompt is String)) Fiber.abort(\"Prompt must be a string.\")\n"
" write(prompt)\n"
" return read()\n"
" }\n"
"\n"
" static writeObject_(obj) {\n"
" var string = obj.toString\n"
" if (string is String) {\n"
" writeString_(string)\n"
" } else {\n"
" writeString_(\"[invalid toString]\")\n"
" }\n"
" }\n"
"\n"
" foreign static writeString_(string)\n"
" foreign static clock\n"
" foreign static time\n"
" foreign static read()\n"
"}\n";
-14
View File
@@ -298,20 +298,6 @@ static WrenForeignMethodFn findForeignMethod(WrenVM* vm,
bool isStatic,
const char* signature)
{
WrenForeignMethodFn fn;
// Bind foreign methods in the core module.
if (strcmp(moduleName, "core") == 0)
{
#if WREN_USE_LIB_IO
fn = wrenBindIOForeignMethod(vm, className, signature);
#endif
ASSERT(fn != NULL, "Failed to bind core module foreign method.");
return fn;
}
// For other modules, let the host bind it.
if (vm->bindForeignMethod == NULL) return NULL;
return vm->bindForeignMethod(vm, moduleName, className, isStatic, signature);