Index: pol-core/bscript/object.cpp =================================================================== --- pol-core/bscript/object.cpp (revision 625) +++ pol-core/bscript/object.cpp (working copy) @@ -1399,6 +1399,27 @@ }; +class objref_cmp_member +{ + const char *membername_; + public: + objref_cmp_member(const char *membername) : membername_(membername) {} + bool operator()(const BObjectRef& x1,const BObjectRef& x2) const + { + + const BObject* b1 = x1.get(); + const BObject* b2 = x2.get(); + + if (b1 == NULL || b2 == NULL) + return (&x1 < &x2); + + BObjectRef obj1_member = x1.get()->impptr()->get_member(membername_); + BObjectRef obj2_member = x2.get()->impptr()->get_member(membername_); + + return (obj1_member.get()->impptr()->isLessThan(obj2_member.get()->impref())); + } +}; + BObjectImp* ObjArray::call_method_id( const int id, Executor& ex, bool forcebuiltin ) { switch(id) @@ -1543,6 +1564,350 @@ return new BError( "array.sort() doesn't take parameters." ); } break; + +case MTH_SORT_BY: + if (name_arr.empty()) + { + if (ex.numParams() == 1) + { + BObjectImp* imp = ex.getParamImp( 0 ); + sort( ref_arr.begin(), ref_arr.end(), objref_cmp_member(imp->getStringRep().c_str()) ); + return new BLong(1); + } + else + return new BError( "array.sortby(membername) requires a parameter." ); + } + break; + case MTH_REJECT: + if (name_arr.empty()) + { + unsigned int ex_numParams = ex.numParams(); + if (ex_numParams > 0) + { + ObjArray* ar = new ObjArray; + + const String* membername_str; + BObject* param1; + + if((membername_str = ex.getStringParam( 0 ))==false) + { + return new BError( "Invalid parameter type" ); + } + + if( ex_numParams >= 2 ) + param1 = ex.getParamObj( 1 ); + + std::string membername = membername_str->getStringRep(); + + for( Cont::const_iterator itr = ref_arr.begin(); itr != ref_arr.end(); ++itr ) + { + if ( itr->get() ) + { + BObject *bo = (itr->get()); + + if ( bo == NULL ) + { + cout << scripts_thread_script << " - '" << bo << " in array{}' check. Invalid data at index " << (itr-ref_arr.begin())+1 << endl; + continue; + } else { + + if(bo->isa(OTUninit)) { + ar->addElement(bo->impptr()); + continue; + } + + BObjectRef bo_member = bo->impptr()->get_member(membername.c_str()); + if( ex_numParams == 1 ) { + if(bo_member->isTrue()) + continue; + } else { // has second parameter + if(bo_member->impptr()->isEqual( param1->impref() )) + continue; + } + ar->addElement(bo->impptr()); + } + } + } + + return ar; + } + else + return new BError( "array.reject(membername, membervalue) requires a parameter." ); + } + break; + case MTH_COLLECT: + if (name_arr.empty()) + { + unsigned int ex_numParams = ex.numParams(); + if (ex_numParams > 0) + { + ObjArray* ar = new ObjArray; + + const String* membername_str; + BObject* param1; + + if((membername_str = ex.getStringParam( 0 ))==false) + { + return new BError( "Invalid parameter type" ); + } + + if( ex_numParams >= 2 ) + param1 = ex.getParamObj( 1 ); + + std::string membername = membername_str->getStringRep(); + + for( Cont::const_iterator itr = ref_arr.begin(); itr != ref_arr.end(); ++itr ) + { + if ( itr->get() ) + { + BObject *bo = (itr->get()); + + if ( bo == NULL ) + { + cout << scripts_thread_script << " - '" << bo << " in array{}' check. Invalid data at index " << (itr-ref_arr.begin())+1 << endl; + continue; + } else { + + // skipping uninit + if(bo->isa(OTUninit)) { + continue; + } + + BObjectRef bo_member = bo->impptr()->get_member(membername.c_str()); + if( ex_numParams == 1 ) { + if(bo_member->isTrue()) + ar->addElement(bo->impptr()); + } else { // has second parameter + if(bo_member->impptr()->isEqual( param1->impref() )) + ar->addElement(bo->impptr()); + } + } + } + } + + return ar; + } + else + return new BError( "array.collect(membername, membervalue) requires a parameter." ); + } + break; + + case MTH_JOIN: + if (name_arr.empty()) + { + if (ex.numParams() == 1) + { + BObjectImp* imp = ex.getParamImp( 0 ); + + if (imp) + { + if(imp->isa(OTString)) { + std::stringstream result; + Cont::const_iterator ref_arr_begin = ref_arr.begin(); + std::string sep = imp->getStringRep(); + + for( Cont::const_iterator itr = ref_arr_begin; itr != ref_arr.end(); ++itr ) + { + if ( itr->get() ) + { + BObject *bo = (itr->get()); + + if ( bo == NULL ) + { + cout << scripts_thread_script << " - '" << imp << " in array{}' check. Invalid data at index " << (itr-ref_arr.begin())+1 << endl; + continue; + } else { + if(itr != ref_arr_begin) + result << sep; + + result << bo->impptr()->getStringRep(); + } + } + } + + return new String( result.str() ); + } + else + { + return new BError( "array.join(value) param 0 must be a string." ); + } + } + else + { + return new BError( "Invalid parameter type" ); + } + } + else + { + return new BError( "array.join(value) requires a parameter." ); + } + } + break; + + case MTH_ALL: + if (name_arr.empty()) + { + if (ex.numParams() == 0) + { + for( Cont::const_iterator itr = ref_arr.begin(); itr != ref_arr.end(); ++itr ) + { + if ( itr->get() ) + { + BObject *bo = (itr->get()); + + if ( bo == NULL ) + { + cout << scripts_thread_script << " - '" << " in array{}' check. Invalid data at index " << (itr-ref_arr.begin())+1 << endl; + continue; + } else { + if(bo->isTrue()==false) { + return new BLong(0); + } + } + } + } + return new BLong(1); + + } else { + return new BError( "array.all() doesn't take parameters." ); + } + } + break; + case MTH_ANY: + if (name_arr.empty()) + { + if (ex.numParams() == 0) + { + for( Cont::const_iterator itr = ref_arr.begin(); itr != ref_arr.end(); ++itr ) + { + if ( itr->get() ) + { + BObject *bo = (itr->get()); + + if ( bo == NULL ) + { + cout << scripts_thread_script << " - '" << " in array{}' check. Invalid data at index " << (itr-ref_arr.begin())+1 << endl; + continue; + } else { + if(bo->isTrue()) { + return new BLong(1); + } + } + } + } + return new BLong(0); + + } else { + return new BError( "array.any() doesn't take parameters." ); + } + } + break; + case MTH_REMOVE: + if (name_arr.empty()) + { + if (ex.numParams() == 1) + { + BObjectImp* imp = ex.getParamImp( 0 ); + + if (imp) + { + BObject* bobj = ex.getParamObj( 0 ); + long element_idx = this->contains( bobj->impref() ); + + if(element_idx != 0) { + ref_arr.erase( ref_arr.begin() + element_idx - 1 ); + return new BLong(1); + } + + return new BLong(0); + } else { + return new BError( "Invalid parameter type." ); + } + + } else { + return new BError( "array.remove(value) requires a parameter." ); + } + } + break; + case MTH_REMOVE_ALL: + if (name_arr.empty()) + { + if (ex.numParams() == 1) + { + BObjectImp* imp = ex.getParamImp( 0 ); + + if (imp) + { + BObject* bobj = ex.getParamObj( 0 ); + long element_idx; + long has_element = 0; + + while(( element_idx = this->contains( bobj->impref() ) ) != 0 ) { + ref_arr.erase( ref_arr.begin() + element_idx - 1 ); + has_element = 1; + } + + return new BLong(has_element); + } else { + return new BError( "Invalid parameter type." ); + } + + } else { + return new BError( "array.removeall(value) requires a parameter." ); + } + } + break; + case MTH_POP_RANDOM: + if (name_arr.empty()) + { + if (ex.numParams() == 0) + { + if (ref_arr.size() > 0) + { + int rnd_elem_idx = random_int( ref_arr.size() ); + + const BObjectRef& ref = ref_arr[ rnd_elem_idx ]; + + if (ref.get() == NULL) + return NULL; + + BObjectImp* pop_imp = ref.get()->impptr()->copy(); + + ref_arr.erase( ref_arr.begin() + rnd_elem_idx ); + + return pop_imp; + } + } + else { + return new BError( "array.pop() doesn't take parameters." ); + } + } + break; + case MTH_POP: + if (name_arr.empty()) + { + if (ex.numParams() == 0) + { + if (ref_arr.size() > 0) + { + const BObjectRef& ref = ref_arr[ ref_arr.size() - 1 ]; + + if (ref.get() == NULL) + return NULL; + + BObjectImp* pop_imp = ref.get()->impptr()->copy(); + + ref_arr.erase( ref_arr.end() - 1 ); + + return pop_imp; + } + } + else { + return new BError( "array.poprandom() doesn't take parameters." ); + } + } + break; + case MTH_RANDOMENTRY: if (name_arr.empty()) { Index: pol-core/bscript/objmethods.h =================================================================== --- pol-core/bscript/objmethods.h (revision 625) +++ pol-core/bscript/objmethods.h (working copy) @@ -168,7 +168,16 @@ MTH_JOIN, MTH_FIND, MTH_UPPER, - MTH_LOWER + MTH_LOWER, + MTH_ANY, + MTH_ALL, + MTH_REMOVE, + MTH_REMOVE_ALL, + MTH_POP, + MTH_POP_RANDOM, + MTH_SORT_BY, + MTH_REJECT, + MTH_COLLECT }; Index: pol-core/bscript/parser.cpp =================================================================== --- pol-core/bscript/parser.cpp (revision 625) +++ pol-core/bscript/parser.cpp (working copy) @@ -631,7 +631,16 @@ { MTH_JOIN, "join"}, { MTH_FIND, "find"}, { MTH_UPPER, "upper"}, - { MTH_LOWER, "lower"} + { MTH_LOWER, "lower"}, + { MTH_ALL, "all"}, + { MTH_ANY, "any"}, + { MTH_REMOVE, "remove"}, + { MTH_REMOVE_ALL, "removeall"}, + { MTH_POP, "pop"}, + { MTH_POP_RANDOM, "poprandom"}, + { MTH_SORT_BY, "sortby"}, + { MTH_COLLECT, "collect"}, + { MTH_REJECT, "reject"} }; int n_objmethods = sizeof object_methods / sizeof object_methods[0]; ObjMethod* getKnownObjMethod(const char* token)