|
|
|
|
@ -50,7 +50,7 @@ DEF_PRIMITIVE(class_toString)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(fiber_new)
|
|
|
|
|
{
|
|
|
|
|
if (!validateFn(vm, args[1], "Argument")) return PRIM_ERROR;
|
|
|
|
|
if (!validateFn(vm, args[1], "Argument")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
ObjFiber* newFiber = wrenNewFiber(vm, AS_OBJ(args[1]));
|
|
|
|
|
|
|
|
|
|
@ -70,7 +70,7 @@ DEF_PRIMITIVE(fiber_abort)
|
|
|
|
|
vm->fiber->error = args[1];
|
|
|
|
|
|
|
|
|
|
// If the error is explicitly null, it's not really an abort.
|
|
|
|
|
return IS_NULL(args[1]) ? PRIM_VALUE : PRIM_ERROR;
|
|
|
|
|
return IS_NULL(args[1]) ? PRIM_VALUE : PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Transfer execution to [fiber] coming from the current fiber whose stack has
|
|
|
|
|
@ -95,14 +95,14 @@ static PrimitiveResult runFiber(WrenVM* vm, ObjFiber* fiber, Value* args,
|
|
|
|
|
{
|
|
|
|
|
vm->fiber->error = wrenStringFormat(vm, "Cannot $ a finished fiber.",
|
|
|
|
|
isCall ? "call" : "transfer to");
|
|
|
|
|
return PRIM_ERROR;
|
|
|
|
|
return PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!IS_NULL(fiber->error))
|
|
|
|
|
{
|
|
|
|
|
vm->fiber->error = wrenStringFormat(vm, "Cannot $ an aborted fiber.",
|
|
|
|
|
isCall ? "call" : "transfer to");
|
|
|
|
|
return PRIM_ERROR;
|
|
|
|
|
return PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// When the calling fiber resumes, we'll store the result of the call in its
|
|
|
|
|
@ -118,7 +118,7 @@ static PrimitiveResult runFiber(WrenVM* vm, ObjFiber* fiber, Value* args,
|
|
|
|
|
|
|
|
|
|
vm->fiber = fiber;
|
|
|
|
|
|
|
|
|
|
return PRIM_RUN_FIBER;
|
|
|
|
|
return PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(fiber_call)
|
|
|
|
|
@ -151,7 +151,7 @@ DEF_PRIMITIVE(fiber_suspend)
|
|
|
|
|
{
|
|
|
|
|
// Switching to a null fiber tells the interpreter to stop and exit.
|
|
|
|
|
vm->fiber = NULL;
|
|
|
|
|
return PRIM_RUN_FIBER;
|
|
|
|
|
return PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(fiber_transfer)
|
|
|
|
|
@ -167,7 +167,7 @@ DEF_PRIMITIVE(fiber_transfer1)
|
|
|
|
|
DEF_PRIMITIVE(fiber_transferError)
|
|
|
|
|
{
|
|
|
|
|
PrimitiveResult result = runFiber(vm, AS_FIBER(args[0]), args, false, true);
|
|
|
|
|
if (result == PRIM_RUN_FIBER) vm->fiber->error = args[1];
|
|
|
|
|
if (result == PRIM_FIBER) vm->fiber->error = args[1];
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
@ -191,7 +191,7 @@ DEF_PRIMITIVE(fiber_try)
|
|
|
|
|
vm->fiber->stackTop[-1] = NULL_VAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PRIM_RUN_FIBER;
|
|
|
|
|
return PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(fiber_yield)
|
|
|
|
|
@ -208,7 +208,7 @@ DEF_PRIMITIVE(fiber_yield)
|
|
|
|
|
vm->fiber->stackTop[-1] = NULL_VAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PRIM_RUN_FIBER;
|
|
|
|
|
return PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(fiber_yield1)
|
|
|
|
|
@ -231,12 +231,12 @@ DEF_PRIMITIVE(fiber_yield1)
|
|
|
|
|
fiber->stackTop--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PRIM_RUN_FIBER;
|
|
|
|
|
return PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(fn_new)
|
|
|
|
|
{
|
|
|
|
|
if (!validateFn(vm, args[1], "Argument")) return PRIM_ERROR;
|
|
|
|
|
if (!validateFn(vm, args[1], "Argument")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
// The block argument is already a function, so just return it.
|
|
|
|
|
RETURN_VAL(args[1]);
|
|
|
|
|
@ -316,7 +316,7 @@ DEF_PRIMITIVE(list_insert)
|
|
|
|
|
// count + 1 here so you can "insert" at the very end.
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], list->elements.count + 1,
|
|
|
|
|
"Index");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
wrenListInsert(vm, list, args[2], index);
|
|
|
|
|
RETURN_VAL(args[2]);
|
|
|
|
|
@ -333,7 +333,7 @@ DEF_PRIMITIVE(list_iterate)
|
|
|
|
|
RETURN_NUM(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!validateInt(vm, args[1], "Iterator")) return PRIM_ERROR;
|
|
|
|
|
if (!validateInt(vm, args[1], "Iterator")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
// Stop if we're out of bounds.
|
|
|
|
|
double index = AS_NUM(args[1]);
|
|
|
|
|
@ -347,7 +347,7 @@ DEF_PRIMITIVE(list_iteratorValue)
|
|
|
|
|
{
|
|
|
|
|
ObjList* list = AS_LIST(args[0]);
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], list->elements.count, "Iterator");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_VAL(list->elements.data[index]);
|
|
|
|
|
}
|
|
|
|
|
@ -356,7 +356,7 @@ DEF_PRIMITIVE(list_removeAt)
|
|
|
|
|
{
|
|
|
|
|
ObjList* list = AS_LIST(args[0]);
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], list->elements.count, "Index");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_VAL(wrenListRemoveAt(vm, list, index));
|
|
|
|
|
}
|
|
|
|
|
@ -369,7 +369,7 @@ DEF_PRIMITIVE(list_subscript)
|
|
|
|
|
{
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], list->elements.count,
|
|
|
|
|
"Subscript");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_VAL(list->elements.data[index]);
|
|
|
|
|
}
|
|
|
|
|
@ -382,7 +382,7 @@ DEF_PRIMITIVE(list_subscript)
|
|
|
|
|
int step;
|
|
|
|
|
uint32_t count = list->elements.count;
|
|
|
|
|
uint32_t start = calculateRange(vm, AS_RANGE(args[1]), &count, &step);
|
|
|
|
|
if (start == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (start == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
ObjList* result = wrenNewList(vm, count);
|
|
|
|
|
for (uint32_t i = 0; i < count; i++)
|
|
|
|
|
@ -398,7 +398,7 @@ DEF_PRIMITIVE(list_subscriptSetter)
|
|
|
|
|
ObjList* list = AS_LIST(args[0]);
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], list->elements.count,
|
|
|
|
|
"Subscript");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
list->elements.data[index] = args[2];
|
|
|
|
|
RETURN_VAL(args[2]);
|
|
|
|
|
@ -411,7 +411,7 @@ DEF_PRIMITIVE(map_new)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(map_subscript)
|
|
|
|
|
{
|
|
|
|
|
if (!validateKey(vm, args[1])) return PRIM_ERROR;
|
|
|
|
|
if (!validateKey(vm, args[1])) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
ObjMap* map = AS_MAP(args[0]);
|
|
|
|
|
Value value = wrenMapGet(map, args[1]);
|
|
|
|
|
@ -422,7 +422,7 @@ DEF_PRIMITIVE(map_subscript)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(map_subscriptSetter)
|
|
|
|
|
{
|
|
|
|
|
if (!validateKey(vm, args[1])) return PRIM_ERROR;
|
|
|
|
|
if (!validateKey(vm, args[1])) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
wrenMapSet(vm, AS_MAP(args[0]), args[1], args[2]);
|
|
|
|
|
RETURN_VAL(args[2]);
|
|
|
|
|
@ -436,7 +436,7 @@ DEF_PRIMITIVE(map_clear)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(map_containsKey)
|
|
|
|
|
{
|
|
|
|
|
if (!validateKey(vm, args[1])) return PRIM_ERROR;
|
|
|
|
|
if (!validateKey(vm, args[1])) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_BOOL(!IS_UNDEFINED(wrenMapGet(AS_MAP(args[0]), args[1])));
|
|
|
|
|
}
|
|
|
|
|
@ -458,7 +458,7 @@ DEF_PRIMITIVE(map_iterate)
|
|
|
|
|
// Otherwise, start one past the last entry we stopped at.
|
|
|
|
|
if (!IS_NULL(args[1]))
|
|
|
|
|
{
|
|
|
|
|
if (!validateInt(vm, args[1], "Iterator")) return PRIM_ERROR;
|
|
|
|
|
if (!validateInt(vm, args[1], "Iterator")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
if (AS_NUM(args[1]) < 0) RETURN_FALSE;
|
|
|
|
|
index = (uint32_t)AS_NUM(args[1]);
|
|
|
|
|
@ -481,7 +481,7 @@ DEF_PRIMITIVE(map_iterate)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(map_remove)
|
|
|
|
|
{
|
|
|
|
|
if (!validateKey(vm, args[1])) return PRIM_ERROR;
|
|
|
|
|
if (!validateKey(vm, args[1])) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_VAL(wrenMapRemoveKey(vm, AS_MAP(args[0]), args[1]));
|
|
|
|
|
}
|
|
|
|
|
@ -490,7 +490,7 @@ DEF_PRIMITIVE(map_keyIteratorValue)
|
|
|
|
|
{
|
|
|
|
|
ObjMap* map = AS_MAP(args[0]);
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], map->capacity, "Iterator");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
MapEntry* entry = &map->entries[index];
|
|
|
|
|
if (IS_UNDEFINED(entry->key))
|
|
|
|
|
@ -505,7 +505,7 @@ DEF_PRIMITIVE(map_valueIteratorValue)
|
|
|
|
|
{
|
|
|
|
|
ObjMap* map = AS_MAP(args[0]);
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], map->capacity, "Iterator");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
MapEntry* entry = &map->entries[index];
|
|
|
|
|
if (IS_UNDEFINED(entry->key))
|
|
|
|
|
@ -528,7 +528,7 @@ DEF_PRIMITIVE(null_toString)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(num_fromString)
|
|
|
|
|
{
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
ObjString* string = AS_STRING(args[1]);
|
|
|
|
|
|
|
|
|
|
@ -545,7 +545,7 @@ DEF_PRIMITIVE(num_fromString)
|
|
|
|
|
if (errno == ERANGE)
|
|
|
|
|
{
|
|
|
|
|
vm->fiber->error = CONST_STRING(vm, "Number literal is too large.");
|
|
|
|
|
return PRIM_ERROR;
|
|
|
|
|
return PRIM_FIBER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We must have consumed the entire string. Otherwise, it contains non-number
|
|
|
|
|
@ -564,7 +564,7 @@ DEF_PRIMITIVE(num_pi)
|
|
|
|
|
#define DEF_NUM_INFIX(name, op, type) \
|
|
|
|
|
DEF_PRIMITIVE(num_##name) \
|
|
|
|
|
{ \
|
|
|
|
|
if (!validateNum(vm, args[1], "Right operand")) return PRIM_ERROR; \
|
|
|
|
|
if (!validateNum(vm, args[1], "Right operand")) return PRIM_FIBER; \
|
|
|
|
|
RETURN_##type(AS_NUM(args[0]) op AS_NUM(args[1])); \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -581,7 +581,7 @@ DEF_NUM_INFIX(gte, >=, BOOL)
|
|
|
|
|
#define DEF_NUM_BITWISE(name, op) \
|
|
|
|
|
DEF_PRIMITIVE(num_bitwise##name) \
|
|
|
|
|
{ \
|
|
|
|
|
if (!validateNum(vm, args[1], "Right operand")) return PRIM_ERROR; \
|
|
|
|
|
if (!validateNum(vm, args[1], "Right operand")) return PRIM_FIBER; \
|
|
|
|
|
uint32_t left = (uint32_t)AS_NUM(args[0]); \
|
|
|
|
|
uint32_t right = (uint32_t)AS_NUM(args[1]); \
|
|
|
|
|
RETURN_NUM(left op right); \
|
|
|
|
|
@ -614,7 +614,7 @@ DEF_NUM_FN(tan, tan)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(num_mod)
|
|
|
|
|
{
|
|
|
|
|
if (!validateNum(vm, args[1], "Right operand")) return PRIM_ERROR;
|
|
|
|
|
if (!validateNum(vm, args[1], "Right operand")) return PRIM_FIBER;
|
|
|
|
|
RETURN_NUM(fmod(AS_NUM(args[0]), AS_NUM(args[1])));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -638,7 +638,7 @@ DEF_PRIMITIVE(num_bitwiseNot)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(num_dotDot)
|
|
|
|
|
{
|
|
|
|
|
if (!validateNum(vm, args[1], "Right hand side of range")) return PRIM_ERROR;
|
|
|
|
|
if (!validateNum(vm, args[1], "Right hand side of range")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
double from = AS_NUM(args[0]);
|
|
|
|
|
double to = AS_NUM(args[1]);
|
|
|
|
|
@ -647,7 +647,7 @@ DEF_PRIMITIVE(num_dotDot)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(num_dotDotDot)
|
|
|
|
|
{
|
|
|
|
|
if (!validateNum(vm, args[1], "Right hand side of range")) return PRIM_ERROR;
|
|
|
|
|
if (!validateNum(vm, args[1], "Right hand side of range")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
double from = AS_NUM(args[0]);
|
|
|
|
|
double to = AS_NUM(args[1]);
|
|
|
|
|
@ -790,7 +790,7 @@ DEF_PRIMITIVE(range_iterate)
|
|
|
|
|
// Start the iteration.
|
|
|
|
|
if (IS_NULL(args[1])) RETURN_NUM(range->from);
|
|
|
|
|
|
|
|
|
|
if (!validateNum(vm, args[1], "Iterator")) return PRIM_ERROR;
|
|
|
|
|
if (!validateNum(vm, args[1], "Iterator")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
double iterator = AS_NUM(args[1]);
|
|
|
|
|
|
|
|
|
|
@ -837,7 +837,7 @@ DEF_PRIMITIVE(range_toString)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(string_fromCodePoint)
|
|
|
|
|
{
|
|
|
|
|
if (!validateInt(vm, args[1], "Code point")) return PRIM_ERROR;
|
|
|
|
|
if (!validateInt(vm, args[1], "Code point")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
int codePoint = (int)AS_NUM(args[1]);
|
|
|
|
|
if (codePoint < 0)
|
|
|
|
|
@ -857,7 +857,7 @@ DEF_PRIMITIVE(string_byteAt)
|
|
|
|
|
ObjString* string = AS_STRING(args[0]);
|
|
|
|
|
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], string->length, "Index");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_NUM((uint8_t)string->value[index]);
|
|
|
|
|
}
|
|
|
|
|
@ -872,7 +872,7 @@ DEF_PRIMITIVE(string_codePointAt)
|
|
|
|
|
ObjString* string = AS_STRING(args[0]);
|
|
|
|
|
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], string->length, "Index");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
// If we are in the middle of a UTF-8 sequence, indicate that.
|
|
|
|
|
const uint8_t* bytes = (uint8_t*)string->value;
|
|
|
|
|
@ -885,7 +885,7 @@ DEF_PRIMITIVE(string_codePointAt)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(string_contains)
|
|
|
|
|
{
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
ObjString* string = AS_STRING(args[0]);
|
|
|
|
|
ObjString* search = AS_STRING(args[1]);
|
|
|
|
|
@ -895,7 +895,7 @@ DEF_PRIMITIVE(string_contains)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(string_endsWith)
|
|
|
|
|
{
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
ObjString* string = AS_STRING(args[0]);
|
|
|
|
|
ObjString* search = AS_STRING(args[1]);
|
|
|
|
|
@ -909,7 +909,7 @@ DEF_PRIMITIVE(string_endsWith)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(string_indexOf)
|
|
|
|
|
{
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
ObjString* string = AS_STRING(args[0]);
|
|
|
|
|
ObjString* search = AS_STRING(args[1]);
|
|
|
|
|
@ -929,7 +929,7 @@ DEF_PRIMITIVE(string_iterate)
|
|
|
|
|
RETURN_NUM(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!validateInt(vm, args[1], "Iterator")) return PRIM_ERROR;
|
|
|
|
|
if (!validateInt(vm, args[1], "Iterator")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
if (AS_NUM(args[1]) < 0) RETURN_FALSE;
|
|
|
|
|
uint32_t index = (uint32_t)AS_NUM(args[1]);
|
|
|
|
|
@ -955,7 +955,7 @@ DEF_PRIMITIVE(string_iterateByte)
|
|
|
|
|
RETURN_NUM(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!validateInt(vm, args[1], "Iterator")) return PRIM_ERROR;
|
|
|
|
|
if (!validateInt(vm, args[1], "Iterator")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
if (AS_NUM(args[1]) < 0) RETURN_FALSE;
|
|
|
|
|
uint32_t index = (uint32_t)AS_NUM(args[1]);
|
|
|
|
|
@ -971,14 +971,14 @@ DEF_PRIMITIVE(string_iteratorValue)
|
|
|
|
|
{
|
|
|
|
|
ObjString* string = AS_STRING(args[0]);
|
|
|
|
|
uint32_t index = validateIndex(vm, args[1], string->length, "Iterator");
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_ERROR;
|
|
|
|
|
if (index == UINT32_MAX) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_VAL(wrenStringCodePointAt(vm, string, index));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(string_startsWith)
|
|
|
|
|
{
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
|
|
|
|
|
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
ObjString* string = AS_STRING(args[0]);
|
|
|
|
|
ObjString* search = AS_STRING(args[1]);
|
|
|
|
|
@ -991,7 +991,7 @@ DEF_PRIMITIVE(string_startsWith)
|
|
|
|
|
|
|
|
|
|
DEF_PRIMITIVE(string_plus)
|
|
|
|
|
{
|
|
|
|
|
if (!validateString(vm, args[1], "Right operand")) return PRIM_ERROR;
|
|
|
|
|
if (!validateString(vm, args[1], "Right operand")) return PRIM_FIBER;
|
|
|
|
|
RETURN_VAL(wrenStringFormat(vm, "@@", args[0], args[1]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1002,7 +1002,7 @@ DEF_PRIMITIVE(string_subscript)
|
|
|
|
|
if (IS_NUM(args[1]))
|
|
|
|
|
{
|
|
|
|
|
int index = validateIndex(vm, args[1], string->length, "Subscript");
|
|
|
|
|
if (index == -1) return PRIM_ERROR;
|
|
|
|
|
if (index == -1) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_VAL(wrenStringCodePointAt(vm, string, index));
|
|
|
|
|
}
|
|
|
|
|
@ -1015,7 +1015,7 @@ DEF_PRIMITIVE(string_subscript)
|
|
|
|
|
int step;
|
|
|
|
|
uint32_t count = string->length;
|
|
|
|
|
int start = calculateRange(vm, AS_RANGE(args[1]), &count, &step);
|
|
|
|
|
if (start == -1) return PRIM_ERROR;
|
|
|
|
|
if (start == -1) return PRIM_FIBER;
|
|
|
|
|
|
|
|
|
|
RETURN_VAL(wrenNewStringFromRange(vm, string, start, count, step));
|
|
|
|
|
}
|
|
|
|
|
|