Ink_Object *InkNative_Array_Each(Ink_InterpreteEngine *engine, Ink_ContextChain *context, Ink_ArgcType argc, Ink_Object **argv, Ink_Object *this_p) { Ink_Object *base = context->searchSlot(engine, "base"); Ink_Array *array = as<Ink_Array>(base); Ink_Object **args; Ink_Object *ret_tmp; Ink_ArrayValue ret_val; Ink_ArrayValue::size_type i; ASSUME_BASE_TYPE(engine, INK_ARRAY); if (!checkArgument(engine, argc, argv, 1, INK_FUNCTION)) { return NULL_OBJ; } args = (Ink_Object **)malloc(sizeof(Ink_Object *)); for (i = 0; i < array->value.size(); i++) { args[0] = array->value[i] ? array->value[i]->getValue() : UNDEFINED; ret_val.push_back(new Ink_HashTable(ret_tmp = argv[0]->call(engine, context, 1, args))); if (engine->getSignal() != INTER_NONE) { switch (engine->getSignal()) { case INTER_RETURN: free(args); cleanArrayHashTable(ret_val); return engine->getInterruptValue(); // signal penetrated case INTER_DROP: case INTER_BREAK: free(args); cleanArrayHashTable(ret_val); return engine->trapSignal(); // trap the signal case INTER_CONTINUE: engine->trapSignal(); // trap the signal, but do not return continue; default: free(args); cleanArrayHashTable(ret_val); return NULL_OBJ; } } } free(args); return new Ink_Array(engine, ret_val); }
Ink_Object *InkNative_Object_Each(Ink_InterpreteEngine *engine, Ink_ContextChain *context, Ink_ArgcType argc, Ink_Object **argv, Ink_Object *this_p) { Ink_Object *base = context->searchSlot(engine, "base"); Ink_Object **args; Ink_Object *ret_tmp; Ink_HashTable *hash; Ink_ArrayValue ret_val; if (!checkArgument(engine, argc, argv, 1, INK_FUNCTION)) { return NULL_OBJ; } args = (Ink_Object **)malloc(2 * sizeof(Ink_Object *)); for (hash = base->hash_table; hash && hash->getValue(); hash = hash->next) { args[0] = new Ink_String(engine, string(hash->key)); args[1] = hash->getValue() ? hash->getValue() : UNDEFINED; ret_val.push_back(new Ink_HashTable(ret_tmp = argv[0]->call(engine, context, 2, args))); if (engine->getSignal() != INTER_NONE) { switch (engine->getSignal()) { case INTER_RETURN: free(args); cleanArrayHashTable(ret_val); return engine->getInterruptValue(); // signal penetrated case INTER_DROP: case INTER_BREAK: free(args); cleanArrayHashTable(ret_val); return engine->trapSignal(); // trap the signal case INTER_CONTINUE: engine->trapSignal(); // trap the signal, but do not return continue; default: free(args); cleanArrayHashTable(ret_val); return NULL_OBJ; } } } free(args); return new Ink_Array(engine, ret_val); }
Ink_Object *InkNative_Array_Remove(Ink_InterpreteEngine *engine, Ink_ContextChain *context, Ink_ArgcType argc, Ink_Object **argv, Ink_Object *this_p) { Ink_Object *base = context->searchSlot(engine, "base"); // Ink_Object *ret; Ink_Array *tmp; Ink_Object *ret = NULL_OBJ; Ink_ArrayValue::size_type index_begin, index_end, tmp_val; ASSUME_BASE_TYPE(engine, INK_ARRAY); if (!checkArgument(engine, argc, argv, 1, INK_NUMERIC)) { return NULL_OBJ; } tmp = as<Ink_Array>(base); index_begin = getRealIndex(as<Ink_Numeric>(argv[0])->value, tmp->value.size()); if (argc > 1 && argv[1]->type == INK_NUMERIC) { index_end = getRealIndex(as<Ink_Numeric>(argv[1])->value, tmp->value.size()); } else index_end = index_begin; if (index_end > tmp->value.size() || index_end > tmp->value.size()) { InkWarn_Too_Huge_Index(engine); return NULL_OBJ; } if (index_end != index_begin) { if (index_begin > index_end) { tmp_val = index_begin; index_begin = index_end; index_end = tmp_val; } index_end++; cleanArrayHashTable(tmp->value, index_begin, index_end); tmp->value.erase(tmp->value.begin() + index_begin, tmp->value.begin() + index_end); } else { if (tmp->value[index_begin]) ret = tmp->value[index_begin]->getValue(); delete tmp->value[index_begin]; tmp->value.erase(tmp->value.begin() + index_begin); } return ret; }