~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

Viewing changes to src/sdk/scripting/squirrel/sqbaselib.cpp

  • Committer: damienlmoore at gmail
  • Date: 2016-02-02 02:43:22 UTC
  • Revision ID: damienlmoore@gmail.com-20160202024322-yql5qmtbwdyamdwd
Code::BlocksĀ 16.01

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        see copyright notice in squirrel.h
 
3
*/
 
4
#include "sqpcheader.h"
 
5
#include "sqvm.h"
 
6
#include "sqstring.h"
 
7
#include "sqtable.h"
 
8
#include "sqarray.h"
 
9
#include "sqfuncproto.h"
 
10
#include "sqclosure.h"
 
11
#include "sqclass.h"
 
12
#include <stdlib.h>
 
13
#include <stdarg.h>
 
14
#include <ctype.h>
 
15
 
 
16
bool str2num(const SQChar *s,SQObjectPtr &res)
 
17
{
 
18
        SQChar *end;
 
19
        if(scstrstr(s,_SC("."))){
 
20
                SQFloat r = SQFloat(scstrtod(s,&end));
 
21
                if(s == end) return false;
 
22
                res = r;
 
23
                return true;
 
24
        }
 
25
        else{
 
26
                SQInteger r = SQInteger(scstrtol(s,&end,10));
 
27
                if(s == end) return false;
 
28
                res = r;
 
29
                return true;
 
30
        }
 
31
}
 
32
 
 
33
// C::B patch: Make the compiler happy by commenting unused variables
 
34
static SQInteger base_dummy(HSQUIRRELVM /*v*/)
 
35
{
 
36
        return 0;
 
37
}
 
38
 
 
39
#ifndef NO_GARBAGE_COLLECTOR
 
40
static SQInteger base_collectgarbage(HSQUIRRELVM v)
 
41
{
 
42
        sq_pushinteger(v, sq_collectgarbage(v));
 
43
        return 1;
 
44
}
 
45
#endif
 
46
 
 
47
static SQInteger base_getroottable(HSQUIRRELVM v)
 
48
{
 
49
        v->Push(v->_roottable);
 
50
        return 1;
 
51
}
 
52
 
 
53
static SQInteger base_getconsttable(HSQUIRRELVM v)
 
54
{
 
55
        v->Push(_ss(v)->_consts);
 
56
        return 1;
 
57
}
 
58
 
 
59
 
 
60
static SQInteger base_setroottable(HSQUIRRELVM v)
 
61
{
 
62
        SQObjectPtr &o=stack_get(v,2);
 
63
        if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
 
64
        v->Push(o);
 
65
        return 1;
 
66
}
 
67
 
 
68
static SQInteger base_setconsttable(HSQUIRRELVM v)
 
69
{
 
70
        SQObjectPtr &o=stack_get(v,2);
 
71
        if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR;
 
72
        v->Push(o);
 
73
        return 1;
 
74
}
 
75
 
 
76
static SQInteger base_seterrorhandler(HSQUIRRELVM v)
 
77
{
 
78
        sq_seterrorhandler(v);
 
79
        return 0;
 
80
}
 
81
 
 
82
static SQInteger base_setdebughook(HSQUIRRELVM v)
 
83
{
 
84
        sq_setdebughook(v);
 
85
        return 0;
 
86
}
 
87
 
 
88
static SQInteger base_enabledebuginfo(HSQUIRRELVM v)
 
89
{
 
90
        SQObjectPtr &o=stack_get(v,2);
 
91
        sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
 
92
        return 0;
 
93
}
 
94
 
 
95
static SQInteger base_getstackinfos(HSQUIRRELVM v)
 
96
{
 
97
        SQInteger level;
 
98
        SQStackInfos si;
 
99
        SQInteger seq = 0;
 
100
        const SQChar *name = NULL;
 
101
        sq_getinteger(v, -1, &level);
 
102
        if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
 
103
        {
 
104
                const SQChar *fn = _SC("unknown");
 
105
                const SQChar *src = _SC("unknown");
 
106
                if(si.funcname)fn = si.funcname;
 
107
                if(si.source)src = si.source;
 
108
                sq_newtable(v);
 
109
                sq_pushstring(v, _SC("func"), -1);
 
110
                sq_pushstring(v, fn, -1);
 
111
                sq_createslot(v, -3);
 
112
                sq_pushstring(v, _SC("src"), -1);
 
113
                sq_pushstring(v, src, -1);
 
114
                sq_createslot(v, -3);
 
115
                sq_pushstring(v, _SC("line"), -1);
 
116
                sq_pushinteger(v, si.line);
 
117
                sq_createslot(v, -3);
 
118
                sq_pushstring(v, _SC("locals"), -1);
 
119
                sq_newtable(v);
 
120
                seq=0;
 
121
                while ((name = sq_getlocal(v, level, seq))) {
 
122
                        sq_pushstring(v, name, -1);
 
123
                        sq_push(v, -2);
 
124
                        sq_createslot(v, -4);
 
125
                        sq_pop(v, 1);
 
126
                        seq++;
 
127
                }
 
128
                sq_createslot(v, -3);
 
129
                return 1;
 
130
        }
 
131
 
 
132
        return 0;
 
133
}
 
