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; }
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 __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; }
//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 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; }
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 base_setroottable(HSQUIRRELVM v) { SQObjectPtr o = v->_roottable; if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; v->Push(o); return 1; }
bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) { SQObjectType t; _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType))); switch(t){ case OT_STRING:{ SQInteger len; _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len))); o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); } break; case OT_INTEGER:{ SQInteger i; _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; } case OT_FLOAT:{ SQFloat f; _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; } case OT_NULL: o=_null_; break; default: v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); return false; } return true; }
//QSORT ala Sedgewick bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func) { SQInteger i, j; SQArray *a=_array(arr); SQObjectPtr pivot,t; if( l < r ){ pivot = a->_values[l]; i = l; j = r+1; while(1){ SQInteger ret; do { ++i; if(i > r) break; if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret)) return false; } while( ret <= 0); do { --j; if ( j < 0 ) { v->Raise_Error( _SC("Invalid qsort, probably compare function defect") ); return false; } if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret)) return false; } while( ret > 0 ); if( i >= j ) break; t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t; } t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t; if(!_qsort( v, arr, l, j-1,func)) return false; if(!_qsort( v, arr, j+1, r,func)) return false; } 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; }
bool SafeRead( HSQUIRRELVM v, SQWRITEFUNC read, SQUserPointer up, SQUserPointer dest, SQInteger size ) { if ( size && read( up, dest, size ) != size ) { v->Raise_Error( _SC( "io error, read function failure, the origin stream could be corrupted/trucated" ) ); return false; } return true; }
bool SafeWrite( HSQUIRRELVM v, SQWRITEFUNC write, SQUserPointer up, SQUserPointer dest, SQInteger size ) { if ( write( up, dest, size ) != size ) { v->Raise_Error( _SC( "io error (write function failure)" ) ); return false; } return true; }
static SQInteger base_assert(HSQUIRRELVM v) { if(v->IsFalse(stack_get(v,2))){ return sq_throwerror(v,_SC("assertion failed")); } return 0; }
void sq_setdebughook(HSQUIRRELVM v) { SQObject o = stack_get(v,-1); if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { v->_debughook = o; v->Pop(); } }
void sq_seterrorhandler(HSQUIRRELVM v) { SQObject o = stack_get(v, -1); if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { v->_errorhandler = o; v->Pop(); } }
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; }
bool CheckTag( HSQUIRRELVM v, SQWRITEFUNC read, SQUserPointer up, SQInteger tag ) { SQInteger t; _CHECK_IO( SafeRead( v, read, up, &t, sizeof( t ) ) ); if ( t != tag ) { v->Raise_Error( _SC( "invalid or corrupted closure stream" ) ); return false; } return true; }
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 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; }
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 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; }
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_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; }
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 }
//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; }
//QSORT ala Sedgewick bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,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; } sq_getinteger(v, -1, &ret); sq_settop(v, top); return true; } return true; }
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")); }
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; }