feat: add arity getter to Fn class and rename numParams to arity

Add a public `arity` getter to the Fn class that returns the number of required arguments for a function. Internally rename the `numParams` field to `arity` across the codebase for consistency, update the C API parameter name from `numParams` to `arity` in `wrenDefineMethod` and `wrenDefineStaticMethod`, and adjust the error message in `callFunction` to use the new field name. Also update documentation to clarify that extra arguments are ignored rather than causing an error, and add a new test file `test/function/arity.wren` verifying arity values from 0 to 4.
This commit is contained in:
Bob Nystrom
2015-01-24 04:33:05 +00:00
parent c65b03ac32
commit 368d9a3052
7 changed files with 46 additions and 28 deletions
+23 -18
View File
@@ -489,23 +489,6 @@ DEF_NATIVE(fiber_yield1)
return PRIM_RUN_FIBER;
}
static PrimitiveResult callFunction(WrenVM* vm, Value* args, int numArgs)
{
ObjFn* fn;
if (IS_CLOSURE(args[0]))
{
fn = AS_CLOSURE(args[0])->fn;
}
else
{
fn = AS_FN(args[0]);
}
if (numArgs < fn->numParams) RETURN_ERROR("Function expects more arguments.");
return PRIM_CALL;
}
DEF_NATIVE(fn_instantiate)
{
// Return the Fn class itself. When we then call "new" on it, it will
@@ -521,6 +504,28 @@ DEF_NATIVE(fn_new)
RETURN_VAL(args[1]);
}
DEF_NATIVE(fn_arity)
{
RETURN_NUM(AS_FN(args[0])->arity);
}
static PrimitiveResult callFunction(WrenVM* vm, Value* args, int numArgs)
{
ObjFn* fn;
if (IS_CLOSURE(args[0]))
{
fn = AS_CLOSURE(args[0])->fn;
}
else
{
fn = AS_FN(args[0]);
}
if (numArgs < fn->arity) RETURN_ERROR("Function expects more arguments.");
return PRIM_CALL;
}
DEF_NATIVE(fn_call0) { return callFunction(vm, args, 0); }
DEF_NATIVE(fn_call1) { return callFunction(vm, args, 1); }
DEF_NATIVE(fn_call2) { return callFunction(vm, args, 2); }
@@ -1245,6 +1250,7 @@ void wrenInitializeCore(WrenVM* vm)
NATIVE(vm->fnClass->obj.classObj, " instantiate", fn_instantiate);
NATIVE(vm->fnClass->obj.classObj, "new ", fn_new);
NATIVE(vm->fnClass, "arity", fn_arity);
NATIVE(vm->fnClass, "call", fn_call0);
NATIVE(vm->fnClass, "call ", fn_call1);
NATIVE(vm->fnClass, "call ", fn_call2);
@@ -1262,7 +1268,6 @@ void wrenInitializeCore(WrenVM* vm)
NATIVE(vm->fnClass, "call ", fn_call14);
NATIVE(vm->fnClass, "call ", fn_call15);
NATIVE(vm->fnClass, "call ", fn_call16);
// TODO: "arity" getter.
NATIVE(vm->fnClass, "toString", fn_toString);
vm->nullClass = defineClass(vm, "Null");
+2 -2
View File
@@ -160,7 +160,7 @@ ObjFiber* wrenNewFiber(WrenVM* vm, Obj* fn)
}
ObjFn* wrenNewFunction(WrenVM* vm, Value* constants, int numConstants,
int numUpvalues, int numParams,
int numUpvalues, int arity,
uint8_t* bytecode, int bytecodeLength,
ObjString* debugSourcePath,
const char* debugName, int debugNameLength,
@@ -200,7 +200,7 @@ ObjFn* wrenNewFunction(WrenVM* vm, Value* constants, int numConstants,
fn->constants = copiedConstants;
fn->numUpvalues = numUpvalues;
fn->numConstants = numConstants;
fn->numParams = numParams;
fn->arity = arity;
fn->bytecodeLength = bytecodeLength;
fn->debug = debug;
+2 -2
View File
@@ -246,7 +246,7 @@ typedef struct
// The number of parameters this function expects. Used to ensure that .call
// handles a mismatch between number of parameters and arguments. This will
// only be set for fns, and not ObjFns that represent methods or scripts.
int numParams;
int arity;
FnDebug* debug;
} ObjFn;
@@ -571,7 +571,7 @@ ObjFiber* wrenNewFiber(WrenVM* vm, Obj* fn);
// function will take over ownership of [bytecode] and [sourceLines]. It will
// copy [constants] into its own array.
ObjFn* wrenNewFunction(WrenVM* vm, Value* constants, int numConstants,
int numUpvalues, int numParams,
int numUpvalues, int arity,
uint8_t* bytecode, int bytecodeLength,
ObjString* debugSourcePath,
const char* debugName, int debugNameLength,