134
 
 
135
static SQInteger base_assert(HSQUIRRELVM v)
 
136
{
 
137
        if(v->IsFalse(stack_get(v,2))){
 
138
                return sq_throwerror(v,_SC("assertion failed"));
 
139
        }
 
140
        return 0;
 
141
}
 
142
 
 
143
static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
 
144
{
 
145
        SQInteger top = sq_gettop(v);
 
146
        sidx=0;
 
147
        eidx=0;
 
148
        o=stack_get(v,1);
 
149
        SQObjectPtr &start=stack_get(v,2);
 
150
        if(type(start)!=OT_NULL && sq_isnumeric(start)){
 
151
                sidx=tointeger(start);
 
152
        }
 
153
        if(top>2){
 
154
                SQObjectPtr &end=stack_get(v,3);
 
155
                if(sq_isnumeric(end)){
 
156
                        eidx=tointeger(end);
 
157
                }
 
158
        }
 
159
        else {
 
160
                eidx = sq_getsize(v,1);
 
161
        }
 
162
        return 1;
 
163
}
 
164
 
 
165
static SQInteger base_print(HSQUIRRELVM v)
 
166
{
 
167
        const SQChar *str;
 
168
        sq_tostring(v,2);
 
169
        sq_getstring(v,-1,&str);
 
170
        if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
 
171
        return 0;
 
172
}
 
173
 
 
174
static SQInteger base_compilestring(HSQUIRRELVM v)
 
175
{
 
176
        SQInteger nargs=sq_gettop(v);
 
177
        const SQChar *src=NULL,*name=_SC("unnamedbuffer");
 
178
        SQInteger size;
 
179
        sq_getstring(v,2,&src);
 
180
        size=sq_getsize(v,2);
 
181
        if(nargs>2){
 
182
                sq_getstring(v,3,&name);
 
183
        }
 
184
        if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
 
185
                return 1;
 
186
        else
 
187
                return SQ_ERROR;
 
188
}
 
189
 
 
190
static SQInteger base_newthread(HSQUIRRELVM v)
 
191
{
 
192
        SQObjectPtr &func = stack_get(v,2);
 
193
        SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
 
194
        HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
 
195
        sq_move(newv,v,-2);
 
196
        return 1;
 
197
}
 
198
 
 
199
static SQInteger base_suspend(HSQUIRRELVM v)
 
200
{
 
201
        return sq_suspendvm(v);
 
202
}
 
203
 
 
204
static SQInteger base_array(HSQUIRRELVM v)
 
205
{
 
206
        SQArray *a;
 
207
        SQObject &size = stack_get(v,2);
 
208
        if(sq_gettop(v) > 2) {
 
209
                a = SQArray::Create(_ss(v),0);
 
210
                a->Resize(tointeger(size),stack_get(v,3));
 
211
        }
 
212
        else {
 
213
                a = SQArray::Create(_ss(v),tointeger(size));
 
214
        }
 
215
        v->Push(a);
 
216
        return 1;
 
217
}
 
218
 
 
219
static SQInteger base_type(HSQUIRRELVM v)
 
220
{
 
221
        SQObjectPtr &o = stack_get(v,2);
 
222
        v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
 
223
        return 1;
 
224
}
 
