feat: replace inline C string literals with auto-generated .wren.inc includes

Replace the manually embedded C string constants for builtin Wren modules with
a new build system that automatically generates `.wren.inc` header files from
`.wren` source files. The old `script/generate_builtins.py` is removed and
replaced by `script/wren_to_c_string.py`, which produces standalone include
files with a `PREAMBLE` containing the module name and source path. The Makefile
gains pattern rules to rebuild these `.wren.inc` files whenever the
corresponding `.wren` source changes, and the `builtin` phony target is removed
since the generation is now automatic. The `wren.mk` wildcard lists are updated
to include the new `.wren.inc` files as dependencies. The `timer.c` and
`wren_core.c` source files now `#include` their respective `.wren.inc` headers
instead of defining the string literals inline, and the `timer.wren` trailing
newline is removed.
This commit is contained in:
Bob Nystrom
2015-09-13 17:03:02 +00:00
parent 95ec9c63bd
commit 95626bb136
15 changed files with 455 additions and 441 deletions
+9 -45
View File
@@ -7,43 +7,7 @@
#include "wren.h"
#include "vm.h"
// This is generated from builtin/module/timer.wren. Do not edit here.
static const char* timerLibSource =
"class Timer {\n"
" static sleep(milliseconds) {\n"
" if (!(milliseconds is Num)) Fiber.abort(\"Milliseconds must be a number.\")\n"
" if (milliseconds < 0) Fiber.abort(\"Milliseconds cannot be negative.\")\n"
" startTimer_(milliseconds, Fiber.current)\n"
"\n"
" runNextScheduled_()\n"
" }\n"
"\n"
" // TODO: Once the CLI modules are more fleshed out, find a better place to\n"
" // put this.\n"
" static schedule(callable) {\n"
" if (__scheduled == null) __scheduled = []\n"
" __scheduled.add(Fiber.new {\n"
" callable.call()\n"
" runNextScheduled_()\n"
" })\n"
" }\n"
"\n"
" foreign static startTimer_(milliseconds, fiber)\n"
"\n"
" // Called by native code.\n"
" static resumeTimer_(fiber) {\n"
" fiber.transfer()\n"
" }\n"
"\n"
" static runNextScheduled_() {\n"
" if (__scheduled == null || __scheduled.isEmpty) {\n"
" Fiber.suspend()\n"
" } else {\n"
" __scheduled.removeAt(0).transfer()\n"
" }\n"
" }\n"
"}\n"
"\n";
#include "timer.wren.inc"
// The Wren method to call when a timer has completed.
static WrenValue* resumeTimer;
@@ -58,7 +22,7 @@ static void timerCloseCallback(uv_handle_t* handle)
static void timerCallback(uv_timer_t* handle)
{
WrenValue* fiber = (WrenValue*)handle->data;
// Tell libuv that we don't need the timer anymore.
uv_close((uv_handle_t*)handle, timerCloseCallback);
@@ -74,24 +38,24 @@ static void startTimer(WrenVM* vm)
{
resumeTimer = wrenGetMethod(vm, "timer", "Timer", "resumeTimer_(_)");
}
int milliseconds = (int)wrenGetArgumentDouble(vm, 1);
WrenValue* fiber = wrenGetArgumentValue(vm, 2);
// Store the fiber to resume when the timer completes.
uv_timer_t* handle = (uv_timer_t*)malloc(sizeof(uv_timer_t));
handle->data = fiber;
uv_timer_init(getLoop(), handle);
uv_timer_start(handle, timerCallback, milliseconds, 0);
}
char* timerGetSource()
{
size_t length = strlen(timerLibSource);
size_t length = strlen(timerModuleSource);
char* copy = (char*)malloc(length + 1);
strncpy(copy, timerLibSource, length + 1);
strncpy(copy, timerModuleSource, length + 1);
return copy;
}
@@ -101,7 +65,7 @@ WrenForeignMethodFn timerBindForeign(
if (strcmp(className, "Timer") != 0) return NULL;
if (isStatic && strcmp(signature, "startTimer_(_,_)") == 0) return startTimer;
return NULL;
}
-1
View File
@@ -32,4 +32,3 @@ class Timer {
}
}
}
+36
View File
@@ -0,0 +1,36 @@
// Generated automatically from src/module/timer.wren. Do not edit.
static const char* timerModuleSource =
"class Timer {\n"
" static sleep(milliseconds) {\n"
" if (!(milliseconds is Num)) Fiber.abort(\"Milliseconds must be a number.\")\n"
" if (milliseconds < 0) Fiber.abort(\"Milliseconds cannot be negative.\")\n"
" startTimer_(milliseconds, Fiber.current)\n"
"\n"
" runNextScheduled_()\n"
" }\n"
"\n"
" // TODO: Once the CLI modules are more fleshed out, find a better place to\n"
" // put this.\n"
" static schedule(callable) {\n"
" if (__scheduled == null) __scheduled = []\n"
" __scheduled.add(Fiber.new {\n"
" callable.call()\n"
" runNextScheduled_()\n"
" })\n"
" }\n"
"\n"
" foreign static startTimer_(milliseconds, fiber)\n"
"\n"
" // Called by native code.\n"
" static resumeTimer_(fiber) {\n"
" fiber.transfer()\n"
" }\n"
"\n"
" static runNextScheduled_() {\n"
" if (__scheduled == null || __scheduled.isEmpty) {\n"
" Fiber.suspend()\n"
" } else {\n"
" __scheduled.removeAt(0).transfer()\n"
" }\n"
" }\n"
"}\n";