static int runRepl() { WrenVM* vm = wrenNewVM(reallocate); for (;;) { printf("> "); char line[MAX_LINE]; fgets(line, MAX_LINE, stdin); // TODO: Handle failure. wrenInterpret(vm, line); // TODO: Figure out how this should work with wren API. /* ObjFn* fn = compile(vm, line); if (fn != NULL) { Value result = interpret(vm, fn); printf("= "); printValue(result); printf("\n"); } */ } wrenFreeVM(vm); return 0; }
static int runRepl() { WrenVM* vm = createVM(NULL); printf("\\\\/\"-\n"); printf(" \\_/ wren v0.0.0\n"); char line[MAX_LINE_LENGTH]; for (;;) { printf("> "); if (!fgets(line, MAX_LINE_LENGTH, stdin)) { printf("\n"); break; } // TODO: Handle failure. wrenInterpret(vm, "Prompt", line); // TODO: Automatically print the result of expressions. } wrenFreeVM(vm); return 0; }
int runRepl() { initVM(); printf("\\\\/\"-\n"); printf(" \\_/ wren v0.0.0\n"); char line[MAX_LINE_LENGTH]; for (;;) { printf("> "); if (!fgets(line, MAX_LINE_LENGTH, stdin)) { printf("\n"); break; } // TODO: Handle failure. wrenInterpret(vm, line); // TODO: Automatically print the result of expressions. } freeVM(); return 0; }
void wrenLoadMetaLibrary(WrenVM* vm) { wrenInterpret(vm, "", metaModuleSource); ObjModule* coreModule = wrenGetCoreModule(vm); // The methods on "Meta" are static, so get the metaclass for the Meta class. ObjClass* meta = AS_CLASS(wrenFindVariable(vm, coreModule, "Meta")); PRIMITIVE(meta->obj.classObj, "eval(_)", meta_eval); }
static int runFile(const char* path) { char* source = readFile(path); WrenVM* vm = wrenNewVM(reallocate); int result = wrenInterpret(vm, source); wrenFreeVM(vm); free(source); return result; }
void Wren::executeString( const std::string& code ) { // set global variables for the C-callbacks boundForeignMethods = &foreignMethods_; boundForeignClasses = &foreignClasses_; auto res = wrenInterpret( vm_, "string", code.c_str() ); if ( res == WrenInterpretResult::WREN_RESULT_COMPILE_ERROR ) { std::cerr << "WREN_RESULT_COMPILE_ERROR in string: " << code << std::endl; } if ( res == WrenInterpretResult::WREN_RESULT_RUNTIME_ERROR ) { std::cerr << "WREN_RESULT_RUNTIME_ERROR in string: " << code << std::endl; } boundForeignMethods = nullptr; boundForeignClasses = nullptr; }
int main(int argc, char *argv[]) { const char* s = argc > 1 ? argv[1] : DEFAULT_SCRIPT; const int c = argc > 2 ? atoi(argv[2]) : DEFAULT_COUNT; count += c; char* script = readFile(s); if (script == NULL) { fprintf(stderr, "Could not locate %s\n", s); return 1; } WrenConfiguration config; wrenInitConfiguration(&config); config.bindForeignMethodFn = bindForeignMethod; //config.bindForeignClassFn = bindForeignClass; //config.loadModuleFn = readModule; config.writeFn = write; config.errorFn = reportError; // Since we're running in a standalone process, be generous with memory. config.initialHeapSize = 1024 * 1024 * 100; WrenVM* vm = wrenNewVM(&config); //fprintf(stdout, "Found hello.wren\n%s\n", script); WrenInterpretResult result = wrenInterpret(vm, script); if (result == WREN_RESULT_SUCCESS) { printf("%lld\n", ts_stop - ts_start); } else { fprintf(stderr, "Error executing hello.wren %d\n", result); } wrenFreeVM(vm); free(script); return result; }
void runFile(const char* path) { // Use the directory where the file is as the root to resolve imports // relative to. char* root = NULL; const char* lastSlash = strrchr(path, '/'); if (lastSlash != NULL) { root = (char*)malloc(lastSlash - path + 2); memcpy(root, path, lastSlash - path + 1); root[lastSlash - path + 1] = '\0'; rootDirectory = root; } char* source = readFile(path); if (source == NULL) { fprintf(stderr, "Could not find file \"%s\".\n", path); exit(66); } initVM(); WrenInterpretResult result = wrenInterpret(vm, source); if (afterLoadFn != NULL) afterLoadFn(vm); if (result == WREN_RESULT_SUCCESS) { uv_run(loop, UV_RUN_DEFAULT); } freeVM(); free(source); free(root); // Exit with an error code if the script failed. if (result == WREN_RESULT_COMPILE_ERROR) exit(65); // EX_DATAERR. if (result == WREN_RESULT_RUNTIME_ERROR) exit(70); // EX_SOFTWARE. if (defaultExitCode != 0) exit(defaultExitCode); }
void Wren::executeModule( const std::string& mod ) { // set global variables for the C-callbacks boundForeignMethods = &foreignMethods_; boundForeignClasses = &foreignClasses_; std::string file = mod; file += ".wren"; auto source = FileToString( file ); auto res = wrenInterpret( vm_, file.c_str(), source.c_str() ); if ( res == WrenInterpretResult::WREN_RESULT_COMPILE_ERROR ) { std::cerr << "WREN_RESULT_COMPILE_ERROR in module " << mod << std::endl; } if ( res == WrenInterpretResult::WREN_RESULT_RUNTIME_ERROR ) { std::cerr << "WREN_RESULT_RUNTIME_ERROR in module " << mod << std::endl; } boundForeignMethods = nullptr; boundForeignClasses = nullptr; }
void wrenInitializeCore(WrenVM* vm) { ObjModule* coreModule = wrenGetCoreModule(vm); // Define the root Object class. This has to be done a little specially // because it has no superclass. vm->objectClass = defineClass(vm, coreModule, "Object"); PRIMITIVE(vm->objectClass, "!", object_not); PRIMITIVE(vm->objectClass, "==(_)", object_eqeq); PRIMITIVE(vm->objectClass, "!=(_)", object_bangeq); PRIMITIVE(vm->objectClass, "is(_)", object_is); PRIMITIVE(vm->objectClass, "toString", object_toString); PRIMITIVE(vm->objectClass, "type", object_type); // Now we can define Class, which is a subclass of Object. vm->classClass = defineClass(vm, coreModule, "Class"); wrenBindSuperclass(vm, vm->classClass, vm->objectClass); PRIMITIVE(vm->classClass, "name", class_name); PRIMITIVE(vm->classClass, "supertype", class_supertype); PRIMITIVE(vm->classClass, "toString", class_toString); // Finally, we can define Object's metaclass which is a subclass of Class. ObjClass* objectMetaclass = defineClass(vm, coreModule, "Object metaclass"); // Wire up the metaclass relationships now that all three classes are built. vm->objectClass->obj.classObj = objectMetaclass; objectMetaclass->obj.classObj = vm->classClass; vm->classClass->obj.classObj = vm->classClass; // Do this after wiring up the metaclasses so objectMetaclass doesn't get // collected. wrenBindSuperclass(vm, objectMetaclass, vm->classClass); PRIMITIVE(objectMetaclass, "same(_,_)", object_same); // The core class diagram ends up looking like this, where single lines point // to a class's superclass, and double lines point to its metaclass: // // .------------------------------------. .====. // | .---------------. | # # // v | v | v # // .---------. .-------------------. .-------. # // | Object |==>| Object metaclass |==>| Class |==" // '---------' '-------------------' '-------' // ^ ^ ^ ^ ^ // | .--------------' # | # // | | # | # // .---------. .-------------------. # | # -. // | Base |==>| Base metaclass |======" | # | // '---------' '-------------------' | # | // ^ | # | // | .------------------' # | Example classes // | | # | // .---------. .-------------------. # | // | Derived |==>| Derived metaclass |==========" | // '---------' '-------------------' -' // The rest of the classes can now be defined normally. wrenInterpret(vm, "", coreLibSource); vm->boolClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Bool")); PRIMITIVE(vm->boolClass, "toString", bool_toString); PRIMITIVE(vm->boolClass, "!", bool_not); vm->fiberClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Fiber")); PRIMITIVE(vm->fiberClass->obj.classObj, "new(_)", fiber_new); PRIMITIVE(vm->fiberClass->obj.classObj, "abort(_)", fiber_abort); PRIMITIVE(vm->fiberClass->obj.classObj, "current", fiber_current); PRIMITIVE(vm->fiberClass->obj.classObj, "suspend()", fiber_suspend); PRIMITIVE(vm->fiberClass->obj.classObj, "yield()", fiber_yield); PRIMITIVE(vm->fiberClass->obj.classObj, "yield(_)", fiber_yield1); PRIMITIVE(vm->fiberClass, "call()", fiber_call); PRIMITIVE(vm->fiberClass, "call(_)", fiber_call1); PRIMITIVE(vm->fiberClass, "error", fiber_error); PRIMITIVE(vm->fiberClass, "isDone", fiber_isDone); PRIMITIVE(vm->fiberClass, "transfer()", fiber_transfer); PRIMITIVE(vm->fiberClass, "transfer(_)", fiber_transfer1); PRIMITIVE(vm->fiberClass, "try()", fiber_try); vm->fnClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Fn")); PRIMITIVE(vm->fnClass->obj.classObj, "new(_)", fn_new); PRIMITIVE(vm->fnClass, "arity", fn_arity); PRIMITIVE(vm->fnClass, "call()", fn_call0); PRIMITIVE(vm->fnClass, "call(_)", fn_call1); PRIMITIVE(vm->fnClass, "call(_,_)", fn_call2); PRIMITIVE(vm->fnClass, "call(_,_,_)", fn_call3); PRIMITIVE(vm->fnClass, "call(_,_,_,_)", fn_call4); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_)", fn_call5); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_)", fn_call6); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_)", fn_call7); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_)", fn_call8); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_,_)", fn_call9); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_,_,_)", fn_call10); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_,_,_,_)", fn_call11); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_,_,_,_,_)", fn_call12); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_,_,_,_,_,_)", fn_call13); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_)", fn_call14); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_)", fn_call15); PRIMITIVE(vm->fnClass, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_)", fn_call16); PRIMITIVE(vm->fnClass, "toString", fn_toString); vm->nullClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Null")); PRIMITIVE(vm->nullClass, "!", null_not); PRIMITIVE(vm->nullClass, "toString", null_toString); vm->numClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Num")); PRIMITIVE(vm->numClass->obj.classObj, "fromString(_)", num_fromString); PRIMITIVE(vm->numClass->obj.classObj, "pi", num_pi); PRIMITIVE(vm->numClass, "-(_)", num_minus); PRIMITIVE(vm->numClass, "+(_)", num_plus); PRIMITIVE(vm->numClass, "*(_)", num_multiply); PRIMITIVE(vm->numClass, "/(_)", num_divide); PRIMITIVE(vm->numClass, "<(_)", num_lt); PRIMITIVE(vm->numClass, ">(_)", num_gt); PRIMITIVE(vm->numClass, "<=(_)", num_lte); PRIMITIVE(vm->numClass, ">=(_)", num_gte); PRIMITIVE(vm->numClass, "&(_)", num_bitwiseAnd); PRIMITIVE(vm->numClass, "|(_)", num_bitwiseOr); PRIMITIVE(vm->numClass, "^(_)", num_bitwiseXor); PRIMITIVE(vm->numClass, "<<(_)", num_bitwiseLeftShift); PRIMITIVE(vm->numClass, ">>(_)", num_bitwiseRightShift); PRIMITIVE(vm->numClass, "abs", num_abs); PRIMITIVE(vm->numClass, "acos", num_acos); PRIMITIVE(vm->numClass, "asin", num_asin); PRIMITIVE(vm->numClass, "atan", num_atan); PRIMITIVE(vm->numClass, "ceil", num_ceil); PRIMITIVE(vm->numClass, "cos", num_cos); PRIMITIVE(vm->numClass, "floor", num_floor); PRIMITIVE(vm->numClass, "-", num_negate); PRIMITIVE(vm->numClass, "sin", num_sin); PRIMITIVE(vm->numClass, "sqrt", num_sqrt); PRIMITIVE(vm->numClass, "tan", num_tan); PRIMITIVE(vm->numClass, "%(_)", num_mod); PRIMITIVE(vm->numClass, "~", num_bitwiseNot); PRIMITIVE(vm->numClass, "..(_)", num_dotDot); PRIMITIVE(vm->numClass, "...(_)", num_dotDotDot); PRIMITIVE(vm->numClass, "atan(_)", num_atan2); PRIMITIVE(vm->numClass, "fraction", num_fraction); PRIMITIVE(vm->numClass, "isNan", num_isNan); PRIMITIVE(vm->numClass, "sign", num_sign); PRIMITIVE(vm->numClass, "toString", num_toString); PRIMITIVE(vm->numClass, "truncate", num_truncate); // These are defined just so that 0 and -0 are equal, which is specified by // IEEE 754 even though they have different bit representations. PRIMITIVE(vm->numClass, "==(_)", num_eqeq); PRIMITIVE(vm->numClass, "!=(_)", num_bangeq); vm->stringClass = AS_CLASS(wrenFindVariable(vm, coreModule, "String")); PRIMITIVE(vm->stringClass->obj.classObj, "fromCodePoint(_)", string_fromCodePoint); PRIMITIVE(vm->stringClass, "+(_)", string_plus); PRIMITIVE(vm->stringClass, "[_]", string_subscript); PRIMITIVE(vm->stringClass, "byteAt(_)", string_byteAt); PRIMITIVE(vm->stringClass, "codePointAt(_)", string_codePointAt); PRIMITIVE(vm->stringClass, "contains(_)", string_contains); PRIMITIVE(vm->stringClass, "count", string_count); PRIMITIVE(vm->stringClass, "endsWith(_)", string_endsWith); PRIMITIVE(vm->stringClass, "indexOf(_)", string_indexOf); PRIMITIVE(vm->stringClass, "iterate(_)", string_iterate); PRIMITIVE(vm->stringClass, "iterateByte_(_)", string_iterateByte); PRIMITIVE(vm->stringClass, "iteratorValue(_)", string_iteratorValue); PRIMITIVE(vm->stringClass, "startsWith(_)", string_startsWith); PRIMITIVE(vm->stringClass, "toString", string_toString); vm->listClass = AS_CLASS(wrenFindVariable(vm, coreModule, "List")); PRIMITIVE(vm->listClass->obj.classObj, "new()", list_new); PRIMITIVE(vm->listClass, "[_]", list_subscript); PRIMITIVE(vm->listClass, "[_]=(_)", list_subscriptSetter); PRIMITIVE(vm->listClass, "add(_)", list_add); PRIMITIVE(vm->listClass, "clear()", list_clear); PRIMITIVE(vm->listClass, "count", list_count); PRIMITIVE(vm->listClass, "insert(_,_)", list_insert); PRIMITIVE(vm->listClass, "iterate(_)", list_iterate); PRIMITIVE(vm->listClass, "iteratorValue(_)", list_iteratorValue); PRIMITIVE(vm->listClass, "removeAt(_)", list_removeAt); vm->mapClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Map")); PRIMITIVE(vm->mapClass->obj.classObj, "new()", map_new); PRIMITIVE(vm->mapClass, "[_]", map_subscript); PRIMITIVE(vm->mapClass, "[_]=(_)", map_subscriptSetter); PRIMITIVE(vm->mapClass, "clear()", map_clear); PRIMITIVE(vm->mapClass, "containsKey(_)", map_containsKey); PRIMITIVE(vm->mapClass, "count", map_count); PRIMITIVE(vm->mapClass, "remove(_)", map_remove); PRIMITIVE(vm->mapClass, "iterate_(_)", map_iterate); PRIMITIVE(vm->mapClass, "keyIteratorValue_(_)", map_keyIteratorValue); PRIMITIVE(vm->mapClass, "valueIteratorValue_(_)", map_valueIteratorValue); vm->rangeClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Range")); PRIMITIVE(vm->rangeClass, "from", range_from); PRIMITIVE(vm->rangeClass, "to", range_to); PRIMITIVE(vm->rangeClass, "min", range_min); PRIMITIVE(vm->rangeClass, "max", range_max); PRIMITIVE(vm->rangeClass, "isInclusive", range_isInclusive); PRIMITIVE(vm->rangeClass, "iterate(_)", range_iterate); PRIMITIVE(vm->rangeClass, "iteratorValue(_)", range_iteratorValue); PRIMITIVE(vm->rangeClass, "toString", range_toString); // 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 // first -- the ObjClass for string itself has a reference to the ObjString // for its name. // // These all currently have a NULL classObj pointer, so go back and assign // them now that the string class is known. for (Obj* obj = vm->first; obj != NULL; obj = obj->next) { if (obj->type == OBJ_STRING) obj->classObj = vm->stringClass; } }
void wrenInitializeCore(WrenVM* vm) { // Define the root Object class. This has to be done a little specially // because it has no superclass and an unusual metaclass (Class). vm->objectClass = defineSingleClass(vm, "Object"); NATIVE(vm->objectClass, "== ", object_eqeq); NATIVE(vm->objectClass, "!= ", object_bangeq); NATIVE(vm->objectClass, "new", object_new); NATIVE(vm->objectClass, "toString", object_toString); NATIVE(vm->objectClass, "type", object_type); NATIVE(vm->objectClass, " instantiate", object_instantiate); // Now we can define Class, which is a subclass of Object, but Object's // metaclass. vm->classClass = defineSingleClass(vm, "Class"); // Now that Object and Class are defined, we can wire them up to each other. wrenBindSuperclass(vm, vm->classClass, vm->objectClass); vm->objectClass->metaclass = vm->classClass; vm->classClass->metaclass = vm->classClass; // Define the methods specific to Class after wiring up its superclass to // prevent the inherited ones from overwriting them. NATIVE(vm->classClass, " instantiate", class_instantiate); NATIVE(vm->classClass, "name", class_name); // The core class diagram ends up looking like this, where single lines point // to a class's superclass, and double lines point to its metaclass: // // __________ /====\ // / \ // \\ // v \ v \\ // .---------. .--------------. // // | Object |==>| Class |==/ // '---------' '--------------' // ^ ^ // | | // .---------. .--------------. \ // | Base |==>| Base.type | | // '---------' '--------------' | // ^ ^ | Hypothetical example classes // | | | // .---------. .--------------. | // | Derived |==>| Derived.type | | // '---------' '--------------' / // The rest of the classes can not be defined normally. vm->boolClass = defineClass(vm, "Bool"); NATIVE(vm->boolClass, "toString", bool_toString); NATIVE(vm->boolClass, "!", bool_not); // TODO: Make fibers inherit Sequence and be iterable. vm->fiberClass = defineClass(vm, "Fiber"); NATIVE(vm->fiberClass->metaclass, " instantiate", fiber_instantiate); NATIVE(vm->fiberClass->metaclass, "new ", fiber_new); NATIVE(vm->fiberClass->metaclass, "yield", fiber_yield); NATIVE(vm->fiberClass->metaclass, "yield ", fiber_yield1); NATIVE(vm->fiberClass, "call", fiber_call); NATIVE(vm->fiberClass, "call ", fiber_call1); NATIVE(vm->fiberClass, "isDone", fiber_isDone); NATIVE(vm->fiberClass, "run", fiber_run); NATIVE(vm->fiberClass, "run ", fiber_run1); vm->fnClass = defineClass(vm, "Fn"); NATIVE(vm->fnClass->metaclass, " instantiate", fn_instantiate); NATIVE(vm->fnClass->metaclass, "new ", fn_new); NATIVE(vm->fnClass, "call", fn_call0); NATIVE(vm->fnClass, "call ", fn_call1); NATIVE(vm->fnClass, "call ", fn_call2); NATIVE(vm->fnClass, "call ", fn_call3); NATIVE(vm->fnClass, "call ", fn_call4); NATIVE(vm->fnClass, "call ", fn_call5); NATIVE(vm->fnClass, "call ", fn_call6); NATIVE(vm->fnClass, "call ", fn_call7); NATIVE(vm->fnClass, "call ", fn_call8); NATIVE(vm->fnClass, "call ", fn_call9); NATIVE(vm->fnClass, "call ", fn_call10); NATIVE(vm->fnClass, "call ", fn_call11); NATIVE(vm->fnClass, "call ", fn_call12); NATIVE(vm->fnClass, "call ", fn_call13); NATIVE(vm->fnClass, "call ", fn_call14); NATIVE(vm->fnClass, "call ", fn_call15); NATIVE(vm->fnClass, "call ", fn_call16); NATIVE(vm->fnClass, "toString", fn_toString); vm->nullClass = defineClass(vm, "Null"); NATIVE(vm->nullClass, "toString", null_toString); vm->numClass = defineClass(vm, "Num"); NATIVE(vm->numClass, "abs", num_abs); NATIVE(vm->numClass, "ceil", num_ceil); NATIVE(vm->numClass, "cos", num_cos); NATIVE(vm->numClass, "floor", num_floor); NATIVE(vm->numClass, "isNan", num_isNan); NATIVE(vm->numClass, "sin", num_sin); NATIVE(vm->numClass, "sqrt", num_sqrt); NATIVE(vm->numClass, "toString", num_toString) NATIVE(vm->numClass, "-", num_negate); NATIVE(vm->numClass, "- ", num_minus); NATIVE(vm->numClass, "+ ", num_plus); NATIVE(vm->numClass, "* ", num_multiply); NATIVE(vm->numClass, "/ ", num_divide); NATIVE(vm->numClass, "% ", num_mod); NATIVE(vm->numClass, "< ", num_lt); NATIVE(vm->numClass, "> ", num_gt); NATIVE(vm->numClass, "<= ", num_lte); NATIVE(vm->numClass, ">= ", num_gte); NATIVE(vm->numClass, "~", num_bitwiseNot); NATIVE(vm->numClass, "& ", num_bitwiseAnd); NATIVE(vm->numClass, "| ", num_bitwiseOr); NATIVE(vm->numClass, ".. ", num_dotDot); NATIVE(vm->numClass, "... ", num_dotDotDot); vm->stringClass = defineClass(vm, "String"); NATIVE(vm->stringClass, "contains ", string_contains); NATIVE(vm->stringClass, "count", string_count); NATIVE(vm->stringClass, "toString", string_toString) NATIVE(vm->stringClass, "+ ", string_plus); NATIVE(vm->stringClass, "== ", string_eqeq); NATIVE(vm->stringClass, "!= ", string_bangeq); NATIVE(vm->stringClass, "[ ]", string_subscript); wrenInterpret(vm, "Wren core library", libSource); vm->listClass = AS_CLASS(findGlobal(vm, "List")); NATIVE(vm->listClass->metaclass, " instantiate", list_instantiate); NATIVE(vm->listClass, "add ", list_add); NATIVE(vm->listClass, "clear", list_clear); NATIVE(vm->listClass, "count", list_count); NATIVE(vm->listClass, "insert ", list_insert); NATIVE(vm->listClass, "iterate ", list_iterate); NATIVE(vm->listClass, "iteratorValue ", list_iteratorValue); NATIVE(vm->listClass, "removeAt ", list_removeAt); NATIVE(vm->listClass, "[ ]", list_subscript); NATIVE(vm->listClass, "[ ]=", list_subscriptSetter); vm->rangeClass = AS_CLASS(findGlobal(vm, "Range")); NATIVE(vm->rangeClass, "from", range_from); NATIVE(vm->rangeClass, "to", range_to); NATIVE(vm->rangeClass, "min", range_min); NATIVE(vm->rangeClass, "max", range_max); NATIVE(vm->rangeClass, "isInclusive", range_isInclusive); NATIVE(vm->rangeClass, "iterate ", range_iterate); NATIVE(vm->rangeClass, "iteratorValue ", range_iteratorValue); NATIVE(vm->rangeClass, "toString", range_toString); // These are defined just so that 0 and -0 are equal, which is specified by // IEEE 754 even though they have different bit representations. NATIVE(vm->numClass, "== ", num_eqeq); NATIVE(vm->numClass, "!= ", num_bangeq); }