225
 
 
226
static SQRegFunction base_funcs[]={
 
227
        //generic
 
228
        {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
 
229
        {_SC("setdebughook"),base_setdebughook,2, NULL},
 
230
        {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
 
231
        {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
 
232
        {_SC("getroottable"),base_getroottable,1, NULL},
 
233
        {_SC("setroottable"),base_setroottable,2, NULL},
 
234
        {_SC("getconsttable"),base_getconsttable,1, NULL},
 
235
        {_SC("setconsttable"),base_setconsttable,2, NULL},
 
236
        {_SC("assert"),base_assert,2, NULL},
 
237
        {_SC("print"),base_print,2, NULL},
 
238
        {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
 
239
        {_SC("newthread"),base_newthread,2, _SC(".c")},
 
240
        {_SC("suspend"),base_suspend,-1, NULL},
 
241
        {_SC("array"),base_array,-2, _SC(".n")},
 
242
        {_SC("type"),base_type,2, NULL},
 
243
        {_SC("dummy"),base_dummy,0,NULL},
 
244
#ifndef NO_GARBAGE_COLLECTOR
 
245
        {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
 
246
#endif
 
247
        {0,0}
 
248
};
 
249
 
 
250
void sq_base_register(HSQUIRRELVM v)
 
251
{
 
252
        SQInteger i=0;
 
253
        sq_pushroottable(v);
 
254
        while(base_funcs[i].name!=0) {
 
255
                sq_pushstring(v,base_funcs[i].name,-1);
 
256
                sq_newclosure(v,base_funcs[i].f,0);
 
257
                sq_setnativeclosurename(v,-1,base_funcs[i].name);
 
258
                sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
 
259
                sq_createslot(v,-3);
 
260
                i++;
 
261
        }
 
262
        sq_pushstring(v,_SC("_version_"),-1);
 
263
        sq_pushstring(v,SQUIRREL_VERSION,-1);
 
264
        sq_createslot(v,-3);
 
265
        sq_pushstring(v,_SC("_charsize_"),-1);
 
266
        sq_pushinteger(v,sizeof(SQChar));
 
267
        sq_createslot(v,-3);
 
268
        sq_pushstring(v,_SC("_intsize_"),-1);
 
269
        sq_pushinteger(v,sizeof(SQInteger));
 
270
        sq_createslot(v,-3);
 
271
        sq_pushstring(v,_SC("_floatsize_"),-1);
 
272
        sq_pushinteger(v,sizeof(SQFloat));
 
273
        sq_createslot(v,-3);
 
274
        sq_pop(v,1);
 
275
}
 
276
 
 
277
static SQInteger default_delegate_len(HSQUIRRELVM v)
 
278
{
 
279
        v->Push(SQInteger(sq_getsize(v,1)));
 
280
        return 1;
 
281
}
 
282
 
 
283
static SQInteger default_delegate_tofloat(HSQUIRRELVM v)
 
284
{
 
285
        SQObjectPtr &o=stack_get(v,1);
 
286
        switch(type(o)){
 
287
        case OT_STRING:{
 
288
                SQObjectPtr res;
 
289
                if(str2num(_stringval(o),res)){
 
290
                        v->Push(SQObjectPtr(tofloat(res)));
 
291
                        break;
 
292
                }}
 
293
                return sq_throwerror(v, _SC("cannot convert the string"));
 
294
                break;
 
295
        case OT_INTEGER:case OT_FLOAT:
 
296
                v->Push(SQObjectPtr(tofloat(o)));
 
297
                break;
 
298
        case OT_BOOL:
 
299
                v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
 
300
                break;
 
301
        default:
 
302
                v->Push(_null_);
 
303
                break;
 
304
        }
 
305
        return 1;
 
306
}
 
307
 
 
308
static SQInteger default_delegate_tointeger(HSQUIRRELVM v)
 
309
{
 
310
        SQObjectPtr &o=stack_get(v,1);
 
311
        switch(type(o)){
 
312
        case OT_STRING:{
 
313
                SQObjectPtr res;
 
314
                if(str2num(_stringval(o),res)){
 
315
                        v->Push(SQObjectPtr(tointeger(res)));
 
316
                        break;
 
317
                }}
 
318
                return sq_throwerror(v, _SC("cannot convert the string"));
 
319
                break;
 
320
        case OT_INTEGER:case OT_FLOAT:
 
321
                v->Push(SQObjectPtr(tointeger(o)));
 
322
                break;
 
323
        case OT_BOOL:
 
324
                v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));
 
325
                break;
 
326
        default:
 
327
                v->Push(_null_);
 
328
                break;
 
329
        }
 
330
        return 1;
 
331
}
 
332
 
 
333
static SQInteger default_delegate_tostring(HSQUIRRELVM v)
 
334
{
 
335
        sq_tostring(v,1);
 
336
        return 1;
 
337
}
 
338
 
 
339
static SQInteger obj_delegate_weakref(HSQUIRRELVM v)
 
340
{
 
341
        sq_weakref(v,1);
 
342
        return 1;
 
343
}
 
344
 
 
345
static SQInteger obj_clear(HSQUIRRELVM v)
 
346
{
 
347
        return sq_clear(v,-1);
 
348
}
 
349
 
 
350
 
 
351
static SQInteger number_delegate_tochar(HSQUIRRELVM v)
 
352
{
 
353
        SQObject &o=stack_get(v,1);
 
354
        SQChar c = (SQChar)tointeger(o);
 
355
        v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
 
356
        return 1;
 
357
}
 
358
 
 
359
 
 
360
/////////////////////////////////////////////////////////////////
 
361
//TABLE DEFAULT DELEGATE
 
362
 
 
363
static SQInteger table_rawdelete(HSQUIRRELVM v)
 
364
{
 
365
        if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
 
366
                return SQ_ERROR;
 
367
        return 1;
 
368
}
 
369
 
 
370
 
 
371
static SQInteger container_rawexists(HSQUIRRELVM v)
 
372
{
 
373
        if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
 
374
                sq_pushbool(v,SQTrue);
 
375
                return 1;
 
376
        }
 
377
        sq_pushbool(v,SQFalse);
 
378
        return 1;
 
379
}
 
380
 
 
381
static SQInteger table_rawset(HSQUIRRELVM v)
 
382
{
 
383
        return sq_rawset(v,-3);
 
384
}
 
385
 
 
386
 
 
387
static SQInteger table_rawget(HSQUIRRELVM v)
 
388
{
 
389
        return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
 
390
}
 
391
 
 
392
 
 
393
SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
 
394
        {_SC("len"),default_delegate_len,1, _SC("t")},
 
395
        {_SC("rawget"),table_rawget,2, _SC("t")},
 
396
        {_SC("rawset"),table_rawset,3, _SC("t")},
 
397
        {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
 
398
        {_SC("rawin"),container_rawexists,2, _SC("t")},
 
399
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
400
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
401
        {_SC("clear"),obj_clear,1, _SC(".")},
 
402
        {0,0}
 
403
};
 
404
 
 
405
//ARRAY DEFAULT DELEGATE///////////////////////////////////////
 
406
 
 
407
static SQInteger array_append(HSQUIRRELVM v)
 
408
{
 
409
        return sq_arrayappend(v,-2);
 
410
}
 
411
 
 
412
static SQInteger array_extend(HSQUIRRELVM v)
 
413
{
 
414
        _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
 
415
        return 0;
 
416
}
 
417
 
 
418
static SQInteger array_reverse(HSQUIRRELVM v)
 
419
{
 
420
        return sq_arrayreverse(v,-1);
 
421
}
 
422
 
 
423
static SQInteger array_pop(HSQUIRRELVM v)
 
424
{
 
425
        return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
 
426
}
 
427
 
 
428
static SQInteger array_top(HSQUIRRELVM v)
 
429
{
 
430
        SQObject &o=stack_get(v,1);
 
431
        if(_array(o)->Size()>0){
 
432
                v->Push(_array(o)->Top());
 
433
                return 1;
 
434
        }
 
435
        else return sq_throwerror(v,_SC("top() on a empty array"));
 
436
}
 
437
 
 
438
static SQInteger array_insert(HSQUIRRELVM v)
 
439
{
 
440
        SQObject &o=stack_get(v,1);
 
441
        SQObject &idx=stack_get(v,2);
 
442
        SQObject &val=stack_get(v,3);
 
443
        if(!_array(o)->Insert(tointeger(idx),val))
 
444
                return sq_throwerror(v,_SC("index out of range"));
 
445
        return 0;
 
446
}
 
447
 
 
448
static SQInteger array_remove(HSQUIRRELVM v)
 
449
{
 
450
        SQObject &o = stack_get(v, 1);
 
451
        SQObject &idx = stack_get(v, 2);
 
452
        if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
 
453
        SQObjectPtr val;
 
454
        if(_array(o)->Get(tointeger(idx), val)) {
 
455
                _array(o)->Remove(tointeger(idx));
 
456
                v->Push(val);
 
457
                return 1;
 
458
        }
 
459
        return sq_throwerror(v, _SC("idx out of range"));
 
460
}
 
461
 
 
462
static SQInteger array_resize(HSQUIRRELVM v)
 
463
{
 
464
        SQObject &o = stack_get(v, 1);
 
465
        SQObject &nsize = stack_get(v, 2);
 
466
        SQObjectPtr fill;
 
467
        if(sq_isnumeric(nsize)) {
 
468
                if(sq_gettop(v) > 2)
 
469
                        fill = stack_get(v, 3);
 
470
                _array(o)->Resize(tointeger(nsize),fill);
 
471
                return 0;
 
472
        }
 
473
        return sq_throwerror(v, _SC("size must be a number"));
 
474
}
 
475
 
 
476
 
 
477
bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
 
478
{
 
479
        if(func < 0) {
 
480
                if(!v->ObjCmp(a,b,ret)) return false;
 
481
        }
 
482
        else {
 
483
                SQInteger top = sq_gettop(v);
 
484
                sq_push(v, func);
 
485
                sq_pushroottable(v);
 
486
                v->Push(a);
 
487
                v->Push(b);
 
488
                if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
 
489
                        if(!sq_isstring( v->_lasterror))
 
490
                                v->Raise_Error(_SC("compare func failed"));
 
491
                        return false;
 
492
                }
 
493
                if(SQ_FAILED(sq_getinteger(v, -1, &ret))) {
 
494
                        v->Raise_Error(_SC("numeric value expected as return value of the compare function"));
 
495
                        return false;
 
496
                }
 
497
                sq_settop(v, top);
 
498
                return true;
 
499
        }
 
500
        return true;
 
501
}
 
502
 
 
503
bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, int root, int bottom, SQInteger func)
 
