static SQInteger array_reduce(HSQUIRRELVM v) { SQObject &o = stack_get(v,1); SQArray *a = _array(o); SQInteger size = a->Size(); if(size == 0) { return 0; } SQObjectPtr res; a->Get(0,res); if(size > 1) { SQObjectPtr other; for(SQInteger n = 1; n < size; n++) { a->Get(n,other); v->Push(o); v->Push(res); v->Push(other); if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { return SQ_ERROR; } res = v->GetUp(-1); v->Pop(); } } v->Push(res); return 1; }
static SQInteger default_delegate_tointeger(HSQUIRRELVM v) { SQObjectPtr &o=stack_get(v,1); switch(type(o)) { case OT_STRING: { SQObjectPtr res; if(str2num(_stringval(o),res)) { v->Push(SQObjectPtr(tointeger(res))); break; } } return sq_throwerror(v, _SC("cannot convert the string")); break; case OT_INTEGER: case OT_FLOAT: v->Push(SQObjectPtr(tointeger(o))); break; case OT_BOOL: v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); break; default: v->Push(_null_); break; } return 1; }
static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) { SQArray *aparams=_array(stack_get(v,2)); SQInteger nparams=aparams->Size(); v->Push(stack_get(v,1)); for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]); return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; }
//GENERATOR DEFAULT DELEGATE static SQInteger generator_getstatus(HSQUIRRELVM v) { SQObject &o=stack_get(v,1); switch(_generator(o)->_state){ case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; } return 1; }
static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { SQObjectPtr temp; SQInteger size = src->Size(); for(SQInteger n = 0; n < size; n++) { src->Get(n,temp); v->Push(src); v->Push(temp); if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) { return SQ_ERROR; } dest->Set(n,v->GetUp(-1)); v->Pop(); } return 0; }
static SQInteger base_setroottable(HSQUIRRELVM v) { SQObjectPtr o = v->_roottable; if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; v->Push(o); return 1; }
static SQInteger base_setconsttable(HSQUIRRELVM v) { SQObjectPtr o = _ss(v)->_consts; if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; v->Push(o); return 1; }
static SQInteger number_delegate_tochar(HSQUIRRELVM v) { SQObject &o=stack_get(v,1); SQChar c = (SQChar)tointeger(o); v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); return 1; }
bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) { if(func < 0) { if(!v->ObjCmp(a,b,ret)) return false; } else { SQInteger top = sq_gettop(v); sq_push(v, func); sq_pushroottable(v); v->Push(a); v->Push(b); if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { if(!sq_isstring( v->_lasterror)) v->Raise_Error(_SC("compare func failed")); return false; } if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { v->Raise_Error(_SC("numeric value expected as return value of the compare function")); return false; } sq_settop(v, top); return true; } return true; }
static SQInteger base_setconsttable(HSQUIRRELVM v) { SQObjectPtr &o=stack_get(v,2); if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; v->Push(o); return 1; }
static SQInteger base_callee(HSQUIRRELVM v) { if(v->_callsstacksize > 1) { v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); return 1; } return sq_throwerror(v,_SC("no closure in the calls stack")); }
static SQInteger array_top(HSQUIRRELVM v) { SQObject &o=stack_get(v,1); if(_array(o)->Size()>0){ v->Push(_array(o)->Top()); return 1; } else return sq_throwerror(v,_SC("top() on a empty array")); }
SQRESULT at(HSQUIRRELVM vm) { SQObjectPtr self = vm->GetAt(vm->_top-2); if (type(self) == OT_STRING) { SQString *selfString = _string(self); SQInteger index = selfString->_len; sq_getinteger(vm, -1, &index); auto begin = selfString->_val; auto end = begin+selfString->_len; try { SQChar *from = NULL; if (index >= 0) { from = begin; utf8::advance(from, index, end); } else { from = end; for (auto i = index; i < 0; ++i) { utf8::prior(from, begin); } } auto to = from; utf8::advance(to, 1, end); SQInteger resultLen = to-from; assert((resultLen >= 0) && "Length of the resulting string should not be negative"); if (resultLen < 0) { sq_pushnull(vm); return 1; } SQChar *resultSequence = vm->_sharedstate->GetScratchPad(resultLen+1); memset(resultSequence, 0, (resultLen+1)*sizeof(SQChar)); memcpy(resultSequence, from, resultLen*sizeof(SQChar)); SQString *result = SQString::Create(vm->_sharedstate, resultSequence); vm->Push(result); } catch (...) { sq_pushnull(vm); } } else { vm->Raise_Error("string::at - Invalid receiver of type %s", GetTypeName(self)); return SQ_ERROR; } return 1; }
SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) { SQObjectPtr o; if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { v->Push(SQClosure::Create(_ss(v), _funcproto(o))); return SQ_OK; } return SQ_ERROR; }
static SQInteger array_map(HSQUIRRELVM v) { SQObject &o = stack_get(v,1); SQInteger size = _array(o)->Size(); SQObjectPtr ret = SQArray::Create(_ss(v),size); if(SQ_FAILED(__map_array(_array(ret),_array(o),v))) return SQ_ERROR; v->Push(ret); return 1; }
SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval) { sq_aux_paramscheck(v, 1); SQObjectPtr *arr; _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); if(_array(*arr)->Size() > 0) { if(pushval != 0){ v->Push(_array(*arr)->Top()); } _array(*arr)->Pop(); return SQ_OK; } return sq_throwerror(v, _SC("empty array")); }
static SQInteger array_remove(HSQUIRRELVM v) { SQObject &o = stack_get(v, 1); SQObject &idx = stack_get(v, 2); if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); SQObjectPtr val; if(_array(o)->Get(tointeger(idx), val)) { _array(o)->Remove(tointeger(idx)); v->Push(val); return 1; } return sq_throwerror(v, _SC("idx out of range")); }
//STRING DEFAULT DELEGATE////////////////////////// static SQInteger string_slice(HSQUIRRELVM v) { SQInteger sidx,eidx; SQObjectPtr o; if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; SQInteger slen = _string(o)->_len; if(sidx < 0)sidx = slen + sidx; if(eidx < 0)eidx = slen + eidx; if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); if(eidx > slen) return sq_throwerror(v,_SC("slice out of range")); v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); return 1; }
SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) { SQObjectPtr o; #ifndef NO_COMPILER if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { v->Push(SQClosure::Create(_ss(v), _funcproto(o))); return SQ_OK; } return SQ_ERROR; #else return sq_throwerror(v,_SC("this is a no compiler build")); #endif }
SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) { SQClass *baseclass = NULL; if(hasbase) { SQObjectPtr &base = stack_get(v,-1); if(type(base) != OT_CLASS) return sq_throwerror(v,_SC("invalid base type")); baseclass = _class(base); } SQClass *newclass = SQClass::Create(_ss(v), baseclass); if(baseclass) v->Pop(); v->Push(newclass); return SQ_OK; }
static SQInteger array_filter(HSQUIRRELVM v) { SQObject &o = stack_get(v,1); SQArray *a = _array(o); SQObjectPtr ret = SQArray::Create(_ss(v),0); SQInteger size = a->Size(); SQObjectPtr val; for(SQInteger n = 0; n < size; n++) { a->Get(n,val); v->Push(o); v->Push(n); v->Push(val); if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { return SQ_ERROR; } if(!v->IsFalse(v->GetUp(-1))) { _array(ret)->Append(val); } v->Pop(); } v->Push(ret); return 1; }
static SQInteger base_array(HSQUIRRELVM v) { SQArray *a; SQObject &size = stack_get(v,2); if(sq_gettop(v) > 2) { a = SQArray::Create(_ss(v),0); a->Resize(tointeger(size),stack_get(v,3)); } else { a = SQArray::Create(_ss(v),tointeger(size)); } v->Push(a); return 1; }
SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase, const SQChar* name) { SQClass *baseclass = NULL; if(hasbase) { SQObjectPtr &base = stack_get(v,-1); if(sqi_type(base) != OT_CLASS) return sq_throwerror(v,_SC("invalid base type")); baseclass = sqi_class(base); } SQClass *newclass = SQClass::Create(_ss(v), baseclass); if (name) newclass->_methods[0].val = SQString::Create(_ss(v), name, -1); if(baseclass) v->Pop(); v->Push(newclass); return SQ_OK; }
static SQInteger array_find(HSQUIRRELVM v) { SQObject &o = stack_get(v,1); SQObjectPtr &val = stack_get(v,2); SQArray *a = _array(o); SQInteger size = a->Size(); SQObjectPtr temp; for(SQInteger n = 0; n < size; n++) { bool res = false; a->Get(n,temp); if(v->IsEqual(temp,val,res) && res) { v->Push(n); return 1; } } return 0; }
HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) { SQSharedState *ss; SQVM *v; ss=_ss(friendvm); v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); new (v) SQVM(ss); if(v->Init(friendvm, initialstacksize)) { friendvm->Push(v); return v; } else { sq_delete(v, SQVM); return NULL; } }
static SQInteger closure_getinfos(HSQUIRRELVM v) { SQObject o = stack_get(v,1); SQTable *res = SQTable::Create(_ss(v),4); if(type(o) == OT_CLOSURE) { SQFunctionProto *f = _closure(o)->_function; SQInteger nparams = f->_nparameters + (f->_varparams?1:0); SQObjectPtr params = SQArray::Create(_ss(v),nparams); SQObjectPtr defparams = SQArray::Create(_ss(v),f->_ndefaultparams); for(SQInteger n = 0; n<f->_nparameters; n++) { _array(params)->Set((SQInteger)n,f->_parameters[n]); } for(SQInteger j = 0; j<f->_ndefaultparams; j++) { _array(defparams)->Set((SQInteger)j,_closure(o)->_defaultparams[j]); } if(f->_varparams) { _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); } res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); res->NewSlot(SQString::Create(_ss(v),_SC("defparams"),-1),defparams); } else { //OT_NATIVECLOSURE SQNativeClosure *nc = _nativeclosure(o); res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); SQObjectPtr typecheck; if(nc->_typecheck.size() > 0) { typecheck = SQArray::Create(_ss(v), nc->_typecheck.size()); for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) { _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); } } res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); } v->Push(res); return 1; }
static SQInteger base_array(HSQUIRRELVM v) { SQArray *a; SQInteger nInitialSize = tointeger(stack_get(v,2)); SQInteger ret = 1; if (nInitialSize < 0) { v->Raise_Error(_SC("can't create/resize array with/to size %d"), nInitialSize); nInitialSize = 0; ret = -1; } if(sq_gettop(v) > 2) { a = SQArray::Create(_ss(v),0); a->Resize(nInitialSize,stack_get(v,3)); } else { a = SQArray::Create(_ss(v),nInitialSize); } v->Push(a); return ret; }
static SQRESULT map_single(HSQUIRRELVM vm) { SQObjectPtr closure = vm->GetAt(vm->_top-1); if ((sq_type(closure) != OT_CLOSURE) && (sq_type(closure) != OT_NATIVECLOSURE)) { vm->Raise_ParamTypeError(1, OT_CLOSURE | OT_NATIVECLOSURE, sq_type(closure)); return 0; } SQObjectPtr result; result.Null(); sq_push(vm, -2); // push self as implicit `this` sq_push(vm, -3); // push self as parameter vm->Call(closure, 2, vm->_top-2, result, SQTrue); sq_pop(vm, 1); // pop self x2 vm->Push(result); return 1; }
static SQInteger array_slice(HSQUIRRELVM v) { SQInteger sidx,eidx; SQObjectPtr o; if(get_slice_params(v,sidx,eidx,o)==-1)return -1; SQInteger alen = _array(o)->Size(); if(sidx < 0)sidx = alen + sidx; if(eidx < 0)eidx = alen + eidx; if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); if(eidx > alen)return sq_throwerror(v,_SC("slice out of range")); SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); SQObjectPtr t; SQInteger count=0; for(SQInteger i=sidx;i<eidx;i++){ _array(o)->Get(i,t); arr->Set(count++,t); } v->Push(arr); return 1; }
void sq_newarray(HSQUIRRELVM v,SQInteger size) { v->Push(SQArray::Create(_ss(v), size)); }