// Validates that the given argument in [args] is a function. Returns true if // it is. If not, reports an error and returns false. static bool validateFn(WrenVM* vm, Value* args, int index, const char* argName) { if (IS_FN(args[index]) || IS_CLOSURE(args[index])) return true; args[0] = OBJ_VAL(wrenStringConcat(vm, argName, " must be a function.")); return false; }
// 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) { if (IS_NUM(args[index])) return true; args[0] = OBJ_VAL(wrenStringConcat(vm, argName, " must be a number.")); return false; }
// Validates that [value] is an integer. Returns true if it is. If not, reports // an error and returns false. static bool validateIntValue(WrenVM* vm, Value* args, double value, const char* argName) { if (trunc(value) == value) return true; args[0] = OBJ_VAL(wrenStringConcat(vm, argName, " must be an integer.")); return false; }
// Validates that [value] is an integer within `[0, count)`. Also allows // negative indices which map backwards from the end. Returns the valid positive // index value. If invalid, reports an error and returns -1. static int validateIndexValue(WrenVM* vm, Value* args, int count, double value, const char* argName) { if (!validateIntValue(vm, args, value, argName)) return -1; int index = (int)value; // Negative indices count from the end. if (index < 0) index = count + index; // Check bounds. if (index >= 0 && index < count) return index; args[0] = OBJ_VAL(wrenStringConcat(vm, argName, " out of bounds.")); return -1; }
ObjClass* wrenNewClass(WrenVM* vm, ObjClass* superclass, int numFields, ObjString* name) { WREN_PIN(vm, name); // Create the metaclass. ObjString* metaclassName = wrenStringConcat(vm, name->value, " metaclass"); WREN_PIN(vm, metaclassName); ObjClass* metaclass = wrenNewSingleClass(vm, 0, metaclassName); metaclass->obj.classObj = vm->classClass; WREN_UNPIN(vm); // Make sure the metaclass isn't collected when we allocate the class. WREN_PIN(vm, metaclass); // Metaclasses always inherit Class and do not parallel the non-metaclass // hierarchy. wrenBindSuperclass(vm, metaclass, vm->classClass); ObjClass* classObj = wrenNewSingleClass(vm, numFields, name); // Make sure the class isn't collected while the inherited methods are being // bound. WREN_PIN(vm, classObj); classObj->obj.classObj = metaclass; wrenBindSuperclass(vm, classObj, superclass); WREN_UNPIN(vm); WREN_UNPIN(vm); WREN_UNPIN(vm); return classObj; }