504
{
 
505
        SQInteger maxChild;
 
506
        SQInteger done = 0;
 
507
        SQInteger ret;
 
508
        SQInteger root2;
 
509
        while (((root2 = root * 2) <= bottom) && (!done))
 
510
        {
 
511
                if (root2 == bottom) {
 
512
                        maxChild = root2;
 
513
                }
 
514
                else {
 
515
                        if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret))
 
516
                                return false;
 
517
                        if (ret > 0) {
 
518
                                maxChild = root2;
 
519
                        }
 
520
                        else {
 
521
                                maxChild = root2 + 1;
 
522
                        }
 
523
                }
 
524
 
 
525
                if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret))
 
526
                        return false;
 
527
                if (ret < 0) {
 
528
                        _Swap(arr->_values[root],arr->_values[maxChild]);
 
529
                        root = maxChild;
 
530
                }
 
531
                else {
 
532
                        done = 1;
 
533
                }
 
534
        }
 
535
        return true;
 
536
}
 
537
 
 
538
bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
 
539
{
 
540
        SQArray *a = _array(arr);
 
541
        SQInteger i;
 
542
        SQInteger array_size = a->Size();
 
543
        for (i = (array_size / 2); i >= 0; i--) {
 
544
                if(!_hsort_sift_down(v,a, i, array_size - 1,func)) return false;
 
545
        }
 
546
 
 
547
        for (i = array_size-1; i >= 1; i--)
 
548
        {
 
549
                _Swap(a->_values[0],a->_values[i]);
 
550
                if(!_hsort_sift_down(v,a, 0, i-1,func)) return false;
 
551
        }
 
552
        return true;
 
553
}
 
