feat: implement expression evaluation and statement detection in REPL with Meta.compileExpression

Add executeInput() method to REPL that lexes input, determines if it's a statement or expression based on the first token, and evaluates accordingly using Meta.eval for statements or the new Meta.compileExpression for expressions. Extend Meta.compile_ foreign method with isExpression and printErrors parameters, update wrenCompile signature to support expression compilation mode, and add newline handling after equals in variable definitions.
This commit is contained in:
Bob Nystrom
2016-05-21 06:03:05 +00:00
parent 33c211f7c2
commit c726845c42
9 changed files with 347 additions and 177 deletions
+6 -2
View File
@@ -15,8 +15,12 @@ void metaCompile(WrenVM* vm)
ObjClosure* caller = vm->fiber->frames[vm->fiber->numFrames - 2].closure;
ObjModule* module = caller->fn->module;
const char* source = wrenGetSlotString(vm, 1);
bool isExpression = wrenGetSlotBool(vm, 2);
bool printErrors = wrenGetSlotBool(vm, 3);
// Compile it.
ObjFn* fn = wrenCompile(vm, module, wrenGetSlotString(vm, 1), false);
ObjFn* fn = wrenCompile(vm, module, source, isExpression, printErrors);
// Return the result. We can't use the public API for this since we have a
// bare ObjFn.
@@ -45,7 +49,7 @@ WrenForeignMethodFn wrenMetaBindForeignMethod(WrenVM* vm,
// There is only one foreign method in the meta module.
ASSERT(strcmp(className, "Meta") == 0, "Should be in Meta class.");
ASSERT(isStatic, "Should be static.");
ASSERT(strcmp(signature, "compile_(_)") == 0, "Should be compile method.");
ASSERT(strcmp(signature, "compile_(_,_,_)") == 0, "Should be compile method.");
return metaCompile;
}
+7 -2
View File
@@ -2,12 +2,17 @@ class Meta {
static eval(source) {
if (!(source is String)) Fiber.abort("Source code must be a string.")
var fn = compile_(source)
var fn = compile_(source, false, false)
// TODO: Include compile errors.
if (fn == null) Fiber.abort("Could not compile source code.")
Fiber.new(fn).call()
}
foreign static compile_(source)
static compileExpression(source) {
if (!(source is String)) Fiber.abort("Source code must be a string.")
return compile_(source, true, true)
}
foreign static compile_(source, isExpression, printErrors)
}
+7 -2
View File
@@ -4,12 +4,17 @@ static const char* metaModuleSource =
" static eval(source) {\n"
" if (!(source is String)) Fiber.abort(\"Source code must be a string.\")\n"
"\n"
" var fn = compile_(source)\n"
" var fn = compile_(source, false, false)\n"
" // TODO: Include compile errors.\n"
" if (fn == null) Fiber.abort(\"Could not compile source code.\")\n"
"\n"
" Fiber.new(fn).call()\n"
" }\n"
"\n"
" foreign static compile_(source)\n"
" static compileExpression(source) {\n"
" if (!(source is String)) Fiber.abort(\"Source code must be a string.\")\n"
" return compile_(source, true, true)\n"
" }\n"
"\n"
" foreign static compile_(source, isExpression, printErrors)\n"
"}\n";