89 lines
3.5 KiB
C
89 lines
3.5 KiB
C
#ifndef wren_primitive_h
|
|
#define wren_primitive_h
|
|
|
|
#include "wren_vm.h"
|
|
|
|
// Binds a primitive method named [name] (in Wren) implemented using C function
|
|
// [fn] to `ObjClass` [cls].
|
|
#define PRIMITIVE(cls, name, function) \
|
|
{ \
|
|
int symbol = wrenSymbolTableEnsure(vm, \
|
|
&vm->methodNames, name, strlen(name)); \
|
|
Method method; \
|
|
method.type = METHOD_PRIMITIVE; \
|
|
method.as.primitive = prim_##function; \
|
|
wrenBindMethod(vm, cls, symbol, method); \
|
|
}
|
|
|
|
// Defines a primitive method whose C function name is [name]. This abstracts
|
|
// the actual type signature of a primitive function and makes it clear which C
|
|
// functions are invoked as primitives.
|
|
#define DEF_PRIMITIVE(name) \
|
|
static bool prim_##name(WrenVM* vm, Value* args)
|
|
|
|
#define RETURN_VAL(value) do { args[0] = value; return true; } while (0)
|
|
|
|
#define RETURN_OBJ(obj) RETURN_VAL(OBJ_VAL(obj))
|
|
#define RETURN_BOOL(value) RETURN_VAL(BOOL_VAL(value))
|
|
#define RETURN_FALSE RETURN_VAL(FALSE_VAL)
|
|
#define RETURN_NULL RETURN_VAL(NULL_VAL)
|
|
#define RETURN_NUM(value) RETURN_VAL(NUM_VAL(value))
|
|
#define RETURN_TRUE RETURN_VAL(TRUE_VAL)
|
|
|
|
#define RETURN_ERROR(msg) \
|
|
do { \
|
|
vm->fiber->error = wrenNewStringLength(vm, msg, sizeof(msg) - 1); \
|
|
return false; \
|
|
} while (0);
|
|
|
|
#define RETURN_ERROR_FMT(msg, arg) \
|
|
do { \
|
|
vm->fiber->error = wrenStringFormat(vm, msg, arg); \
|
|
return false; \
|
|
} while (0);
|
|
|
|
// Validates that the given [arg] is a function. Returns true if it is. If not,
|
|
// reports an error and returns false.
|
|
bool validateFn(WrenVM* vm, Value arg, const char* argName);
|
|
|
|
// Validates that the given [arg] is a Num. Returns true if it is. If not,
|
|
// reports an error and returns false.
|
|
bool validateNum(WrenVM* vm, Value arg, const char* argName);
|
|
|
|
// Validates that [value] is an integer. Returns true if it is. If not, reports
|
|
// an error and returns false.
|
|
bool validateIntValue(WrenVM* vm, double value, const char* argName);
|
|
|
|
// Validates that the given [arg] is an integer. Returns true if it is. If not,
|
|
// reports an error and returns false.
|
|
bool validateInt(WrenVM* vm, Value arg, const char* argName);
|
|
|
|
// Validates that [arg] is a valid object for use as a map key. Returns true if
|
|
// it is. If not, reports an error and returns false.
|
|
bool validateKey(WrenVM* vm, Value arg);
|
|
|
|
// Validates that the argument at [argIndex] 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
|
|
// `UINT32_MAX`.
|
|
uint32_t validateIndex(WrenVM* vm, Value arg, uint32_t count,
|
|
const char* argName);
|
|
|
|
// Validates that the given [arg] is a String. Returns true if it is. If not,
|
|
// reports an error and returns false.
|
|
bool validateString(WrenVM* vm, Value arg, const char* argName);
|
|
|
|
// Given a [range] and the [length] of the object being operated on, determines
|
|
// the series of elements that should be chosen from the underlying object.
|
|
// Handles ranges that count backwards from the end as well as negative ranges.
|
|
//
|
|
// Returns the index from which the range should start or `UINT32_MAX` if the
|
|
// range is invalid. After calling, [length] will be updated with the number of
|
|
// elements in the resulting sequence. [step] will be direction that the range
|
|
// is going: `1` if the range is increasing from the start index or `-1` if the
|
|
// range is decreasing.
|
|
uint32_t calculateRange(WrenVM* vm, ObjRange* range, uint32_t* length,
|
|
int* step);
|
|
|
|
#endif
|