554
 
 
555
static SQInteger array_sort(HSQUIRRELVM v)
 
556
{
 
557
        SQInteger func = -1;
 
558
        SQObjectPtr &o = stack_get(v,1);
 
559
        if(_array(o)->Size() > 1) {
 
560
                if(sq_gettop(v) == 2) func = 2;
 
561
                if(!_hsort(v, o, 0, _array(o)->Size()-1, func))
 
562
                        return SQ_ERROR;
 
563
 
 
564
        }
 
565
        return 0;
 
566
}
 
567
 
 
568
static SQInteger array_slice(HSQUIRRELVM v)
 
569
{
 
570
        SQInteger sidx,eidx;
 
571
        SQObjectPtr o;
 
572
        if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
 
573
        SQInteger alen = _array(o)->Size();
 
574
        if(sidx < 0)sidx = alen + sidx;
 
575
        if(eidx < 0)eidx = alen + eidx;
 
576
        if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
 
577
        if(eidx > alen)return sq_throwerror(v,_SC("slice out of range"));
 
578
        SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
 
579
        SQObjectPtr t;
 
580
        SQInteger count=0;
 
581
        for(SQInteger i=sidx;i<eidx;i++){
 
582
                _array(o)->Get(i,t);
 
583
                arr->Set(count++,t);
 
584
        }
 
585
        v->Push(arr);
 
586
        return 1;
 
587
 
 
588
}
 
