00001
00002
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 if(scstrstr(s,_SC("."))){
00020 SQFloat r = SQFloat(scstrtod(s,&end));
00021 if(s == end) return false;
00022 res = r;
00023 return true;
00024 }
00025 else{
00026 SQInteger r = SQInteger(scstrtol(s,&end,10));
00027 if(s == end) return false;
00028 res = r;
00029 return true;
00030 }
00031 }
00032
00033 #ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
00034 static SQInteger base_dummy(HSQUIRRELVM v)
00035 {
00036 return 0;
00037 }
00038
00039 #ifndef NO_GARBAGE_COLLECTOR
00040 static SQInteger base_collectgarbage(HSQUIRRELVM v)
00041 {
00042 sq_pushinteger(v, sq_collectgarbage(v));
00043 return 1;
00044 }
00045 #endif
00046
00047 static SQInteger base_getroottable(HSQUIRRELVM v)
00048 {
00049 v->Push(v->_roottable);
00050 return 1;
00051 }
00052
00053 static SQInteger base_getconsttable(HSQUIRRELVM v)
00054 {
00055 v->Push(_ss(v)->_consts);
00056 return 1;
00057 }
00058
00059
00060 static SQInteger base_setroottable(HSQUIRRELVM v)
00061 {
00062 SQObjectPtr &o=stack_get(v,2);
00063 if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
00064 v->Push(o);
00065 return 1;
00066 }
00067
00068 static SQInteger base_setconsttable(HSQUIRRELVM v)
00069 {
00070 SQObjectPtr &o=stack_get(v,2);
00071 if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR;
00072 v->Push(o);
00073 return 1;
00074 }
00075
00076 static SQInteger base_seterrorhandler(HSQUIRRELVM v)
00077 {
00078 sq_seterrorhandler(v);
00079 return 0;
00080 }
00081
00082 static SQInteger base_setdebughook(HSQUIRRELVM v)
00083 {
00084 sq_setdebughook(v);
00085 return 0;
00086 }
00087
00088 static SQInteger base_enabledebuginfo(HSQUIRRELVM v)
00089 {
00090 SQObjectPtr &o=stack_get(v,2);
00091 sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
00092 return 0;
00093 }
00094
00095 static SQInteger base_getstackinfos(HSQUIRRELVM v)
00096 {
00097 SQInteger level;
00098 SQStackInfos si;
00099 SQInteger seq = 0;
00100 const SQChar *name = NULL;
00101 sq_getinteger(v, -1, &level);
00102 if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
00103 {
00104 const SQChar *fn = _SC("unknown");
00105 const SQChar *src = _SC("unknown");
00106 if(si.funcname)fn = si.funcname;
00107 if(si.source)src = si.source;
00108 sq_newtable(v);
00109 sq_pushstring(v, _SC("func"), -1);
00110 sq_pushstring(v, fn, -1);
00111 sq_createslot(v, -3);
00112 sq_pushstring(v, _SC("src"), -1);
00113 sq_pushstring(v, src, -1);
00114 sq_createslot(v, -3);
00115 sq_pushstring(v, _SC("line"), -1);
00116 sq_pushinteger(v, si.line);
00117 sq_createslot(v, -3);
00118 sq_pushstring(v, _SC("locals"), -1);
00119 sq_newtable(v);
00120 seq=0;
00121 while ((name = sq_getlocal(v, level, seq))) {
00122 sq_pushstring(v, name, -1);
00123 sq_push(v, -2);
00124 sq_createslot(v, -4);
00125 sq_pop(v, 1);
00126 seq++;
00127 }
00128 sq_createslot(v, -3);
00129 return 1;
00130 }
00131
00132 return 0;
00133 }
00134 #endif
00135
00136 static SQInteger base_assert(HSQUIRRELVM v)
00137 {
00138 if(v->IsFalse(stack_get(v,2))){
00139 return sq_throwerror(v,_SC("assertion failed"));
00140 }
00141 return 0;
00142 }
00143
00144 static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
00145 {
00146 SQInteger top = sq_gettop(v);
00147 sidx=0;
00148 eidx=0;
00149 o=stack_get(v,1);
00150 SQObjectPtr &start=stack_get(v,2);
00151 if(type(start)!=OT_NULL && sq_isnumeric(start)){
00152 sidx=tointeger(start);
00153 }
00154 if(top>2){
00155 SQObjectPtr &end=stack_get(v,3);
00156 if(sq_isnumeric(end)){
00157 eidx=tointeger(end);
00158 }
00159 }
00160 else {
00161 eidx = sq_getsize(v,1);
00162 }
00163 return 1;
00164 }
00165
00166 static SQInteger base_print(HSQUIRRELVM v)
00167 {
00168 const SQChar *str;
00169 sq_tostring(v,2);
00170 sq_getstring(v,-1,&str);
00171 if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
00172 return 0;
00173 }
00174
00175 #ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
00176 static SQInteger base_compilestring(HSQUIRRELVM v)
00177 {
00178 SQInteger nargs=sq_gettop(v);
00179 const SQChar *src=NULL,*name=_SC("unnamedbuffer");
00180 SQInteger size;
00181 sq_getstring(v,2,&src);
00182 size=sq_getsize(v,2);
00183 if(nargs>2){
00184 sq_getstring(v,3,&name);
00185 }
00186 if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
00187 return 1;
00188 else
00189 return SQ_ERROR;
00190 }
00191
00192 static SQInteger base_newthread(HSQUIRRELVM v)
00193 {
00194 SQObjectPtr &func = stack_get(v,2);
00195 SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
00196 HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
00197 sq_move(newv,v,-2);
00198 return 1;
00199 }
00200
00201 static SQInteger base_suspend(HSQUIRRELVM v)
00202 {
00203 return sq_suspendvm(v);
00204 }
00205 #endif
00206
00207 static SQInteger base_array(HSQUIRRELVM v)
00208 {
00209 SQArray *a;
00210 SQObject &size = stack_get(v,2);
00211 if(sq_gettop(v) > 2) {
00212 a = SQArray::Create(_ss(v),0);
00213 a->Resize(tointeger(size),stack_get(v,3));
00214 }
00215 else {
00216 a = SQArray::Create(_ss(v),tointeger(size));
00217 }
00218 v->Push(a);
00219 return 1;
00220 }
00221
00222 static SQInteger base_type(HSQUIRRELVM v)
00223 {
00224 SQObjectPtr &o = stack_get(v,2);
00225 v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
00226 return 1;
00227 }
00228
00229 static SQRegFunction base_funcs[]={
00230
00231 #ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
00232 {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
00233 {_SC("setdebughook"),base_setdebughook,2, NULL},
00234 {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
00235 {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
00236 {_SC("getroottable"),base_getroottable,1, NULL},
00237 {_SC("setroottable"),base_setroottable,2, NULL},
00238 {_SC("getconsttable"),base_getconsttable,1, NULL},
00239 {_SC("setconsttable"),base_setconsttable,2, NULL},
00240 #endif
00241 {_SC("assert"),base_assert,2, NULL},
00242 {_SC("print"),base_print,2, NULL},
00243 #ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
00244 {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
00245 {_SC("newthread"),base_newthread,2, _SC(".c")},
00246 {_SC("suspend"),base_suspend,-1, NULL},
00247 #endif
00248 {_SC("array"),base_array,-2, _SC(".n")},
00249 {_SC("type"),base_type,2, NULL},
00250 #ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
00251 {_SC("dummy"),base_dummy,0,NULL},
00252 #ifndef NO_GARBAGE_COLLECTOR
00253 {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
00254 #endif
00255 #endif
00256 {0,0,0,0}
00257 };
00258
00259 void sq_base_register(HSQUIRRELVM v)
00260 {
00261 SQInteger i=0;
00262 sq_pushroottable(v);
00263 while(base_funcs[i].name!=0) {
00264 sq_pushstring(v,base_funcs[i].name,-1);
00265 sq_newclosure(v,base_funcs[i].f,0);
00266 sq_setnativeclosurename(v,-1,base_funcs[i].name);
00267 sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
00268 sq_createslot(v,-3);
00269 i++;
00270 }
00271 sq_pushstring(v,_SC("_version_"),-1);
00272 sq_pushstring(v,SQUIRREL_VERSION,-1);
00273 sq_createslot(v,-3);
00274 sq_pushstring(v,_SC("_charsize_"),-1);
00275 sq_pushinteger(v,sizeof(SQChar));
00276 sq_createslot(v,-3);
00277 sq_pushstring(v,_SC("_intsize_"),-1);
00278 sq_pushinteger(v,sizeof(SQInteger));
00279 sq_createslot(v,-3);
00280 sq_pop(v,1);
00281 }
00282
00283 static SQInteger default_delegate_len(HSQUIRRELVM v)
00284 {
00285 v->Push(SQInteger(sq_getsize(v,1)));
00286 return 1;
00287 }
00288
00289 static SQInteger default_delegate_tofloat(HSQUIRRELVM v)
00290 {
00291 SQObjectPtr &o=stack_get(v,1);
00292 switch(type(o)){
00293 case OT_STRING:{
00294 SQObjectPtr res;
00295 if(str2num(_stringval(o),res)){
00296 v->Push(SQObjectPtr(tofloat(res)));
00297 break;
00298 }}
00299 return sq_throwerror(v, _SC("cannot convert the string"));
00300 break;
00301 case OT_INTEGER:case OT_FLOAT:
00302 v->Push(SQObjectPtr(tofloat(o)));
00303 break;
00304 case OT_BOOL:
00305 v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
00306 break;
00307 default:
00308 v->Push(_null_);
00309 break;
00310 }
00311 return 1;
00312 }
00313
00314 static SQInteger default_delegate_tointeger(HSQUIRRELVM v)
00315 {
00316 SQObjectPtr &o=stack_get(v,1);
00317 switch(type(o)){
00318 case OT_STRING:{
00319 SQObjectPtr res;
00320 if(str2num(_stringval(o),res)){
00321 v->Push(SQObjectPtr(tointeger(res)));
00322 break;
00323 }}
00324 return sq_throwerror(v, _SC("cannot convert the string"));
00325 break;
00326 case OT_INTEGER:case OT_FLOAT:
00327 v->Push(SQObjectPtr(tointeger(o)));
00328 break;
00329 case OT_BOOL:
00330 v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));
00331 break;
00332 default:
00333 v->Push(_null_);
00334 break;
00335 }
00336 return 1;
00337 }
00338
00339 static SQInteger default_delegate_tostring(HSQUIRRELVM v)
00340 {
00341 sq_tostring(v,1);
00342 return 1;
00343 }
00344
00345 static SQInteger obj_delegate_weakref(HSQUIRRELVM v)
00346 {
00347 sq_weakref(v,1);
00348 return 1;
00349 }
00350
00351 static SQInteger obj_clear(HSQUIRRELVM v)
00352 {
00353 return sq_clear(v,-1);
00354 }
00355
00356
00357 static SQInteger number_delegate_tochar(HSQUIRRELVM v)
00358 {
00359 SQObject &o=stack_get(v,1);
00360 SQChar c = (SQChar)tointeger(o);
00361 v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
00362 return 1;
00363 }
00364
00365
00367
00368
00369 static SQInteger table_rawdelete(HSQUIRRELVM v)
00370 {
00371 if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
00372 return SQ_ERROR;
00373 return 1;
00374 }
00375
00376
00377 static SQInteger container_rawexists(HSQUIRRELVM v)
00378 {
00379 if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
00380 sq_pushbool(v,SQTrue);
00381 return 1;
00382 }
00383 sq_pushbool(v,SQFalse);
00384 return 1;
00385 }
00386
00387 static SQInteger table_rawset(HSQUIRRELVM v)
00388 {
00389 return sq_rawset(v,-3);
00390 }
00391
00392
00393 static SQInteger table_rawget(HSQUIRRELVM v)
00394 {
00395 return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
00396 }
00397
00398
00399 SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
00400 {_SC("len"),default_delegate_len,1, _SC("t")},
00401 {_SC("rawget"),table_rawget,2, _SC("t")},
00402 {_SC("rawset"),table_rawset,3, _SC("t")},
00403 {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
00404 {_SC("rawin"),container_rawexists,2, _SC("t")},
00405 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00406 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00407 {_SC("clear"),obj_clear,1, _SC(".")},
00408 {0,0,0,0}
00409 };
00410
00411
00412
00413 static SQInteger array_append(HSQUIRRELVM v)
00414 {
00415 return sq_arrayappend(v,-2);
00416 }
00417
00418 static SQInteger array_extend(HSQUIRRELVM v)
00419 {
00420 _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
00421 return 0;
00422 }
00423
00424 static SQInteger array_reverse(HSQUIRRELVM v)
00425 {
00426 return sq_arrayreverse(v,-1);
00427 }
00428
00429 static SQInteger array_pop(HSQUIRRELVM v)
00430 {
00431 return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
00432 }
00433
00434 static SQInteger array_top(HSQUIRRELVM v)
00435 {
00436 SQObject &o=stack_get(v,1);
00437 if(_array(o)->Size()>0){
00438 v->Push(_array(o)->Top());
00439 return 1;
00440 }
00441 else return sq_throwerror(v,_SC("top() on a empty array"));
00442 }
00443
00444 static SQInteger array_insert(HSQUIRRELVM v)
00445 {
00446 SQObject &o=stack_get(v,1);
00447 SQObject &idx=stack_get(v,2);
00448 SQObject &val=stack_get(v,3);
00449 if(!_array(o)->Insert(tointeger(idx),val))
00450 return sq_throwerror(v,_SC("index out of range"));
00451 return 0;
00452 }
00453
00454 static SQInteger array_remove(HSQUIRRELVM v)
00455 {
00456 SQObject &o = stack_get(v, 1);
00457 SQObject &idx = stack_get(v, 2);
00458 if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
00459 SQObjectPtr val;
00460 if(_array(o)->Get(tointeger(idx), val)) {
00461 _array(o)->Remove(tointeger(idx));
00462 v->Push(val);
00463 return 1;
00464 }
00465 return sq_throwerror(v, _SC("idx out of range"));
00466 }
00467
00468 static SQInteger array_resize(HSQUIRRELVM v)
00469 {
00470 SQObject &o = stack_get(v, 1);
00471 SQObject &nsize = stack_get(v, 2);
00472 SQObjectPtr fill;
00473 if(sq_isnumeric(nsize)) {
00474 if(sq_gettop(v) > 2)
00475 fill = stack_get(v, 3);
00476 _array(o)->Resize(tointeger(nsize),fill);
00477 return 0;
00478 }
00479 return sq_throwerror(v, _SC("size must be a number"));
00480 }
00481
00482
00483
00484 bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
00485 {
00486 if(func < 0) {
00487 if(!v->ObjCmp(a,b,ret)) return false;
00488 }
00489 else {
00490 SQInteger top = sq_gettop(v);
00491 sq_push(v, func);
00492 sq_pushroottable(v);
00493 v->Push(a);
00494 v->Push(b);
00495 if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
00496 if(!sq_isstring( v->_lasterror))
00497 v->Raise_Error(_SC("compare func failed"));
00498 return false;
00499 }
00500 sq_getinteger(v, -1, &ret);
00501 sq_settop(v, top);
00502 return true;
00503 }
00504 return true;
00505 }
00506
00507 bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
00508 {
00509 SQInteger i, j;
00510 SQArray *a=_array(arr);
00511 SQObjectPtr pivot,t;
00512 if( l < r ){
00513 pivot = a->_values[l];
00514 i = l; j = r+1;
00515 while(1){
00516 SQInteger ret;
00517 do {
00518 ++i;
00519 if(i > r) break;
00520 if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
00521 return false;
00522 } while( ret <= 0);
00523 do {
00524 --j;
00525 if ( j < 0 ) {
00526 v->Raise_Error( _SC("Invalid qsort, probably compare function defect") );
00527 return false;
00528 }
00529 if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
00530 return false;
00531 }
00532 while( ret > 0 );
00533 if( i >= j ) break;
00534 t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
00535 }
00536 t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
00537 if(!_qsort( v, arr, l, j-1,func)) return false;
00538 if(!_qsort( v, arr, j+1, r,func)) return false;
00539 }
00540 return true;
00541 }
00542
00543 static SQInteger array_sort(HSQUIRRELVM v)
00544 {
00545 SQInteger func = -1;
00546 SQObjectPtr &o = stack_get(v,1);
00547 SQObject &funcobj = stack_get(v,2);
00548 if(_array(o)->Size() > 1) {
00549 if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;
00550 if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
00551 return SQ_ERROR;
00552
00553 }
00554 return 0;
00555 }
00556 static SQInteger array_slice(HSQUIRRELVM v)
00557 {
00558 SQInteger sidx,eidx;
00559 SQObjectPtr o;
00560 if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
00561 SQInteger alen = _array(o)->Size();
00562 if(sidx < 0)sidx = alen + sidx;
00563 if(eidx < 0)eidx = alen + eidx;
00564 if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
00565 if(eidx > alen)return sq_throwerror(v,_SC("slice out of range"));
00566 SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
00567 SQObjectPtr t;
00568 SQInteger count=0;
00569 for(SQInteger i=sidx;i<eidx;i++){
00570 _array(o)->Get(i,t);
00571 arr->Set(count++,t);
00572 }
00573 v->Push(arr);
00574 return 1;
00575
00576 }
00577
00578 SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
00579 {_SC("len"),default_delegate_len,1, _SC("a")},
00580 {_SC("append"),array_append,2, _SC("a")},
00581 {_SC("extend"),array_extend,2, _SC("aa")},
00582 {_SC("push"),array_append,2, _SC("a")},
00583 {_SC("pop"),array_pop,1, _SC("a")},
00584 {_SC("top"),array_top,1, _SC("a")},
00585 {_SC("insert"),array_insert,3, _SC("an")},
00586 {_SC("remove"),array_remove,2, _SC("an")},
00587 {_SC("resize"),array_resize,-2, _SC("an")},
00588 {_SC("reverse"),array_reverse,1, _SC("a")},
00589 {_SC("sort"),array_sort,-1, _SC("ac")},
00590 {_SC("slice"),array_slice,-1, _SC("ann")},
00591 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00592 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00593 {_SC("clear"),obj_clear,1, _SC(".")},
00594 {0,0,0,0}
00595 };
00596
00597
00598 static SQInteger string_slice(HSQUIRRELVM v)
00599 {
00600 SQInteger sidx,eidx;
00601 SQObjectPtr o;
00602 if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
00603 SQInteger slen = _string(o)->_len;
00604 if(sidx < 0)sidx = slen + sidx;
00605 if(eidx < 0)eidx = slen + eidx;
00606 if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
00607 if(eidx > slen) return sq_throwerror(v,_SC("slice out of range"));
00608 v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
00609 return 1;
00610 }
00611
00612 static SQInteger string_find(HSQUIRRELVM v)
00613 {
00614 SQInteger top,start_idx=0;
00615 const SQChar *str,*substr,*ret;
00616 if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
00617 if(top>2)sq_getinteger(v,3,&start_idx);
00618 if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
00619 ret=scstrstr(&str[start_idx],substr);
00620 if(ret){
00621 sq_pushinteger(v,(SQInteger)(ret-str));
00622 return 1;
00623 }
00624 }
00625 return 0;
00626 }
00627 return sq_throwerror(v,_SC("invalid param"));
00628 }
00629
00630 #define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
00631 { \
00632 SQObject str=stack_get(v,1); \
00633 SQInteger len=_string(str)->_len; \
00634 const SQChar *sThis=_stringval(str); \
00635 SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
00636 for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
00637 v->Push(SQString::Create(_ss(v),sNew,len)); \
00638 return 1; \
00639 }
00640
00641
00642 STRING_TOFUNCZ(tolower)
00643 STRING_TOFUNCZ(toupper)
00644
00645 SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
00646 {_SC("len"),default_delegate_len,1, _SC("s")},
00647 {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
00648 {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
00649 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00650 {_SC("slice"),string_slice,-1, _SC(" s n n")},
00651 {_SC("find"),string_find,-2, _SC("s s n ")},
00652 {_SC("tolower"),string_tolower,1, _SC("s")},
00653 {_SC("toupper"),string_toupper,1, _SC("s")},
00654 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00655 {0,0,0,0}
00656 };
00657
00658
00659 SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
00660 {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
00661 {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
00662 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00663 {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
00664 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00665 {0,0,0,0}
00666 };
00667
00668
00669 static SQInteger closure_pcall(HSQUIRRELVM v)
00670 {
00671 return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
00672 }
00673
00674 static SQInteger closure_call(HSQUIRRELVM v)
00675 {
00676 return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
00677 }
00678
00679 static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
00680 {
00681 SQArray *aparams=_array(stack_get(v,2));
00682 SQInteger nparams=aparams->Size();
00683 v->Push(stack_get(v,1));
00684 for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
00685 return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
00686 }
00687
00688 static SQInteger closure_acall(HSQUIRRELVM v)
00689 {
00690 return _closure_acall(v,SQTrue);
00691 }
00692
00693 static SQInteger closure_pacall(HSQUIRRELVM v)
00694 {
00695 return _closure_acall(v,SQFalse);
00696 }
00697
00698 static SQInteger closure_bindenv(HSQUIRRELVM v)
00699 {
00700 if(SQ_FAILED(sq_bindenv(v,1)))
00701 return SQ_ERROR;
00702 return 1;
00703 }
00704
00705 static SQInteger closure_getinfos(HSQUIRRELVM v) {
00706 SQObject o = stack_get(v,1);
00707 SQTable *res = SQTable::Create(_ss(v),4);
00708 if(type(o) == OT_CLOSURE) {
00709 SQFunctionProto *f = _funcproto(_closure(o)->_function);
00710 SQInteger nparams = f->_nparameters + (f->_varparams?1:0);
00711 SQObjectPtr params = SQArray::Create(_ss(v),nparams);
00712 for(SQInteger n = 0; n<f->_nparameters; n++) {
00713 _array(params)->Set((SQInteger)n,f->_parameters[n]);
00714 }
00715 if(f->_varparams) {
00716 _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
00717 }
00718 res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
00719 res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
00720 res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
00721 res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
00722 res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
00723 }
00724 else {
00725 SQNativeClosure *nc = _nativeclosure(o);
00726 res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
00727 res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
00728 res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
00729 SQObjectPtr typecheck;
00730 if(nc->_typecheck.size() > 0) {
00731 typecheck =
00732 SQArray::Create(_ss(v), nc->_typecheck.size());
00733 for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
00734 _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
00735 }
00736 }
00737 res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
00738 }
00739 v->Push(res);
00740 return 1;
00741 }
00742
00743
00744 SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
00745 {_SC("call"),closure_call,-1, _SC("c")},
00746 {_SC("pcall"),closure_pcall,-1, _SC("c")},
00747 {_SC("acall"),closure_acall,2, _SC("ca")},
00748 {_SC("pacall"),closure_pacall,2, _SC("ca")},
00749 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00750 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00751 {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
00752 {_SC("getinfos"),closure_getinfos,1, _SC("c")},
00753 {0,0,0,0}
00754 };
00755
00756
00757 static SQInteger generator_getstatus(HSQUIRRELVM v)
00758 {
00759 SQObject &o=stack_get(v,1);
00760 switch(_generator(o)->_state){
00761 case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
00762 case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
00763 case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
00764 }
00765 return 1;
00766 }
00767
00768 SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
00769 {_SC("getstatus"),generator_getstatus,1, _SC("g")},
00770 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00771 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00772 {0,0,0,0}
00773 };
00774
00775
00776
00777 static SQInteger thread_call(HSQUIRRELVM v)
00778 {
00779
00780 SQObjectPtr o = stack_get(v,1);
00781 if(type(o) == OT_THREAD) {
00782 SQInteger nparams = sq_gettop(v);
00783 _thread(o)->Push(_thread(o)->_roottable);
00784 for(SQInteger i = 2; i<(nparams+1); i++)
00785 sq_move(_thread(o),v,i);
00786 if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
00787 sq_move(v,_thread(o),-1);
00788 sq_pop(_thread(o),1);
00789 return 1;
00790 }
00791 v->_lasterror = _thread(o)->_lasterror;
00792 return SQ_ERROR;
00793 }
00794 return sq_throwerror(v,_SC("wrong parameter"));
00795 }
00796
00797 static SQInteger thread_wakeup(HSQUIRRELVM v)
00798 {
00799 SQObjectPtr o = stack_get(v,1);
00800 if(type(o) == OT_THREAD) {
00801 SQVM *thread = _thread(o);
00802 SQInteger state = sq_getvmstate(thread);
00803 if(state != SQ_VMSTATE_SUSPENDED) {
00804 switch(state) {
00805 case SQ_VMSTATE_IDLE:
00806 return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
00807 break;
00808 case SQ_VMSTATE_RUNNING:
00809 return sq_throwerror(v,_SC("cannot wakeup a running thread"));
00810 break;
00811 }
00812 }
00813
00814 SQInteger wakeupret = sq_gettop(v)>1?1:0;
00815 if(wakeupret) {
00816 sq_move(thread,v,2);
00817 }
00818 if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQFalse))) {
00819 sq_move(v,thread,-1);
00820 sq_pop(thread,1);
00821 if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
00822 sq_settop(thread,1);
00823 }
00824 return 1;
00825 }
00826 sq_settop(thread,1);
00827 v->_lasterror = thread->_lasterror;
00828 return SQ_ERROR;
00829 }
00830 return sq_throwerror(v,_SC("wrong parameter"));
00831 }
00832
00833 static SQInteger thread_getstatus(HSQUIRRELVM v)
00834 {
00835 SQObjectPtr &o = stack_get(v,1);
00836 switch(sq_getvmstate(_thread(o))) {
00837 case SQ_VMSTATE_IDLE:
00838 sq_pushstring(v,_SC("idle"),-1);
00839 break;
00840 case SQ_VMSTATE_RUNNING:
00841 sq_pushstring(v,_SC("running"),-1);
00842 break;
00843 case SQ_VMSTATE_SUSPENDED:
00844 sq_pushstring(v,_SC("suspended"),-1);
00845 break;
00846 default:
00847 return sq_throwerror(v,_SC("internal VM error"));
00848 }
00849 return 1;
00850 }
00851
00852 SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
00853 {_SC("call"), thread_call, -1, _SC("v")},
00854 {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
00855 {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
00856 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00857 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00858 {0,0,0,0},
00859 };
00860
00861 static SQInteger class_getattributes(HSQUIRRELVM v)
00862 {
00863 if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
00864 return 1;
00865 return SQ_ERROR;
00866 }
00867
00868 static SQInteger class_setattributes(HSQUIRRELVM v)
00869 {
00870 if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
00871 return 1;
00872 return SQ_ERROR;
00873 }
00874
00875 static SQInteger class_instance(HSQUIRRELVM v)
00876 {
00877 if(SQ_SUCCEEDED(sq_createinstance(v,-1)))
00878 return 1;
00879 return SQ_ERROR;
00880 }
00881
00882 SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
00883 {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
00884 {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
00885 {_SC("rawin"),container_rawexists,2, _SC("y")},
00886 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00887 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00888 {_SC("instance"),class_instance,1, _SC("y")},
00889 {0,0,0,0}
00890 };
00891
00892 static SQInteger instance_getclass(HSQUIRRELVM v)
00893 {
00894 if(SQ_SUCCEEDED(sq_getclass(v,1)))
00895 return 1;
00896 return SQ_ERROR;
00897 }
00898
00899 SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
00900 {_SC("getclass"), instance_getclass, 1, _SC("x")},
00901 {_SC("rawin"),container_rawexists,2, _SC("x")},
00902 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00903 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00904 {0,0,0,0}
00905 };
00906
00907 static SQInteger weakref_ref(HSQUIRRELVM v)
00908 {
00909 if(SQ_FAILED(sq_getweakrefval(v,1)))
00910 return SQ_ERROR;
00911 return 1;
00912 }
00913
00914 SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
00915 {_SC("ref"),weakref_ref,1, _SC("r")},
00916 {_SC("weakref"),obj_delegate_weakref,1, NULL },
00917 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
00918 {0,0,0,0}
00919 };
00920
00921