Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sqbaselib.cpp
00001 /* 00002 see copyright notice in squirrel.h 00003 */ 00004 #include "sqpcheader.h" 00005 #include "sqvm.h" 00006 #include "sqstring.h" 00007 #include "sqtable.h" 00008 #include "sqarray.h" 00009 #include "sqfuncproto.h" 00010 #include "sqclosure.h" 00011 #include "sqclass.h" 00012 #include <stdlib.h> 00013 #include <stdarg.h> 00014 #include <ctype.h> 00015 00016 bool str2num(const SQChar *s,SQObjectPtr &res) 00017 { 00018 SQChar *end; 00019 const SQChar *e = s; 00020 SQBool isfloat = SQFalse; 00021 SQChar c; 00022 while((c = *e) != _SC('\0')) 00023 { 00024 if(c == _SC('.') || c == _SC('E')|| c == _SC('e')) { //e and E is for scientific notation 00025 isfloat = SQTrue; 00026 break; 00027 } 00028 e++; 00029 } 00030 if(isfloat){ 00031 SQFloat r = SQFloat(scstrtod(s,&end)); 00032 if(s == end) return false; 00033 res = r; 00034 } 00035 else{ 00036 SQInteger r = SQInteger(scstrtol(s,&end,10)); 00037 if(s == end) return false; 00038 res = r; 00039 } 00040 return true; 00041 } 00042 00043 static SQInteger base_dummy(HSQUIRRELVM v) 00044 { 00045 return 0; 00046 } 00047 00048 #ifndef NO_GARBAGE_COLLECTOR 00049 static SQInteger base_collectgarbage(HSQUIRRELVM v) 00050 { 00051 sq_pushinteger(v, sq_collectgarbage(v)); 00052 return 1; 00053 } 00054 static SQInteger base_resurectureachable(HSQUIRRELVM v) 00055 { 00056 sq_resurrectunreachable(v); 00057 return 1; 00058 } 00059 #endif 00060 00061 static SQInteger base_getroottable(HSQUIRRELVM v) 00062 { 00063 v->Push(v->_roottable); 00064 return 1; 00065 } 00066 00067 static SQInteger base_getconsttable(HSQUIRRELVM v) 00068 { 00069 v->Push(_ss(v)->_consts); 00070 return 1; 00071 } 00072 00073 00074 static SQInteger base_setroottable(HSQUIRRELVM v) 00075 { 00076 SQObjectPtr o = v->_roottable; 00077 if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; 00078 v->Push(o); 00079 return 1; 00080 } 00081 00082 static SQInteger base_setconsttable(HSQUIRRELVM v) 00083 { 00084 SQObjectPtr o = _ss(v)->_consts; 00085 if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; 00086 v->Push(o); 00087 return 1; 00088 } 00089 00090 static SQInteger base_seterrorhandler(HSQUIRRELVM v) 00091 { 00092 sq_seterrorhandler(v); 00093 return 0; 00094 } 00095 00096 static SQInteger base_setdebughook(HSQUIRRELVM v) 00097 { 00098 sq_setdebughook(v); 00099 return 0; 00100 } 00101 00102 static SQInteger base_enabledebuginfo(HSQUIRRELVM v) 00103 { 00104 SQObjectPtr &o=stack_get(v,2); 00105 00106 sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue); 00107 return 0; 00108 } 00109 00110 static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level) 00111 { 00112 SQStackInfos si; 00113 SQInteger seq = 0; 00114 const SQChar *name = NULL; 00115 00116 if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si))) 00117 { 00118 const SQChar *fn = _SC("unknown"); 00119 const SQChar *src = _SC("unknown"); 00120 if(si.funcname)fn = si.funcname; 00121 if(si.source)src = si.source; 00122 sq_newtable(v); 00123 sq_pushstring(v, _SC("func"), -1); 00124 sq_pushstring(v, fn, -1); 00125 sq_newslot(v, -3, SQFalse); 00126 sq_pushstring(v, _SC("src"), -1); 00127 sq_pushstring(v, src, -1); 00128 sq_newslot(v, -3, SQFalse); 00129 sq_pushstring(v, _SC("line"), -1); 00130 sq_pushinteger(v, si.line); 00131 sq_newslot(v, -3, SQFalse); 00132 sq_pushstring(v, _SC("locals"), -1); 00133 sq_newtable(v); 00134 seq=0; 00135 while ((name = sq_getlocal(v, level, seq))) { 00136 sq_pushstring(v, name, -1); 00137 sq_push(v, -2); 00138 sq_newslot(v, -4, SQFalse); 00139 sq_pop(v, 1); 00140 seq++; 00141 } 00142 sq_newslot(v, -3, SQFalse); 00143 return 1; 00144 } 00145 00146 return 0; 00147 } 00148 static SQInteger base_getstackinfos(HSQUIRRELVM v) 00149 { 00150 SQInteger level; 00151 sq_getinteger(v, -1, &level); 00152 return __getcallstackinfos(v,level); 00153 } 00154 00155 static SQInteger base_assert(HSQUIRRELVM v) 00156 { 00157 if(SQVM::IsFalse(stack_get(v,2))){ 00158 return sq_throwerror(v,_SC("assertion failed")); 00159 } 00160 return 0; 00161 } 00162 00163 static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o) 00164 { 00165 SQInteger top = sq_gettop(v); 00166 sidx=0; 00167 eidx=0; 00168 o=stack_get(v,1); 00169 SQObjectPtr &start=stack_get(v,2); 00170 if(type(start)!=OT_NULL && sq_isnumeric(start)){ 00171 sidx=tointeger(start); 00172 } 00173 if(top>2){ 00174 SQObjectPtr &end=stack_get(v,3); 00175 if(sq_isnumeric(end)){ 00176 eidx=tointeger(end); 00177 } 00178 } 00179 else { 00180 eidx = sq_getsize(v,1); 00181 } 00182 return 1; 00183 } 00184 00185 static SQInteger base_print(HSQUIRRELVM v) 00186 { 00187 const SQChar *str; 00188 sq_tostring(v,2); 00189 sq_getstring(v,-1,&str); 00190 if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str); 00191 return 0; 00192 } 00193 00194 static SQInteger base_error(HSQUIRRELVM v) 00195 { 00196 const SQChar *str; 00197 sq_tostring(v,2); 00198 sq_getstring(v,-1,&str); 00199 if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str); 00200 return 0; 00201 } 00202 00203 static SQInteger base_compilestring(HSQUIRRELVM v) 00204 { 00205 SQInteger nargs=sq_gettop(v); 00206 const SQChar *src=NULL,*name=_SC("unnamedbuffer"); 00207 SQInteger size; 00208 sq_getstring(v,2,&src); 00209 size=sq_getsize(v,2); 00210 if(nargs>2){ 00211 sq_getstring(v,3,&name); 00212 } 00213 if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse))) 00214 return 1; 00215 else 00216 return SQ_ERROR; 00217 } 00218 00219 static SQInteger base_newthread(HSQUIRRELVM v) 00220 { 00221 SQObjectPtr &func = stack_get(v,2); 00222 SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2; 00223 HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize); 00224 sq_move(newv,v,-2); 00225 return 1; 00226 } 00227 00228 static SQInteger base_suspend(HSQUIRRELVM v) 00229 { 00230 return sq_suspendvm(v); 00231 } 00232 00233 static SQInteger base_array(HSQUIRRELVM v) 00234 { 00235 SQArray *a; 00236 SQObject &size = stack_get(v,2); 00237 if(sq_gettop(v) > 2) { 00238 a = SQArray::Create(_ss(v),0); 00239 a->Resize(tointeger(size),stack_get(v,3)); 00240 } 00241 else { 00242 a = SQArray::Create(_ss(v),tointeger(size)); 00243 } 00244 v->Push(a); 00245 return 1; 00246 } 00247 00248 static SQInteger base_type(HSQUIRRELVM v) 00249 { 00250 SQObjectPtr &o = stack_get(v,2); 00251 v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); 00252 return 1; 00253 } 00254 00255 static SQInteger base_callee(HSQUIRRELVM v) 00256 { 00257 if(v->_callsstacksize > 1) 00258 { 00259 v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); 00260 return 1; 00261 } 00262 return sq_throwerror(v,_SC("no closure in the calls stack")); 00263 } 00264 00265 static SQRegFunction base_funcs[]={ 00266 //generic 00267 {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, 00268 {_SC("setdebughook"),base_setdebughook,2, NULL}, 00269 {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, 00270 {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, 00271 {_SC("getroottable"),base_getroottable,1, NULL}, 00272 {_SC("setroottable"),base_setroottable,2, NULL}, 00273 {_SC("getconsttable"),base_getconsttable,1, NULL}, 00274 {_SC("setconsttable"),base_setconsttable,2, NULL}, 00275 {_SC("assert"),base_assert,2, NULL}, 00276 {_SC("print"),base_print,2, NULL}, 00277 {_SC("error"),base_error,2, NULL}, 00278 {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, 00279 {_SC("newthread"),base_newthread,2, _SC(".c")}, 00280 {_SC("suspend"),base_suspend,-1, NULL}, 00281 {_SC("array"),base_array,-2, _SC(".n")}, 00282 {_SC("type"),base_type,2, NULL}, 00283 {_SC("callee"),base_callee,0,NULL}, 00284 {_SC("dummy"),base_dummy,0,NULL}, 00285 #ifndef NO_GARBAGE_COLLECTOR 00286 {_SC("collectgarbage"),base_collectgarbage,0, NULL}, 00287 {_SC("resurrectunreachable"),base_resurectureachable,0, NULL}, 00288 #endif 00289 {0,0} 00290 }; 00291 00292 void sq_base_register(HSQUIRRELVM v) 00293 { 00294 SQInteger i=0; 00295 sq_pushroottable(v); 00296 while(base_funcs[i].name!=0) { 00297 sq_pushstring(v,base_funcs[i].name,-1); 00298 sq_newclosure(v,base_funcs[i].f,0); 00299 sq_setnativeclosurename(v,-1,base_funcs[i].name); 00300 sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask); 00301 sq_newslot(v,-3, SQFalse); 00302 i++; 00303 } 00304 00305 sq_pushstring(v,_SC("_versionnumber_"),-1); 00306 sq_pushinteger(v,SQUIRREL_VERSION_NUMBER); 00307 sq_newslot(v,-3, SQFalse); 00308 sq_pushstring(v,_SC("_version_"),-1); 00309 sq_pushstring(v,SQUIRREL_VERSION,-1); 00310 sq_newslot(v,-3, SQFalse); 00311 sq_pushstring(v,_SC("_charsize_"),-1); 00312 sq_pushinteger(v,sizeof(SQChar)); 00313 sq_newslot(v,-3, SQFalse); 00314 sq_pushstring(v,_SC("_intsize_"),-1); 00315 sq_pushinteger(v,sizeof(SQInteger)); 00316 sq_newslot(v,-3, SQFalse); 00317 sq_pushstring(v,_SC("_floatsize_"),-1); 00318 sq_pushinteger(v,sizeof(SQFloat)); 00319 sq_newslot(v,-3, SQFalse); 00320 sq_pop(v,1); 00321 } 00322 00323 static SQInteger default_delegate_len(HSQUIRRELVM v) 00324 { 00325 v->Push(SQInteger(sq_getsize(v,1))); 00326 return 1; 00327 } 00328 00329 static SQInteger default_delegate_tofloat(HSQUIRRELVM v) 00330 { 00331 SQObjectPtr &o=stack_get(v,1); 00332 switch(type(o)){ 00333 case OT_STRING:{ 00334 SQObjectPtr res; 00335 if(str2num(_stringval(o),res)){ 00336 v->Push(SQObjectPtr(tofloat(res))); 00337 break; 00338 }} 00339 return sq_throwerror(v, _SC("cannot convert the string")); 00340 break; 00341 case OT_INTEGER:case OT_FLOAT: 00342 v->Push(SQObjectPtr(tofloat(o))); 00343 break; 00344 case OT_BOOL: 00345 v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0))); 00346 break; 00347 default: 00348 v->PushNull(); 00349 break; 00350 } 00351 return 1; 00352 } 00353 00354 static SQInteger default_delegate_tointeger(HSQUIRRELVM v) 00355 { 00356 SQObjectPtr &o=stack_get(v,1); 00357 switch(type(o)){ 00358 case OT_STRING:{ 00359 SQObjectPtr res; 00360 if(str2num(_stringval(o),res)){ 00361 v->Push(SQObjectPtr(tointeger(res))); 00362 break; 00363 }} 00364 return sq_throwerror(v, _SC("cannot convert the string")); 00365 break; 00366 case OT_INTEGER:case OT_FLOAT: 00367 v->Push(SQObjectPtr(tointeger(o))); 00368 break; 00369 case OT_BOOL: 00370 v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); 00371 break; 00372 default: 00373 v->PushNull(); 00374 break; 00375 } 00376 return 1; 00377 } 00378 00379 static SQInteger default_delegate_tostring(HSQUIRRELVM v) 00380 { 00381 sq_tostring(v,1); 00382 return 1; 00383 } 00384 00385 static SQInteger obj_delegate_weakref(HSQUIRRELVM v) 00386 { 00387 sq_weakref(v,1); 00388 return 1; 00389 } 00390 00391 static SQInteger obj_clear(HSQUIRRELVM v) 00392 { 00393 return sq_clear(v,-1); 00394 } 00395 00396 00397 static SQInteger number_delegate_tochar(HSQUIRRELVM v) 00398 { 00399 SQObject &o=stack_get(v,1); 00400 SQChar c = (SQChar)tointeger(o); 00401 v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); 00402 return 1; 00403 } 00404 00405 00406 00407 ///////////////////////////////////////////////////////////////// 00408 //TABLE DEFAULT DELEGATE 00409 00410 static SQInteger table_rawdelete(HSQUIRRELVM v) 00411 { 00412 if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue))) 00413 return SQ_ERROR; 00414 return 1; 00415 } 00416 00417 00418 static SQInteger container_rawexists(HSQUIRRELVM v) 00419 { 00420 if(SQ_SUCCEEDED(sq_rawget(v,-2))) { 00421 sq_pushbool(v,SQTrue); 00422 return 1; 00423 } 00424 sq_pushbool(v,SQFalse); 00425 return 1; 00426 } 00427 00428 static SQInteger container_rawset(HSQUIRRELVM v) 00429 { 00430 return sq_rawset(v,-3); 00431 } 00432 00433 00434 static SQInteger container_rawget(HSQUIRRELVM v) 00435 { 00436 return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; 00437 } 00438 00439 static SQInteger table_setdelegate(HSQUIRRELVM v) 00440 { 00441 if(SQ_FAILED(sq_setdelegate(v,-2))) 00442 return SQ_ERROR; 00443 sq_push(v,-1); // -1 because sq_setdelegate pops 1 00444 return 1; 00445 } 00446 00447 static SQInteger table_getdelegate(HSQUIRRELVM v) 00448 { 00449 return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR; 00450 } 00451 00452 SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ 00453 {_SC("len"),default_delegate_len,1, _SC("t")}, 00454 {_SC("rawget"),container_rawget,2, _SC("t")}, 00455 {_SC("rawset"),container_rawset,3, _SC("t")}, 00456 {_SC("rawdelete"),table_rawdelete,2, _SC("t")}, 00457 {_SC("rawin"),container_rawexists,2, _SC("t")}, 00458 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 00459 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 00460 {_SC("clear"),obj_clear,1, _SC(".")}, 00461 {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")}, 00462 {_SC("getdelegate"),table_getdelegate,1, _SC(".")}, 00463 {0,0} 00464 }; 00465 00466 //ARRAY DEFAULT DELEGATE/////////////////////////////////////// 00467 00468 static SQInteger array_append(HSQUIRRELVM v) 00469 { 00470 return sq_arrayappend(v,-2); 00471 } 00472 00473 static SQInteger array_extend(HSQUIRRELVM v) 00474 { 00475 _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); 00476 return 0; 00477 } 00478 00479 static SQInteger array_reverse(HSQUIRRELVM v) 00480 { 00481 return sq_arrayreverse(v,-1); 00482 } 00483 00484 static SQInteger array_pop(HSQUIRRELVM v) 00485 { 00486 return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR; 00487 } 00488 00489 static SQInteger array_top(HSQUIRRELVM v) 00490 { 00491 SQObject &o=stack_get(v,1); 00492 if(_array(o)->Size()>0){ 00493 v->Push(_array(o)->Top()); 00494 return 1; 00495 } 00496 else return sq_throwerror(v,_SC("top() on a empty array")); 00497 } 00498 00499 static SQInteger array_insert(HSQUIRRELVM v) 00500 { 00501 SQObject &o=stack_get(v,1); 00502 SQObject &idx=stack_get(v,2); 00503 SQObject &val=stack_get(v,3); 00504 if(!_array(o)->Insert(tointeger(idx),val)) 00505 return sq_throwerror(v,_SC("index out of range")); 00506 return 0; 00507 } 00508 00509 static SQInteger array_remove(HSQUIRRELVM v) 00510 { 00511 SQObject &o = stack_get(v, 1); 00512 SQObject &idx = stack_get(v, 2); 00513 if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); 00514 SQObjectPtr val; 00515 if(_array(o)->Get(tointeger(idx), val)) { 00516 _array(o)->Remove(tointeger(idx)); 00517 v->Push(val); 00518 return 1; 00519 } 00520 return sq_throwerror(v, _SC("idx out of range")); 00521 } 00522 00523 static SQInteger array_resize(HSQUIRRELVM v) 00524 { 00525 SQObject &o = stack_get(v, 1); 00526 SQObject &nsize = stack_get(v, 2); 00527 SQObjectPtr fill; 00528 if(sq_isnumeric(nsize)) { 00529 if(sq_gettop(v) > 2) 00530 fill = stack_get(v, 3); 00531 _array(o)->Resize(tointeger(nsize),fill); 00532 return 0; 00533 } 00534 return sq_throwerror(v, _SC("size must be a number")); 00535 } 00536 00537 static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { 00538 SQObjectPtr temp; 00539 SQInteger size = src->Size(); 00540 for(SQInteger n = 0; n < size; n++) { 00541 src->Get(n,temp); 00542 v->Push(src); 00543 v->Push(temp); 00544 if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) { 00545 return SQ_ERROR; 00546 } 00547 dest->Set(n,v->GetUp(-1)); 00548 v->Pop(); 00549 } 00550 return 0; 00551 } 00552 00553 static SQInteger array_map(HSQUIRRELVM v) 00554 { 00555 SQObject &o = stack_get(v,1); 00556 SQInteger size = _array(o)->Size(); 00557 SQObjectPtr ret = SQArray::Create(_ss(v),size); 00558 if(SQ_FAILED(__map_array(_array(ret),_array(o),v))) 00559 return SQ_ERROR; 00560 v->Push(ret); 00561 return 1; 00562 } 00563 00564 static SQInteger array_apply(HSQUIRRELVM v) 00565 { 00566 SQObject &o = stack_get(v,1); 00567 if(SQ_FAILED(__map_array(_array(o),_array(o),v))) 00568 return SQ_ERROR; 00569 return 0; 00570 } 00571 00572 static SQInteger array_reduce(HSQUIRRELVM v) 00573 { 00574 SQObject &o = stack_get(v,1); 00575 SQArray *a = _array(o); 00576 SQInteger size = a->Size(); 00577 if(size == 0) { 00578 return 0; 00579 } 00580 SQObjectPtr res; 00581 a->Get(0,res); 00582 if(size > 1) { 00583 SQObjectPtr other; 00584 for(SQInteger n = 1; n < size; n++) { 00585 a->Get(n,other); 00586 v->Push(o); 00587 v->Push(res); 00588 v->Push(other); 00589 if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { 00590 return SQ_ERROR; 00591 } 00592 res = v->GetUp(-1); 00593 v->Pop(); 00594 } 00595 } 00596 v->Push(res); 00597 return 1; 00598 } 00599 00600 static SQInteger array_filter(HSQUIRRELVM v) 00601 { 00602 SQObject &o = stack_get(v,1); 00603 SQArray *a = _array(o); 00604 SQObjectPtr ret = SQArray::Create(_ss(v),0); 00605 SQInteger size = a->Size(); 00606 SQObjectPtr val; 00607 for(SQInteger n = 0; n < size; n++) { 00608 a->Get(n,val); 00609 v->Push(o); 00610 v->Push(n); 00611 v->Push(val); 00612 if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { 00613 return SQ_ERROR; 00614 } 00615 if(!SQVM::IsFalse(v->GetUp(-1))) { 00616 _array(ret)->Append(val); 00617 } 00618 v->Pop(); 00619 } 00620 v->Push(ret); 00621 return 1; 00622 } 00623 00624 static SQInteger array_find(HSQUIRRELVM v) 00625 { 00626 SQObject &o = stack_get(v,1); 00627 SQObjectPtr &val = stack_get(v,2); 00628 SQArray *a = _array(o); 00629 SQInteger size = a->Size(); 00630 SQObjectPtr temp; 00631 for(SQInteger n = 0; n < size; n++) { 00632 bool res = false; 00633 a->Get(n,temp); 00634 if(SQVM::IsEqual(temp,val,res) && res) { 00635 v->Push(n); 00636 return 1; 00637 } 00638 } 00639 return 0; 00640 } 00641 00642 00643 bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) 00644 { 00645 if(func < 0) { 00646 if(!v->ObjCmp(a,b,ret)) return false; 00647 } 00648 else { 00649 SQInteger top = sq_gettop(v); 00650 sq_push(v, func); 00651 sq_pushroottable(v); 00652 v->Push(a); 00653 v->Push(b); 00654 if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { 00655 if(!sq_isstring( v->_lasterror)) 00656 v->Raise_Error(_SC("compare func failed")); 00657 return false; 00658 } 00659 if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { 00660 v->Raise_Error(_SC("numeric value expected as return value of the compare function")); 00661 return false; 00662 } 00663 sq_settop(v, top); 00664 return true; 00665 } 00666 return true; 00667 } 00668 00669 bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bottom, SQInteger func) 00670 { 00671 SQInteger maxChild; 00672 SQInteger done = 0; 00673 SQInteger ret; 00674 SQInteger root2; 00675 while (((root2 = root * 2) <= bottom) && (!done)) 00676 { 00677 if (root2 == bottom) { 00678 maxChild = root2; 00679 } 00680 else { 00681 if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret)) 00682 return false; 00683 if (ret > 0) { 00684 maxChild = root2; 00685 } 00686 else { 00687 maxChild = root2 + 1; 00688 } 00689 } 00690 00691 if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret)) 00692 return false; 00693 if (ret < 0) { 00694 if (root == maxChild) { 00695 v->Raise_Error(_SC("inconsistent compare function")); 00696 return false; // We'd be swapping ourselve. The compare function is incorrect 00697 } 00698 00699 _Swap(arr->_values[root],arr->_values[maxChild]); 00700 root = maxChild; 00701 } 00702 else { 00703 done = 1; 00704 } 00705 } 00706 return true; 00707 } 00708 00709 bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func) 00710 { 00711 SQArray *a = _array(arr); 00712 SQInteger i; 00713 SQInteger array_size = a->Size(); 00714 for (i = (array_size / 2); i >= 0; i--) { 00715 if(!_hsort_sift_down(v,a, i, array_size - 1,func)) return false; 00716 } 00717 00718 for (i = array_size-1; i >= 1; i--) 00719 { 00720 _Swap(a->_values[0],a->_values[i]); 00721 if(!_hsort_sift_down(v,a, 0, i-1,func)) return false; 00722 } 00723 return true; 00724 } 00725 00726 static SQInteger array_sort(HSQUIRRELVM v) 00727 { 00728 SQInteger func = -1; 00729 SQObjectPtr &o = stack_get(v,1); 00730 if(_array(o)->Size() > 1) { 00731 if(sq_gettop(v) == 2) func = 2; 00732 if(!_hsort(v, o, 0, _array(o)->Size()-1, func)) 00733 return SQ_ERROR; 00734 00735 } 00736 return 0; 00737 } 00738 00739 static SQInteger array_slice(HSQUIRRELVM v) 00740 { 00741 SQInteger sidx,eidx; 00742 SQObjectPtr o; 00743 if(get_slice_params(v,sidx,eidx,o)==-1)return -1; 00744 SQInteger alen = _array(o)->Size(); 00745 if(sidx < 0)sidx = alen + sidx; 00746 if(eidx < 0)eidx = alen + eidx; 00747 if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); 00748 if(eidx > alen)return sq_throwerror(v,_SC("slice out of range")); 00749 SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); 00750 SQObjectPtr t; 00751 SQInteger count=0; 00752 for(SQInteger i=sidx;i<eidx;i++){ 00753 _array(o)->Get(i,t); 00754 arr->Set(count++,t); 00755 } 00756 v->Push(arr); 00757 return 1; 00758 00759 } 00760 00761 SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ 00762 {_SC("len"),default_delegate_len,1, _SC("a")}, 00763 {_SC("append"),array_append,2, _SC("a")}, 00764 {_SC("extend"),array_extend,2, _SC("aa")}, 00765 {_SC("push"),array_append,2, _SC("a")}, 00766 {_SC("pop"),array_pop,1, _SC("a")}, 00767 {_SC("top"),array_top,1, _SC("a")}, 00768 {_SC("insert"),array_insert,3, _SC("an")}, 00769 {_SC("remove"),array_remove,2, _SC("an")}, 00770 {_SC("resize"),array_resize,-2, _SC("an")}, 00771 {_SC("reverse"),array_reverse,1, _SC("a")}, 00772 {_SC("sort"),array_sort,-1, _SC("ac")}, 00773 {_SC("slice"),array_slice,-1, _SC("ann")}, 00774 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 00775 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 00776 {_SC("clear"),obj_clear,1, _SC(".")}, 00777 {_SC("map"),array_map,2, _SC("ac")}, 00778 {_SC("apply"),array_apply,2, _SC("ac")}, 00779 {_SC("reduce"),array_reduce,2, _SC("ac")}, 00780 {_SC("filter"),array_filter,2, _SC("ac")}, 00781 {_SC("find"),array_find,2, _SC("a.")}, 00782 {0,0} 00783 }; 00784 00785 //STRING DEFAULT DELEGATE////////////////////////// 00786 static SQInteger string_slice(HSQUIRRELVM v) 00787 { 00788 SQInteger sidx,eidx; 00789 SQObjectPtr o; 00790 if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; 00791 SQInteger slen = _string(o)->_len; 00792 if(sidx < 0)sidx = slen + sidx; 00793 if(eidx < 0)eidx = slen + eidx; 00794 if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); 00795 if(eidx > slen) return sq_throwerror(v,_SC("slice out of range")); 00796 v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); 00797 return 1; 00798 } 00799 00800 static SQInteger string_find(HSQUIRRELVM v) 00801 { 00802 SQInteger top,start_idx=0; 00803 const SQChar *str,*substr,*ret; 00804 if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){ 00805 if(top>2)sq_getinteger(v,3,&start_idx); 00806 if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){ 00807 ret=scstrstr(&str[start_idx],substr); 00808 if(ret){ 00809 sq_pushinteger(v,(SQInteger)(ret-str)); 00810 return 1; 00811 } 00812 } 00813 return 0; 00814 } 00815 return sq_throwerror(v,_SC("invalid param")); 00816 } 00817 00818 #define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \ 00819 { \ 00820 SQObject str=stack_get(v,1); \ 00821 SQInteger len=_string(str)->_len; \ 00822 const SQChar *sThis=_stringval(str); \ 00823 SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \ 00824 for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \ 00825 v->Push(SQString::Create(_ss(v),sNew,len)); \ 00826 return 1; \ 00827 } 00828 00829 00830 STRING_TOFUNCZ(tolower) 00831 STRING_TOFUNCZ(toupper) 00832 00833 SQRegFunction SQSharedState::_string_default_delegate_funcz[]={ 00834 {_SC("len"),default_delegate_len,1, _SC("s")}, 00835 {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")}, 00836 {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, 00837 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 00838 {_SC("slice"),string_slice,-1, _SC(" s n n")}, 00839 {_SC("find"),string_find,-2, _SC("s s n ")}, 00840 {_SC("tolower"),string_tolower,1, _SC("s")}, 00841 {_SC("toupper"),string_toupper,1, _SC("s")}, 00842 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 00843 {0,0} 00844 }; 00845 00846 //INTEGER DEFAULT DELEGATE////////////////////////// 00847 SQRegFunction SQSharedState::_number_default_delegate_funcz[]={ 00848 {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, 00849 {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, 00850 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 00851 {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")}, 00852 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 00853 {0,0} 00854 }; 00855 00856 //CLOSURE DEFAULT DELEGATE////////////////////////// 00857 static SQInteger closure_pcall(HSQUIRRELVM v) 00858 { 00859 return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR; 00860 } 00861 00862 static SQInteger closure_call(HSQUIRRELVM v) 00863 { 00864 return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR; 00865 } 00866 00867 static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) 00868 { 00869 SQArray *aparams=_array(stack_get(v,2)); 00870 SQInteger nparams=aparams->Size(); 00871 v->Push(stack_get(v,1)); 00872 for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]); 00873 return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; 00874 } 00875 00876 static SQInteger closure_acall(HSQUIRRELVM v) 00877 { 00878 return _closure_acall(v,SQTrue); 00879 } 00880 00881 static SQInteger closure_pacall(HSQUIRRELVM v) 00882 { 00883 return _closure_acall(v,SQFalse); 00884 } 00885 00886 static SQInteger closure_bindenv(HSQUIRRELVM v) 00887 { 00888 if(SQ_FAILED(sq_bindenv(v,1))) 00889 return SQ_ERROR; 00890 return 1; 00891 } 00892 00893 static SQInteger closure_getinfos(HSQUIRRELVM v) { 00894 SQObject o = stack_get(v,1); 00895 SQTable *res = SQTable::Create(_ss(v),4); 00896 if(type(o) == OT_CLOSURE) { 00897 SQFunctionProto *f = _closure(o)->_function; 00898 SQInteger nparams = f->_nparameters + (f->_varparams?1:0); 00899 SQObjectPtr params = SQArray::Create(_ss(v),nparams); 00900 SQObjectPtr defparams = SQArray::Create(_ss(v),f->_ndefaultparams); 00901 for(SQInteger n = 0; n<f->_nparameters; n++) { 00902 _array(params)->Set((SQInteger)n,f->_parameters[n]); 00903 } 00904 for(SQInteger j = 0; j<f->_ndefaultparams; j++) { 00905 _array(defparams)->Set((SQInteger)j,_closure(o)->_defaultparams[j]); 00906 } 00907 if(f->_varparams) { 00908 _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); 00909 } 00910 res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); 00911 res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); 00912 res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); 00913 res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); 00914 res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); 00915 res->NewSlot(SQString::Create(_ss(v),_SC("defparams"),-1),defparams); 00916 } 00917 else { //OT_NATIVECLOSURE 00918 SQNativeClosure *nc = _nativeclosure(o); 00919 res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); 00920 res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); 00921 res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); 00922 SQObjectPtr typecheck; 00923 if(nc->_typecheck.size() > 0) { 00924 typecheck = 00925 SQArray::Create(_ss(v), nc->_typecheck.size()); 00926 for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) { 00927 _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); 00928 } 00929 } 00930 res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); 00931 } 00932 v->Push(res); 00933 return 1; 00934 } 00935 00936 00937 00938 SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={ 00939 {_SC("call"),closure_call,-1, _SC("c")}, 00940 {_SC("pcall"),closure_pcall,-1, _SC("c")}, 00941 {_SC("acall"),closure_acall,2, _SC("ca")}, 00942 {_SC("pacall"),closure_pacall,2, _SC("ca")}, 00943 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 00944 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 00945 {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")}, 00946 {_SC("getinfos"),closure_getinfos,1, _SC("c")}, 00947 {0,0} 00948 }; 00949 00950 //GENERATOR DEFAULT DELEGATE 00951 static SQInteger generator_getstatus(HSQUIRRELVM v) 00952 { 00953 SQObject &o=stack_get(v,1); 00954 switch(_generator(o)->_state){ 00955 case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; 00956 case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; 00957 case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; 00958 } 00959 return 1; 00960 } 00961 00962 SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ 00963 {_SC("getstatus"),generator_getstatus,1, _SC("g")}, 00964 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 00965 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 00966 {0,0} 00967 }; 00968 00969 //THREAD DEFAULT DELEGATE 00970 static SQInteger thread_call(HSQUIRRELVM v) 00971 { 00972 SQObjectPtr o = stack_get(v,1); 00973 if(type(o) == OT_THREAD) { 00974 SQInteger nparams = sq_gettop(v); 00975 _thread(o)->Push(_thread(o)->_roottable); 00976 for(SQInteger i = 2; i<(nparams+1); i++) 00977 sq_move(_thread(o),v,i); 00978 if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQTrue))) { 00979 sq_move(v,_thread(o),-1); 00980 sq_pop(_thread(o),1); 00981 return 1; 00982 } 00983 v->_lasterror = _thread(o)->_lasterror; 00984 return SQ_ERROR; 00985 } 00986 return sq_throwerror(v,_SC("wrong parameter")); 00987 } 00988 00989 static SQInteger thread_wakeup(HSQUIRRELVM v) 00990 { 00991 SQObjectPtr o = stack_get(v,1); 00992 if(type(o) == OT_THREAD) { 00993 SQVM *thread = _thread(o); 00994 SQInteger state = sq_getvmstate(thread); 00995 if(state != SQ_VMSTATE_SUSPENDED) { 00996 switch(state) { 00997 case SQ_VMSTATE_IDLE: 00998 return sq_throwerror(v,_SC("cannot wakeup a idle thread")); 00999 break; 01000 case SQ_VMSTATE_RUNNING: 01001 return sq_throwerror(v,_SC("cannot wakeup a running thread")); 01002 break; 01003 } 01004 } 01005 01006 SQInteger wakeupret = sq_gettop(v)>1?1:0; 01007 if(wakeupret) { 01008 sq_move(thread,v,2); 01009 } 01010 if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { 01011 sq_move(v,thread,-1); 01012 sq_pop(thread,1); //pop retval 01013 if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { 01014 sq_settop(thread,1); //pop roottable 01015 } 01016 return 1; 01017 } 01018 sq_settop(thread,1); 01019 v->_lasterror = thread->_lasterror; 01020 return SQ_ERROR; 01021 } 01022 return sq_throwerror(v,_SC("wrong parameter")); 01023 } 01024 01025 static SQInteger thread_getstatus(HSQUIRRELVM v) 01026 { 01027 SQObjectPtr &o = stack_get(v,1); 01028 switch(sq_getvmstate(_thread(o))) { 01029 case SQ_VMSTATE_IDLE: 01030 sq_pushstring(v,_SC("idle"),-1); 01031 break; 01032 case SQ_VMSTATE_RUNNING: 01033 sq_pushstring(v,_SC("running"),-1); 01034 break; 01035 case SQ_VMSTATE_SUSPENDED: 01036 sq_pushstring(v,_SC("suspended"),-1); 01037 break; 01038 default: 01039 return sq_throwerror(v,_SC("internal VM error")); 01040 } 01041 return 1; 01042 } 01043 01044 static SQInteger thread_getstackinfos(HSQUIRRELVM v) 01045 { 01046 SQObjectPtr o = stack_get(v,1); 01047 if(type(o) == OT_THREAD) { 01048 SQVM *thread = _thread(o); 01049 SQInteger threadtop = sq_gettop(thread); 01050 SQInteger level; 01051 sq_getinteger(v,-1,&level); 01052 SQRESULT res = __getcallstackinfos(thread,level); 01053 if(SQ_FAILED(res)) 01054 { 01055 sq_settop(thread,threadtop); 01056 if(type(thread->_lasterror) == OT_STRING) { 01057 sq_throwerror(v,_stringval(thread->_lasterror)); 01058 } 01059 else { 01060 sq_throwerror(v,_SC("unknown error")); 01061 } 01062 } 01063 if(res > 0) { 01064 //some result 01065 sq_move(v,thread,-1); 01066 sq_settop(thread,threadtop); 01067 return 1; 01068 } 01069 //no result 01070 sq_settop(thread,threadtop); 01071 return 0; 01072 01073 } 01074 return sq_throwerror(v,_SC("wrong parameter")); 01075 } 01076 01077 SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = { 01078 {_SC("call"), thread_call, -1, _SC("v")}, 01079 {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, 01080 {_SC("getstatus"), thread_getstatus, 1, _SC("v")}, 01081 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 01082 {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")}, 01083 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 01084 {0,0}, 01085 }; 01086 01087 static SQInteger class_getattributes(HSQUIRRELVM v) 01088 { 01089 return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR; 01090 } 01091 01092 static SQInteger class_setattributes(HSQUIRRELVM v) 01093 { 01094 return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR; 01095 } 01096 01097 static SQInteger class_instance(HSQUIRRELVM v) 01098 { 01099 return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR; 01100 } 01101 01102 static SQInteger class_getbase(HSQUIRRELVM v) 01103 { 01104 return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR; 01105 } 01106 01107 static SQInteger class_newmember(HSQUIRRELVM v) 01108 { 01109 SQInteger top = sq_gettop(v); 01110 SQBool bstatic = SQFalse; 01111 if(top == 5) 01112 { 01113 sq_tobool(v,-1,&bstatic); 01114 sq_pop(v,1); 01115 } 01116 01117 if(top < 4) { 01118 sq_pushnull(v); 01119 } 01120 return SQ_SUCCEEDED(sq_newmember(v,-4,bstatic))?1:SQ_ERROR; 01121 } 01122 01123 static SQInteger class_rawnewmember(HSQUIRRELVM v) 01124 { 01125 SQInteger top = sq_gettop(v); 01126 SQBool bstatic = SQFalse; 01127 if(top == 5) 01128 { 01129 sq_tobool(v,-1,&bstatic); 01130 sq_pop(v,1); 01131 } 01132 01133 if(top < 4) { 01134 sq_pushnull(v); 01135 } 01136 return SQ_SUCCEEDED(sq_rawnewmember(v,-4,bstatic))?1:SQ_ERROR; 01137 } 01138 01139 SQRegFunction SQSharedState::_class_default_delegate_funcz[] = { 01140 {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, 01141 {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, 01142 {_SC("rawget"),container_rawget,2, _SC("y")}, 01143 {_SC("rawset"),container_rawset,3, _SC("y")}, 01144 {_SC("rawin"),container_rawexists,2, _SC("y")}, 01145 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 01146 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 01147 {_SC("instance"),class_instance,1, _SC("y")}, 01148 {_SC("getbase"),class_getbase,1, _SC("y")}, 01149 {_SC("newmember"),class_newmember,-3, _SC("y")}, 01150 {_SC("rawnewmember"),class_rawnewmember,-3, _SC("y")}, 01151 {0,0} 01152 }; 01153 01154 01155 static SQInteger instance_getclass(HSQUIRRELVM v) 01156 { 01157 if(SQ_SUCCEEDED(sq_getclass(v,1))) 01158 return 1; 01159 return SQ_ERROR; 01160 } 01161 01162 SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = { 01163 {_SC("getclass"), instance_getclass, 1, _SC("x")}, 01164 {_SC("rawget"),container_rawget,2, _SC("x")}, 01165 {_SC("rawset"),container_rawset,3, _SC("x")}, 01166 {_SC("rawin"),container_rawexists,2, _SC("x")}, 01167 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 01168 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 01169 {0,0} 01170 }; 01171 01172 static SQInteger weakref_ref(HSQUIRRELVM v) 01173 { 01174 if(SQ_FAILED(sq_getweakrefval(v,1))) 01175 return SQ_ERROR; 01176 return 1; 01177 } 01178 01179 SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { 01180 {_SC("ref"),weakref_ref,1, _SC("r")}, 01181 {_SC("weakref"),obj_delegate_weakref,1, NULL }, 01182 {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, 01183 {0,0} 01184 }; 01185
Generated on Tue Jul 12 2022 21:35:49 by