589
 
 
590
SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
 
591
        {_SC("len"),default_delegate_len,1, _SC("a")},
 
592
        {_SC("append"),array_append,2, _SC("a")},
 
593
        {_SC("extend"),array_extend,2, _SC("aa")},
 
594
        {_SC("push"),array_append,2, _SC("a")},
 
595
        {_SC("pop"),array_pop,1, _SC("a")},
 
596
        {_SC("top"),array_top,1, _SC("a")},
 
597
        {_SC("insert"),array_insert,3, _SC("an")},
 
598
        {_SC("remove"),array_remove,2, _SC("an")},
 
599
        {_SC("resize"),array_resize,-2, _SC("an")},
 
600
        {_SC("reverse"),array_reverse,1, _SC("a")},
 
601
        {_SC("sort"),array_sort,-1, _SC("ac")},
 
602
        {_SC("slice"),array_slice,-1, _SC("ann")},
 
603
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
604
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
605
        {_SC("clear"),obj_clear,1, _SC(".")},
 
606
        {0,0}
 
607
};
 
608
 
 
609
//STRING DEFAULT DELEGATE//////////////////////////
 
610
static SQInteger string_slice(HSQUIRRELVM v)
 
611
{
 
612
        SQInteger sidx,eidx;
 
613
        SQObjectPtr o;
 
614
        if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
 
615
        SQInteger slen = _string(o)->_len;
 
616
        if(sidx < 0)sidx = slen + sidx;
 
617
        if(eidx < 0)eidx = slen + eidx;
 
618
        if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
 
619
        if(eidx > slen) return sq_throwerror(v,_SC("slice out of range"));
 
620
        v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
 
621
        return 1;
 
622
}
 
623
 
 
624
static SQInteger string_find(HSQUIRRELVM v)
 
625
{
 
626
        SQInteger top,start_idx=0;
 
627
        const SQChar *str,*substr,*ret;
 
628
        if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
 
629
                if(top>2)sq_getinteger(v,3,&start_idx);
 
630
                if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
 
631
                        ret=scstrstr(&str[start_idx],substr);
 
632
                        if(ret){
 
633
                                sq_pushinteger(v,(SQInteger)(ret-str));
 
634
                                return 1;
 
635
                        }
 
636
                }
 
637
                return 0;
 
638
        }
 
639
        return sq_throwerror(v,_SC("invalid param"));
 
640
}
 
641
 
 
642
#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
 
643
{ \
 
644
        SQObject str=stack_get(v,1); \
 
645
        SQInteger len=_string(str)->_len; \
 
646
        const SQChar *sThis=_stringval(str); \
 
647
        SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
 
648
        for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
 
649
        v->Push(SQString::Create(_ss(v),sNew,len)); \
 
650
        return 1; \
 
651
}
 
652
 
 
653
 
 
654
STRING_TOFUNCZ(tolower)
 
655
STRING_TOFUNCZ(toupper)
 
656
 
 
657
SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
 
658
        {_SC("len"),default_delegate_len,1, _SC("s")},
 
