public static ObjNative newNative(NativeFn function) { ObjNative native = (ObjNative)ALLOCATE_OBJ(ObjType.OBJ_NATIVE); native.function = function; return(native); }
private static void defineNative(char[] name, NativeFn function) { push(Value.OBJ_VAL(Object.copyString(name, 0, name.Length))); push(Value.OBJ_VAL(Object.newNative(function))); Table.tableSet(ref vm.globals, Object.AS_STRING(vm.stack[0]), vm.stack[1]); pop(); pop(); }
private static bool callValue(Value_t callee, int argCount) { if (Value.IS_OBJ(callee)) { ObjType _type = Object.OBJ_TYPE(callee); switch (Object.OBJ_TYPE(callee)) { case ObjType.OBJ_BOUND_METHOD: { ObjBoundMethod bound = Object.AS_BOUND_METHOD(callee); vm.stack[vm.stackTop - argCount - 1] = bound.receiver; return(call(bound.method, argCount)); } case ObjType.OBJ_CLASS: { ObjClass klass = Object.AS_CLASS(callee); vm.stack[vm.stackTop - argCount - 1] = Value.OBJ_VAL(Object.newInstance(klass)); Value_t initializer = new Value_t(); if (Table.tableGet(ref klass.methods, vm.initString, ref initializer)) { return(call(Object.AS_CLOSURE(initializer), argCount)); } else if (argCount != 0) { runtimeError("Expected 0 arguments but got {0}.", argCount.ToString()); return(false); } vm.frames[vm.frameCount - 1]._ip_index += 2; // HACK FIX return(true); } case ObjType.OBJ_CLOSURE: return(call(Object.AS_CLOSURE(callee), argCount)); case ObjType.OBJ_NATIVE: { NativeFn native = Object.AS_NATIVE(callee); Value_t result = native(argCount, vm.stackTop - argCount); vm.stackTop -= argCount + 1; push(result); vm.frames[vm.frameCount - 1]._ip_index += 2; // HACK FIX return(true); } default: // Non-callable object type. break; } } runtimeError("Can only call functions and classes."); return(false); }