moved back to old acc
[vox.git] / src / core / baselib_array.cpp
bloba2f89f437e0b593d972299a161b8a64ece94b755
2 #include <sstream>
3 #include "baselib.hpp"
5 //ARRAY DEFAULT DELEGATE///////////////////////////////////////
7 VXInteger array_append(VXState* v)
9 VXObject arr = v->StackGet(1);
10 arr.Array()->Append(v->StackGet(2));
11 return VX_OK;
14 VXInteger array_extend(VXState* v)
16 VXArrayObj* self = v->StackGet(1).Array();
17 self->Extend(v->StackGet(2).Array());
18 v->Push(self);
19 return 1;
22 VXInteger array_reverse(VXState* v)
24 VXInteger i;
25 VXInteger n;
26 VXInteger size;
27 VXArrayObj* arr = v->StackGet(1).Array();
28 VXArrayObj* narr = arr->Clone();
29 if(arr->Size() > 0)
31 VXObject t;
32 size = arr->Size();
33 n = (size >> 1);
34 size -= 1;
35 for(i=0; i < n; i++)
37 t = arr->_values[i];
38 narr->_values[i] = arr->_values[size-i];
39 narr->_values[size-i] = t;
42 v->Push(narr);
43 return 1;
46 VXInteger array_pop(VXState* v)
48 VXArrayObj* arr = v->StackGet(1).Array();
49 if(arr->Size() > 0)
51 v->Push(arr->Top());
52 arr->Pop();
53 return 1;
55 return v->ThrowError("pop() on an empty array");
58 VXInteger array_top(VXState* v)
60 VXArrayObj* arr = v->StackGet(1).Array();
61 if(arr->Size() > 0)
63 v->Push(arr->Top());
64 return 1;
66 return v->ThrowError("top() on a empty array");
69 VXInteger array_insert(VXState* v)
71 VXArrayObj* arr = v->StackGet(1).Array();
72 VXObject& idx = v->StackGet(2);
73 VXObject& val = v->StackGet(3);
74 if(!arr->Insert(idx.Integer(), val))
76 return v->ThrowError("insert() failed: index out of range");
78 return 0;
81 VXInteger array_remove(VXState* v)
83 VXObject val;
84 VXObject& o = v->StackGet(1);
85 VXObject& idx = v->StackGet(2);
86 if(!idx.IsNumeric())
88 return v->ThrowError("wrong type");
90 if(o.Array()->Get(idx.Integer(), val))
92 o.Array()->Remove(idx.Integer());
93 v->Push(val);
94 return 1;
96 return v->ThrowError("index out of range");
99 VXInteger array_resize(VXState* v)
101 VXObject &o = v->StackGet(1);
102 VXObject &nsize = v->StackGet(2);
103 VXObject fill;
104 if(nsize.IsNumeric())
106 if(v->GetTop() > 2)
108 fill = v->StackGet(3);
110 o.Array()->Resize(nsize.Integer(), fill);
111 return 0;
113 return v->ThrowError("size must be a number");
116 VXInteger __map_array(VXState* v, VXArrayObj *dest,VXArrayObj *src)
118 VXInteger n;
119 VXInteger size;
120 VXObject temp;
121 size = src->Size();
122 for(n=0; n<size; n++)
124 src->Get(n,temp);
125 v->Push(src);
126 v->Push(temp);
127 if(VX_FAILED(v->StackCall(2, true, false)))
129 return VX_ERROR;
131 dest->Set(n, v->GetUp(-1));
132 v->Pop();
134 return 0;
138 VXInteger array_map(VXState* v)
140 VXObject& o = v->StackGet(1);
141 VXInteger size = o.Array()->Size();
142 VXObject ret = v->NewArray(size);
143 if(VX_FAILED(__map_array(v, ret.Array(), o.Array())))
144 return VX_ERROR;
145 v->Push(ret);
146 return 1;
150 VXInteger array_apply(VXState* v)
152 VXObject& o = v->StackGet(1);
153 if(VX_FAILED(__map_array(v, o.Array(), o.Array())))
155 return VX_ERROR;
157 return 0;
160 VXInteger array_reduce(VXState* v)
162 VXObject& o = stack_get(v,1);
163 VXArrayObj *a = o.Array();
164 VXInteger size = a->Size();
165 if(size == 0)
167 return 0;
169 VXObject res;
170 a->Get(0,res);
171 if(size > 1)
173 VXObject other;
174 for(VXInteger n = 1; n < size; n++)
176 a->Get(n,other);
177 v->Push(o);
178 v->Push(res);
179 v->Push(other);
180 if(VX_FAILED(v->StackCall(3,true,false)))
182 return VX_ERROR;
184 res = v->GetUp(-1);
185 v->Pop();
188 v->Push(res);
189 return 1;
192 VXInteger array_filter(VXState* v)
194 VXObject& o = v->StackGet(1);
195 VXArrayObj* a = o.Array();
196 VXObject ret = v->NewArray();
197 VXInteger size = a->Size();
198 VXObject val;
199 for(VXInteger n = 0; n < size; n++)
201 a->Get(n,val);
202 v->Push(o);
203 v->Push(n);
204 v->Push(val);
205 if(VX_FAILED(v->StackCall(3, true, false)))
207 return VX_ERROR;
209 if(!VXState::IsFalse(v->GetUp(-1)))
211 ret.Array()->Append(val);
213 v->Pop();
215 v->Push(ret);
216 return 1;
219 VXInteger array_find(VXState* v)
221 bool res;
222 VXObject temp;
223 VXInteger found_elements;
224 VXInteger n;
225 VXObject& o = v->StackGet(1);
226 VXObject& val = v->StackGet(2);
227 VXArrayObj* a = o.Array();
228 VXInteger size = a->Size();
229 found_elements = 0;
230 res = false;
231 for(n=0; n<size; n++)
233 a->Get(n, temp);
234 if(VXState::IsEqual(temp, val, res) && res)
236 found_elements++;
239 v->Push(found_elements);
240 return 1;
243 //QSORT ala Sedgewick
244 bool _qsort_compare(VXState* v,VXObject &arr,VXObject &a,VXObject &b,VXInteger func,VXInteger &ret)
246 (void)arr;
247 if(func < 0)
249 if(!v->ObjCmp(a,b,ret))
251 return false;
254 else
256 VXInteger top = v->GetTop();
257 v->Repush(func);
258 v->Push(v->GetRootTable());
259 v->Push(a);
260 v->Push(b);
261 if(VX_FAILED(v->CallStack(3, true, false)))
263 if(!v->_lasterror.IsString())
265 v->ThrowError("compare func failed");
267 return false;
269 v->GetInteger(-1, &ret);
270 v->SetTop(top);
271 return true;
273 return true;
276 //QSORT ala Sedgewick
277 bool _qsort(VXState* v,VXObject &arr, VXInteger l, VXInteger r,VXInteger func)
279 VXInteger i;
280 VXInteger j;
281 VXArrayObj *a= arr.Array();
282 VXObject pivot,t;
283 if( l < r )
285 pivot = a->_values[l];
286 i = l;
287 j = r + 1;
288 while(1)
290 VXInteger ret;
293 ++i;
294 if(i > r)
296 break;
298 if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
300 return false;
302 } while( ret <= 0);
305 --j;
306 if (j < 0)
308 v->ThrowError("Invalid qsort, probably compare function defect");
309 return false;
311 if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
313 return false;
316 while(ret > 0);
317 if(i >= j)
319 break;
321 t = a->_values[i];
322 a->_values[i] = a->_values[j];
323 a->_values[j] = t;
325 t = a->_values[l];
326 a->_values[l] = a->_values[j];
327 a->_values[j] = t;
328 if(!_qsort( v, arr, l, j-1,func))
330 return false;
332 if(!_qsort( v, arr, j+1, r,func))
334 return false;
337 v->Push(arr);
338 return true;
341 VXInteger array_sort(VXState* v)
343 VXInteger func = -1;
344 VXObject &o = v->StackGet(1);
345 if(_array(o)->Size() > 1)
347 VXObject clone = o.Array()->Clone();
348 if(v->GetTop() == 2)
350 func = 2;
352 if(!_qsort(v, clone, 0, clone.Array()->Size()-1, func))
354 return VX_ERROR;
357 return 1;
360 VXInteger array_slice(VXState* v)
362 VXInteger sidx;
363 VXInteger eidx;
364 VXObject o;
365 if(get_slice_params(v, sidx, eidx, o) == -1)
367 return -1;
369 VXInteger alen = o.Array()->Size();
370 if(sidx < 0)
372 sidx = alen + sidx;
374 if(eidx < 0)
376 eidx = alen + eidx;
378 if(eidx < sidx)
380 return v->ThrowError("wrong indexes");
382 if(eidx > alen)
384 return v->ThrowError("slice out of range");
386 VXArrayObj* arr = v->NewArray(eidx - sidx);
387 VXObject t;
388 VXInteger count=0;
389 for(VXInteger i=sidx;i<eidx;i++)
391 _array(o)->Get(i,t);
392 arr->Set(count++,t);
394 v->Push(arr);
395 return 1;
399 VXInteger array_join(VXState* v)
401 std::string delim;
402 std::stringstream strm;
403 VXObject& o = v->StackGet(1);
404 VXArrayObj *a = o.Array();
405 VXInteger size = a->Size();
406 VXInteger n;
407 VXObject temp;
408 v->GetString(2, &delim);
409 for(n=0; n<size; n++)
411 const char* stringval;
412 VXInteger stringlen;
413 if(a->Get(n, temp))
415 VXObject res;
416 if(v->ToString(temp, res))
418 res.String()->Get(&stringval, &stringlen);
420 else
422 goto cannot_convert;
424 strm.write(stringval, stringlen);
425 if((n+1) < size)
427 strm << delim;
431 v->Push(v->NewString(strm.str().c_str(), strm.str().length()));
432 return 1;
434 cannot_convert:
435 return v->ThrowError("join(): cannot convert element to string");
438 VXInteger array_isset(VXState* v)
440 bool status;
441 VXInteger index;
442 VXObject val;
443 VXObject& o = v->StackGet(1);
444 VXArrayObj *a = o.Array();
445 v->GetInteger(2, &index);
446 if(a->Get(index, val))
448 status = true;
450 else
452 status = false;
454 v->Push(status);
455 return 1;
458 VXInteger array_first(VXState* v)
460 VXObject val;
461 VXObject& o = v->StackGet(1);
462 VXArrayObj* a = o.Array();
463 a->Get(0, val);
464 v->Push(val);
465 return 1;
468 VXInteger array_last(VXState* v)
470 VXObject val;
471 VXObject& o = v->StackGet(1);
472 VXArrayObj* a = o.Array();
473 a->Get(a->Size()-1, val);
474 v->Push(val);
475 return 1;
478 VXRegFunction VXSharedState::_array_default_delegate_funcz[]=
480 {"weakref", obj_delegate_weakref, 1, NULL},
481 {"tostring", default_delegate_tostring, -1, ".b"},
482 {"len", default_delegate_len, 1, "a"},
483 {"clear", obj_clear, 1, "."},
484 {"first", array_first, 1, "a"},
485 {"last", array_last, 1, "a"},
486 {"append", array_append, 2, "a"},
487 {"push", array_append, 2, "a"},
488 {"extend", array_extend, 2, "aa"},
489 {"pop", array_pop, 1, "a"},
490 {"top", array_top, 1, "a"},
491 {"insert", array_insert, 3, "an"},
492 {"remove", array_remove, 2, "an"},
493 {"resize", array_resize, -2, "an"},
494 {"reverse", array_reverse, 1, "a"},
495 {"sort", array_sort, -1, "ac"},
496 {"slice", array_slice, -1, "ann"},
497 {"map", array_map, 2, "ac"},
498 {"apply", array_apply, 2, "ac"},
499 {"reduce", array_reduce, 2, "ac"},
500 {"filter", array_filter, 2, "ac"},
501 {"find", array_find, 2, "a."},
502 {"join", array_join, 2, "as"},
503 {"isset", array_isset, 2, "an"},
504 {"repr", default_delegate_repr, 1, "."},
505 {0, 0, 0, 0}