659
        {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
 
660
        {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
 
661
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
662
        {_SC("slice"),string_slice,-1, _SC(" s n  n")},
 
663
        {_SC("find"),string_find,-2, _SC("s s n ")},
 
664
        {_SC("tolower"),string_tolower,1, _SC("s")},
 
665
        {_SC("toupper"),string_toupper,1, _SC("s")},
 
666
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
667
        {0,0}
 
668
};
 
669
 
 
670
//INTEGER DEFAULT DELEGATE//////////////////////////
 
671
SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
 
672
        {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
 
673
        {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
 
674
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
675
        {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
 
676
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
677
        {0,0}
 
678
};
 
679
 
 
680
//CLOSURE DEFAULT DELEGATE//////////////////////////
 
681
static SQInteger closure_pcall(HSQUIRRELVM v)
 
682
{
 
683
        return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
 
684
}
 
685
 
 
686
static SQInteger closure_call(HSQUIRRELVM v)
 
687
{
 
688
        return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
 
689
}
 
690
 
 
691
static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
 
692
{
 
693
        SQArray *aparams=_array(stack_get(v,2));
 
694
        SQInteger nparams=aparams->Size();
 
695
        v->Push(stack_get(v,1));
 
696
        for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
 
697
        return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
 
698
}
 
699
 
 
700
static SQInteger closure_acall(HSQUIRRELVM v)
 
701
{
 
702
        return _closure_acall(v,SQTrue);
 
703
}
 
704
 
 
705
static SQInteger closure_pacall(HSQUIRRELVM v)
 
706
{
 
707
        return _closure_acall(v,SQFalse);
 
708
}
 
709
 
 
710
static SQInteger closure_bindenv(HSQUIRRELVM v)
 
711
{
 
712
        if(SQ_FAILED(sq_bindenv(v,1)))
 
713
                return SQ_ERROR;
 
714
        return 1;
 
715
}
 
716
 
 
717
static SQInteger closure_getinfos(HSQUIRRELVM v) {
 
718
        SQObject o = stack_get(v,1);
 
719
        SQTable *res = SQTable::Create(_ss(v),4);
 
720
        if(type(o) == OT_CLOSURE) {
 
721
                SQFunctionProto *f = _funcproto(_closure(o)->_function);
 
722
                SQInteger nparams = f->_nparameters + (f->_varparams?1:0);
 
723
                SQObjectPtr params = SQArray::Create(_ss(v),nparams);
 
724
                for(SQInteger n = 0; n<f->_nparameters; n++) {
 
725
                        _array(params)->Set((SQInteger)n,f->_parameters[n]);
 
726
                }
 
727
                if(f->_varparams) {
 
728
                        _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
 
729
                }
 
730
                res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
 
731
                res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
 
732
                res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
 
733
                res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
 
734
                res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
 
735
        }
 
736
        else { //OT_NATIVECLOSURE
 
737
                SQNativeClosure *nc = _nativeclosure(o);
 
738
                res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
 
739
                res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
 
740
                res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
 
741
                SQObjectPtr typecheck;
 
742
                if(nc->_typecheck.size() > 0) {
 
743
                        typecheck =
 
744
                                SQArray::Create(_ss(v), nc->_typecheck.size());
 
745
                        for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
 
746
                                        _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
 
747
                        }
 
748
                }
 
749
                res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
 
750
        }
 
751
        v->Push(res);
 
752
        return 1;
 
753
}
 
754
 
 
755
 
 
756
SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
 
757
        {_SC("call"),closure_call,-1, _SC("c")},
 
758
        {_SC("pcall"),closure_pcall,-1, _SC("c")},
 
759
        {_SC("acall"),closure_acall,2, _SC("ca")},
 
760
        {_SC("pacall"),closure_pacall,2, _SC("ca")},
 
761
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
762
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
763
        {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
 
764
        {_SC("getinfos"),closure_getinfos,1, _SC("c")},
 
765
        {0,0}
 
766
};
 
767
 
 
768
//GENERATOR DEFAULT DELEGATE
 
769
static SQInteger generator_getstatus(HSQUIRRELVM v)
 
770
{
 
771
        SQObject &o=stack_get(v,1);
 
772
        switch(_generator(o)->_state){
 
773
                case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
 
774
                case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
 
775
                case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
 
776
        }
 
777
        return 1;
 
778
}
 
779
 
 
780
SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
 
781
        {_SC("getstatus"),generator_getstatus,1, _SC("g")},
 
782
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
783
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
784
        {0,0}
 
785
};
 
786
 
 
787
//THREAD DEFAULT DELEGATE
 
788
 
 
789
static SQInteger thread_call(HSQUIRRELVM v)
 
790
{
 
791
 
 
792
        SQObjectPtr o = stack_get(v,1);
 
793
        if(type(o) == OT_THREAD) {
 
794
                SQInteger nparams = sq_gettop(v);
 
795
                _thread(o)->Push(_thread(o)->_roottable);
 
796
                for(SQInteger i = 2; i<(nparams+1); i++)
 
797
                        sq_move(_thread(o),v,i);
 
798
                if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
 
799
                        sq_move(v,_thread(o),-1);
 
800
                        sq_pop(_thread(o),1);
 
801
                        return 1;
 
802
                }
 
803
                v->_lasterror = _thread(o)->_lasterror;
 
804
                return SQ_ERROR;
 
805
        }
 
806
        return sq_throwerror(v,_SC("wrong parameter"));
 
807
}
 
808
 
 
809
static SQInteger thread_wakeup(HSQUIRRELVM v)
 
810
{
 
811
        SQObjectPtr o = stack_get(v,1);
 
812
        if(type(o) == OT_THREAD) {
 
813
                SQVM *thread = _thread(o);
 
814
                SQInteger state = sq_getvmstate(thread);
 
815
                if(state != SQ_VMSTATE_SUSPENDED) {
 
816
                        switch(state) {
 
817
                                case SQ_VMSTATE_IDLE:
 
818
                                        return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
 
819
                                break;
 
820
                                case SQ_VMSTATE_RUNNING:
 
821
                                        return sq_throwerror(v,_SC("cannot wakeup a running thread"));
 
822
                                break;
 
823
                        }
 
824
                }
 
825
 
 
826
                SQInteger wakeupret = sq_gettop(v)>1?1:0;
 
827
                if(wakeupret) {
 
828
                        sq_move(thread,v,2);
 
829
                }
 
830
                if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) {
 
831
                        sq_move(v,thread,-1);
 
832
                        sq_pop(thread,1); //pop retval
 
833
                        if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
 
834
                                sq_settop(thread,1); //pop roottable
 
835
                        }
 
836
                        return 1;
 
837
                }
 
838
                sq_settop(thread,1);
 
839
                v->_lasterror = thread->_lasterror;
 
840
                return SQ_ERROR;
 
841
        }
 
842
        return sq_throwerror(v,_SC("wrong parameter"));
 
843
}
 
844
 
 
845
static SQInteger thread_getstatus(HSQUIRRELVM v)
 
846
{
 
847
        SQObjectPtr &o = stack_get(v,1);
 
848
        switch(sq_getvmstate(_thread(o))) {
 
849
                case SQ_VMSTATE_IDLE:
 
850
                        sq_pushstring(v,_SC("idle"),-1);
 
851
                break;
 
852
                case SQ_VMSTATE_RUNNING:
 
853
                        sq_pushstring(v,_SC("running"),-1);
 
854
                break;
 
855
                case SQ_VMSTATE_SUSPENDED:
 
856
                        sq_pushstring(v,_SC("suspended"),-1);
 
857
                break;
 
858
                default:
 
859
                        return sq_throwerror(v,_SC("internal VM error"));
 
860
        }
 
861
        return 1;
 
862
}
 
863
 
 
864
SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
 
865
        {_SC("call"), thread_call, -1, _SC("v")},
 
866
        {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
 
867
        {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
 
868
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
869
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
870
        {0,0},
 
871
};
 
872
 
 
873
static SQInteger class_getattributes(HSQUIRRELVM v)
 
874
{
 
875
        if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
 
876
                return 1;
 
877
        return SQ_ERROR;
 
878
}
 
879
 
 
880
static SQInteger class_setattributes(HSQUIRRELVM v)
 
881
{
 
882
        if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
 
883
                return 1;
 
884
        return SQ_ERROR;
 
885
}
 
886
 
 
887
static SQInteger class_instance(HSQUIRRELVM v)
 
888
{
 
889
        if(SQ_SUCCEEDED(sq_createinstance(v,-1)))
 
890
                return 1;
 
891
        return SQ_ERROR;
 
892
}
 
893
 
 
894
SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
 
895
        {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
 
896
        {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
 
897
        {_SC("rawin"),container_rawexists,2, _SC("y")},
 
898
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
899
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
900
        {_SC("instance"),class_instance,1, _SC("y")},
 
901
        {0,0}
 
902
};
 
903
 
 
904
static SQInteger instance_getclass(HSQUIRRELVM v)
 
905
{
 
906
        if(SQ_SUCCEEDED(sq_getclass(v,1)))
 
907
                return 1;
 
908
        return SQ_ERROR;
 
909
}
 
910
 
 
911
SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
 
912
        {_SC("getclass"), instance_getclass, 1, _SC("x")},
 
913
        {_SC("rawin"),container_rawexists,2, _SC("x")},
 
914
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
915
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
916
        {0,0}
 
917
};
 
918
 
 
919
static SQInteger weakref_ref(HSQUIRRELVM v)
 
920
{
 
921
        if(SQ_FAILED(sq_getweakrefval(v,1)))
 
922
                return SQ_ERROR;
 
923
        return 1;
 
924
}
 
925
 
 
926
SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
 
927
        {_SC("ref"),weakref_ref,1, _SC("r")},
 
928
        {_SC("weakref"),obj_delegate_weakref,1, NULL },
 
929
        {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 
930
        {0,0}
 
931
};
 
932
 
 
933