2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 Primitives for Arrays.
27 #include "PyrKernel.h"
28 #include "PyrPrimitive.h"
29 #include "SC_InlineBinaryOp.h"
30 #include "SC_Constants.h"
33 int basicSize(VMGlobals
*g
, int numArgsPushed
);
34 int basicMaxSize(VMGlobals
*g
, int numArgsPushed
);
36 int basicSwap(struct VMGlobals
*g
, int numArgsPushed
);
37 int basicAt(VMGlobals
*g
, int numArgsPushed
);
38 int basicRemoveAt(VMGlobals
*g
, int numArgsPushed
);
39 int basicClipAt(VMGlobals
*g
, int numArgsPushed
);
40 int basicWrapAt(VMGlobals
*g
, int numArgsPushed
);
41 int basicFoldAt(VMGlobals
*g
, int numArgsPushed
);
42 int basicPut(VMGlobals
*g
, int numArgsPushed
);
43 int basicClipPut(VMGlobals
*g
, int numArgsPushed
);
44 int basicWrapPut(VMGlobals
*g
, int numArgsPushed
);
45 int basicFoldPut(VMGlobals
*g
, int numArgsPushed
);
47 int prArrayAdd(VMGlobals
*g
, int numArgsPushed
);
48 int prArrayFill(VMGlobals
*g
, int numArgsPushed
);
49 int prArrayPop(VMGlobals
*g
, int numArgsPushed
);
50 int prArrayGrow(VMGlobals
*g
, int numArgsPushed
);
51 int prArrayCat(VMGlobals
*g
, int numArgsPushed
);
53 int prArrayReverse(VMGlobals
*g
, int numArgsPushed
);
54 int prArrayScramble(VMGlobals
*g
, int numArgsPushed
);
55 int prArrayRotate(VMGlobals
*g
, int numArgsPushed
);
56 int prArrayStutter(VMGlobals
*g
, int numArgsPushed
);
57 int prArrayMirror(VMGlobals
*g
, int numArgsPushed
);
58 int prArrayMirror1(VMGlobals
*g
, int numArgsPushed
);
59 int prArrayMirror2(VMGlobals
*g
, int numArgsPushed
);
60 int prArrayExtendWrap(VMGlobals
*g
, int numArgsPushed
);
61 int prArrayExtendFold(VMGlobals
*g
, int numArgsPushed
);
62 int prArrayPermute(VMGlobals
*g
, int numArgsPushed
);
63 int prArrayPyramid(VMGlobals
*g
, int numArgsPushed
);
64 int prArraySlide(VMGlobals
*g
, int numArgsPushed
);
65 int prArrayLace(VMGlobals
*g
, int numArgsPushed
);
66 int prArrayContainsSeqColl(VMGlobals
*g
, int numArgsPushed
);
67 int prArrayWIndex(VMGlobals
*g
, int numArgsPushed
);
68 int prArrayNormalizeSum(VMGlobals
*g
, int numArgsPushed
);
69 int prArrayIndexOfGreaterThan(VMGlobals
*g
, int numArgsPushed
);
72 int basicSize(struct VMGlobals
*g
, int numArgsPushed
)
82 obj
= slotRawObject(a
);
87 int basicMaxSize(struct VMGlobals
*g
, int numArgsPushed
)
98 obj
= slotRawObject(a
);
99 maxsize
= MAXINDEXSIZE(obj
);
104 int basicSwap(struct VMGlobals
*g
, int numArgsPushed
)
106 PyrSlot
*a
, *b
, *c
, tempi
, tempj
;
114 if (NotObj(a
)) return errWrongType
;
115 if (NotInt(b
)) return errIndexNotAnInteger
;
116 if (NotInt(c
)) return errIndexNotAnInteger
;
117 obj
= slotRawObject(a
);
118 if (obj
->obj_flags
& obj_immutable
) return errImmutableObject
;
119 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
120 return errNotAnIndexableObject
;
123 if (i
< 0 || i
>= obj
->size
) return errIndexOutOfRange
;
124 if (j
< 0 || j
>= obj
->size
) return errIndexOutOfRange
;
125 getIndexedSlot(obj
, &tempi
, i
);
126 getIndexedSlot(obj
, &tempj
, j
);
127 putIndexedSlot(g
, obj
, &tempi
, j
);
128 putIndexedSlot(g
, obj
, &tempj
, i
);
129 // in case it is partial scan obj
130 g
->gc
->GCWrite(obj
, &tempi
);
131 g
->gc
->GCWrite(obj
, &tempj
);
136 int getIndexedInt(PyrObject
*obj
, int index
, int *value
);
137 void DumpBackTrace(VMGlobals
*g
);
139 int basicAt(struct VMGlobals
*g
, int numArgsPushed
)
148 if (NotObj(a
)) return errWrongType
;
149 obj
= slotRawObject(a
);
150 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
151 return errNotAnIndexableObject
;
153 int err
= slotIntVal(b
, &index
);
155 if (index
< 0 || index
>= obj
->size
) {
158 getIndexedSlot(obj
, a
, index
);
160 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
161 PyrObject
*indexArray
= slotRawObject(b
);
162 int size
= indexArray
->size
;
163 PyrObject
*outArray
= newPyrArray(g
->gc
, size
, 0, true);
164 PyrSlot
*outArraySlots
= outArray
->slots
;
165 for (int i
=0; i
<size
; ++i
) {
166 int err
= getIndexedInt(indexArray
, i
, &index
);
168 if (index
< 0 || index
>= obj
->size
) {
169 slotCopy(&outArraySlots
[i
],&o_nil
);
171 getIndexedSlot(obj
, outArraySlots
+ i
, index
);
174 outArray
->size
= size
;
175 SetObject(a
, outArray
);
177 return errIndexNotAnInteger
;
182 int basicRemoveAt(struct VMGlobals
*g
, int numArgsPushed
)
185 int index
, length
, elemsize
;
192 if (NotObj(a
)) return errWrongType
;
193 int err
= slotIntVal(b
, &index
);
194 if (err
) return errWrongType
;
196 obj
= slotRawObject(a
);
197 if (obj
->obj_flags
& obj_immutable
) return errImmutableObject
;
198 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
199 return errNotAnIndexableObject
;
201 if (index
< 0 || index
>= obj
->size
) return errIndexOutOfRange
;
202 switch (obj
->obj_format
) {
205 ptr
= obj
->slots
+ index
;
206 slotCopy(a
, (PyrSlot
*)ptr
);
209 ptr
= obj
->slots
+ index
;
210 SetFloat(a
, *(double*)ptr
);
213 ptr
= ((float*)(obj
->slots
)) + index
;
214 SetFloat(a
, *(float*)ptr
);
217 ptr
= ((int32
*)(obj
->slots
)) + index
;
218 SetInt(a
, *(int32
*)ptr
);
221 ptr
= ((int16
*)(obj
->slots
)) + index
;
222 SetInt(a
, *(int16
*)ptr
);
225 ptr
= ((int8
*)(obj
->slots
)) + index
;
226 SetInt(a
, *(int8
*)ptr
);
229 ptr
= ((int*)(obj
->slots
)) + index
;
230 SetSymbol(a
, *(PyrSymbol
**)ptr
);
233 ptr
= ((unsigned char*)(obj
->slots
)) + index
;
234 SetChar(a
, *(unsigned char*)ptr
);
237 length
= obj
->size
- index
- 1;
239 elemsize
= gFormatElemSize
[obj
->obj_format
];
240 memmove(ptr
, (char*)ptr
+ elemsize
, length
* elemsize
);
241 if (obj
->obj_format
<= obj_slot
) {
242 // might be partial scan object
243 g
->gc
->GCWrite(obj
, obj
->slots
+ index
);
251 int basicTakeAt(struct VMGlobals
*g
, int numArgsPushed
);
252 int basicTakeAt(struct VMGlobals
*g
, int numArgsPushed
)
255 int index
, lastIndex
;
261 if (NotObj(a
)) return errWrongType
;
262 int err
= slotIntVal(b
, &index
);
263 if (err
) return errWrongType
;
265 obj
= slotRawObject(a
);
266 if (obj
->obj_flags
& obj_immutable
) return errImmutableObject
;
267 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
268 return errNotAnIndexableObject
;
270 lastIndex
= obj
->size
- 1;
271 if (index
< 0 || index
>= obj
->size
) return errIndexOutOfRange
;
272 switch (obj
->obj_format
) {
274 PyrSlot
* ptr
= obj
->slots
+ index
;
275 PyrSlot
* lastptr
= obj
->slots
+ lastIndex
;
278 // might be partial scan obj
279 g
->gc
->GCWrite(obj
, ptr
);
282 PyrSlot
* ptr
= obj
->slots
+ index
;
283 PyrSlot
* lastptr
= obj
->slots
+ lastIndex
;
284 SetFloat(a
, *(double*)ptr
);
286 // might be partial scan obj
287 g
->gc
->GCWrite(obj
, ptr
);
290 float* ptr
= ((float*)(obj
->slots
)) + index
;
291 float* lastptr
= ((float*)(obj
->slots
)) + lastIndex
;
292 SetFloat(a
, *(float*)ptr
);
296 int32
* ptr
= ((int32
*)(obj
->slots
)) + index
;
297 int32
* lastptr
= ((int32
*)(obj
->slots
)) + lastIndex
;
298 SetInt(a
, *(int32
*)ptr
);
302 int16
* ptr
= ((int16
*)(obj
->slots
)) + index
;
303 int16
* lastptr
= ((int16
*)(obj
->slots
)) + lastIndex
;
304 SetInt(a
, *(int16
*)ptr
);
308 int8
* ptr
= ((int8
*)(obj
->slots
)) + index
;
309 int8
* lastptr
= ((int8
*)(obj
->slots
)) + lastIndex
;
310 SetInt(a
, *(int8
*)ptr
);
314 int32
* ptr
= ((int32
*)(obj
->slots
)) + index
;
315 int32
* lastptr
= ((int32
*)(obj
->slots
)) + lastIndex
;
316 SetSymbol(a
, *(PyrSymbol
**)ptr
);
320 unsigned char* ptr
= ((unsigned char*)(obj
->slots
)) + index
;
321 unsigned char* lastptr
= ((unsigned char*)(obj
->slots
)) + lastIndex
;
322 SetChar(a
, *(unsigned char*)ptr
);
330 int basicWrapAt(struct VMGlobals
*g
, int numArgsPushed
)
338 if (NotObj(a
)) return errWrongType
;
339 obj
= slotRawObject(a
);
340 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
341 return errNotAnIndexableObject
;
343 if(obj
->size
==0) {SetNil(a
); return errNone
; }
345 int err
= slotIntVal(b
, &index
);
348 index
= sc_mod((int)index
, (int)obj
->size
);
349 getIndexedSlot(obj
, a
, index
);
350 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
351 PyrObject
*indexArray
= slotRawObject(b
);
352 int size
= indexArray
->size
;
353 PyrObject
*outArray
= newPyrArray(g
->gc
, size
, 0, true);
354 PyrSlot
*outArraySlots
= outArray
->slots
;
355 for (int i
=0; i
<size
; ++i
) {
356 int err
= getIndexedInt(indexArray
, i
, &index
);
358 index
= sc_mod((int)index
, (int)obj
->size
);
359 getIndexedSlot(obj
, outArraySlots
+ i
, index
);
361 outArray
->size
= size
;
362 SetObject(a
, outArray
);
363 } else return errIndexNotAnInteger
;
368 int basicFoldAt(struct VMGlobals
*g
, int numArgsPushed
)
376 if (NotObj(a
)) return errWrongType
;
377 obj
= slotRawObject(a
);
378 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
379 return errNotAnIndexableObject
;
381 if(obj
->size
==0) {SetNil(a
); return errNone
; }
383 int err
= slotIntVal(b
, &index
);
386 index
= sc_fold(index
, 0, obj
->size
-1);
387 getIndexedSlot(obj
, a
, index
);
388 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
389 PyrObject
*indexArray
= slotRawObject(b
);
390 int size
= indexArray
->size
;
391 PyrObject
*outArray
= newPyrArray(g
->gc
, size
, 0, true);
392 PyrSlot
*outArraySlots
= outArray
->slots
;
393 for (int i
=0; i
<size
; ++i
) {
394 int err
= getIndexedInt(indexArray
, i
, &index
);
396 index
= sc_fold(index
, 0, obj
->size
-1);
397 getIndexedSlot(obj
, outArraySlots
+ i
, index
);
399 outArray
->size
= size
;
400 SetObject(a
, outArray
);
401 } else return errIndexNotAnInteger
;
406 int basicClipAt(struct VMGlobals
*g
, int numArgsPushed
)
414 if (NotObj(a
)) return errWrongType
;
415 obj
= slotRawObject(a
);
416 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
417 return errNotAnIndexableObject
;
419 if(obj
->size
==0) {SetNil(a
); return errNone
; }
421 int err
= slotIntVal(b
, &index
);
424 index
= sc_clip(index
, 0, obj
->size
- 1);
425 getIndexedSlot(obj
, a
, index
);
426 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
427 PyrObject
*indexArray
= slotRawObject(b
);
428 int size
= indexArray
->size
;
429 PyrObject
*outArray
= newPyrArray(g
->gc
, size
, 0, true);
430 PyrSlot
*outArraySlots
= outArray
->slots
;
431 for (int i
=0; i
<size
; ++i
) {
432 int err
= getIndexedInt(indexArray
, i
, &index
);
434 index
= sc_clip(index
, 0, obj
->size
- 1);
435 getIndexedSlot(obj
, outArraySlots
+ i
, index
);
437 outArray
->size
= size
;
438 SetObject(a
, outArray
);
439 } else return errIndexNotAnInteger
;
445 int basicPut(struct VMGlobals
*g
, int numArgsPushed
)
455 obj
= slotRawObject(a
);
456 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
457 return errNotAnIndexableObject
;
459 if (NotObj(a
)) return errWrongType
;
460 int err
= slotIntVal(b
, &index
);
463 if (index
< 0 || index
>= obj
->size
) return errIndexOutOfRange
;
464 return putIndexedSlot(g
, obj
, c
, index
);
465 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
466 PyrObject
*indexArray
= slotRawObject(b
);
467 int size
= slotRawObject(b
)->size
;
469 for (int i
=0; i
<size
; ++i
) {
471 int err
= getIndexedInt(indexArray
, i
, &index
);
473 if (index
< 0 || index
>= obj
->size
) return errIndexOutOfRange
;
474 err
= putIndexedSlot(g
, obj
, c
, index
);
478 } else return errIndexNotAnInteger
;
481 int basicClipPut(struct VMGlobals
*g
, int numArgsPushed
)
491 obj
= slotRawObject(a
);
492 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
493 return errNotAnIndexableObject
;
495 if (NotObj(a
)) return errWrongType
;
496 int err
= slotIntVal(b
, &index
);
499 index
= sc_clip(index
, 0, obj
->size
- 1);
500 return putIndexedSlot(g
, obj
, c
, index
);
501 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
502 PyrObject
*indexArray
= slotRawObject(b
);
503 int size
= slotRawObject(b
)->size
;
505 for (int i
=0; i
<size
; ++i
) {
507 int err
= getIndexedInt(indexArray
, i
, &index
);
509 index
= sc_clip(index
, 0, obj
->size
- 1);
510 err
= putIndexedSlot(g
, obj
, c
, index
);
514 } else return errIndexNotAnInteger
;
517 int basicWrapPut(struct VMGlobals
*g
, int numArgsPushed
)
527 obj
= slotRawObject(a
);
528 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
529 return errNotAnIndexableObject
;
531 if (NotObj(a
)) return errWrongType
;
532 int err
= slotIntVal(b
, &index
);
535 index
= sc_mod((int)index
, (int)obj
->size
);
536 return putIndexedSlot(g
, obj
, c
, index
);
537 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
538 PyrObject
*indexArray
= slotRawObject(b
);
539 int size
= slotRawObject(b
)->size
;
541 for (int i
=0; i
<size
; ++i
) {
543 int err
= getIndexedInt(indexArray
, i
, &index
);
545 index
= sc_mod((int)index
, (int)obj
->size
);
546 err
= putIndexedSlot(g
, obj
, c
, index
);
550 } else return errIndexNotAnInteger
;
553 int basicFoldPut(struct VMGlobals
*g
, int numArgsPushed
)
563 obj
= slotRawObject(a
);
564 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
565 return errNotAnIndexableObject
;
567 if (NotObj(a
)) return errWrongType
;
568 int err
= slotIntVal(b
, &index
);
571 index
= sc_fold(index
, 0, obj
->size
-1);
572 return putIndexedSlot(g
, obj
, c
, index
);
573 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
574 PyrObject
*indexArray
= slotRawObject(b
);
575 int size
= slotRawObject(b
)->size
;
577 for (int i
=0; i
<size
; ++i
) {
579 int err
= getIndexedInt(indexArray
, i
, &index
);
581 index
= sc_fold(index
, 0, obj
->size
-1);
582 err
= putIndexedSlot(g
, obj
, c
, index
);
586 } else return errIndexNotAnInteger
;
589 int prArrayPutEach(struct VMGlobals
*g
, int numArgsPushed
)
598 obj
= slotRawObject(a
);
599 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
600 return errNotAnIndexableObject
;
602 if (!isKindOfSlot(b
, class_arrayed_collection
)) return errWrongType
;
603 if (!isKindOfSlot(c
, class_arrayed_collection
)) return errWrongType
;
605 PyrSlot
*indices
= slotRawObject(b
)->slots
;
606 PyrSlot
*values
= slotRawObject(c
)->slots
;
607 int size
= slotRawObject(b
)->size
;
608 int valsize
= slotRawObject(c
)->size
;
610 for (int i
=0; i
<size
; ++i
) {
612 int err
= slotIntVal(indices
+ i
, &index
);
614 if (index
< 0 || index
>= obj
->size
) return errIndexOutOfRange
;
615 int valindex
= sc_mod(i
, valsize
);
616 err
= putIndexedSlot(g
, obj
, values
+ valindex
, index
);
624 int prArrayAssocAt(struct VMGlobals
*g
, int numArgsPushed
)
633 obj
= slotRawObject(a
);
635 int size
= obj
->size
;
636 if (obj
->obj_format
== obj_slot
) {
637 PyrSlot
*slots
= obj
->slots
;
638 for (int i
=0; i
<size
; i
+=2) {
639 if (SlotEq(slots
+i
, b
)) {
640 if (i
+1 >= size
) return errFailed
;
641 slotCopy(a
,&slots
[i
+1]);
648 for (int i
=0; i
<size
; i
+=2) {
649 getIndexedSlot(obj
, &slot
, i
);
650 if (SlotEq(&slot
, b
)) {
651 if (i
+1 >= size
) return errFailed
;
652 getIndexedSlot(obj
, &slot
, i
+1);
659 if (!found
) SetNil(a
);
665 int prArrayAssocPut(struct VMGlobals
*g
, int numArgsPushed
)
675 obj
= slotRawObject(a
);
677 int size
= obj
->size
;
678 if (obj
->obj_format
== obj_slot
) {
679 PyrSlot
*slots
= obj
->slots
;
680 for (int i
=0; i
<size
; i
+=2) {
681 if (SlotEq(slots
+i
, b
)) {
682 if (i
+1 >= size
) return errFailed
;
683 slotCopy(&slots
[i
+1],c
);
684 g
->gc
->GCWrite(obj
, c
);
691 for (int i
=0; i
<size
; i
+=2) {
692 getIndexedSlot(obj
, &slot
, i
);
693 if (SlotEq(&slot
, b
)) {
694 if (i
+1 >= size
) return errFailed
;
695 putIndexedSlot(g
, obj
, &slot
, i
+1);
696 g
->gc
->GCWrite(obj
, c
);
702 if (!found
) SetNil(a
);
707 int prArrayIndexOf(struct VMGlobals
*g
, int numArgsPushed
)
716 obj
= slotRawObject(a
);
718 int size
= obj
->size
;
719 if (obj
->obj_format
== obj_slot
) {
720 PyrSlot
*slots
= obj
->slots
;
721 for (int i
=0; i
<size
; ++i
) {
722 if (SlotEq(slots
+i
, b
)) {
730 for (int i
=0; i
<size
; ++i
) {
731 getIndexedSlot(obj
, &slot
, i
);
732 if (SlotEq(&slot
, b
)) {
739 if (!found
) SetNil(a
);
745 int prArrayPutSeries(struct VMGlobals
*g
, int numArgsPushed
)
747 PyrSlot
*a
, *b
, *c
, *d
, *e
;
755 PyrObject
*inobj
= slotRawObject(a
);
757 int size
= inobj
->size
;
759 if (NotInt(b
) && NotNil(b
)) return errWrongType
;
760 if (NotInt(c
) && NotNil(c
)) return errWrongType
;
761 if (NotInt(d
) && NotNil(d
)) return errWrongType
;
763 int first
= IsInt(b
) ? slotRawInt(b
) : 0;
764 int last
= IsInt(d
) ? slotRawInt(d
) : size
- 1;
765 int second
= IsInt(c
) ? slotRawInt(c
) : (first
< last
? first
+ 1 : first
- 1);
767 int step
= second
- first
;
769 first
= sc_clip(first
, 0, size
-1);
770 last
= sc_clip(last
, 0, size
-1);
774 if (step
== 0) return errFailed
;
776 for (int i
=first
; i
<=last
; ++i
) {
777 err
= putIndexedSlot(g
, inobj
, e
, i
);
780 } else if (step
== -1) {
781 for (int i
=last
; i
>=first
; --i
) {
782 err
= putIndexedSlot(g
, inobj
, e
, i
);
785 } else if (step
> 0) {
786 int length
= (last
- first
) / step
+ 1;
788 for (int i
=first
, j
=0; j
<length
; i
+=step
, ++j
) {
789 err
= putIndexedSlot(g
, inobj
, e
, i
);
792 } else if (step
< 0) {
793 int length
= (first
- last
) / -step
+ 1;
795 for (int i
=first
, j
=0; j
<length
; i
+=step
, ++j
) {
796 err
= putIndexedSlot(g
, inobj
, e
, i
);
804 int prArrayAdd(struct VMGlobals
*g
, int numArgsPushed
);
805 int prArrayAdd(struct VMGlobals
*g
, int numArgsPushed
)
807 PyrSlot
*a
, *b
, *slots
;
809 int maxelems
, elemsize
, format
, tag
, numbytes
;
816 array
= slotRawObject(a
);
817 if (array
->obj_flags
& obj_immutable
) return errImmutableObject
;
818 format
= slotRawObject(a
)->obj_format
;
819 tag
= gFormatElemTag
[format
];
821 if (GetTag(b) != tag) return errWrongType;
822 } else if (tag == 0) {
823 if (NotFloat(b)) return errWrongType;
824 } // else format is obj_slot, any tag is acceptable*/
825 elemsize
= gFormatElemSize
[format
];
826 maxelems
= MAXINDEXSIZE(array
);
827 if (array
->size
>= maxelems
) {
828 numbytes
= sizeof(PyrSlot
) << (array
->obj_sizeclass
+ 1);
829 array
= g
->gc
->New(numbytes
, 0, format
, true);
830 array
->classptr
= slotRawObject(a
)->classptr
;
831 array
->size
= slotRawObject(a
)->size
;
832 memcpy(array
->slots
, slotRawObject(a
)->slots
, slotRawObject(a
)->size
* elemsize
);
835 slots
= array
->slots
;
838 slotCopy(&slots
[array
->size
++],b
);
839 g
->gc
->GCWrite(array
, b
);
842 err
= slotIntVal(b
, &ival
);
844 ((int32
*)slots
)[array
->size
++] = ival
;
847 err
= slotIntVal(b
, &ival
);
849 ((int16
*)slots
)[array
->size
++] = ival
;
852 err
= slotIntVal(b
, &ival
);
854 ((int8
*)slots
)[array
->size
++] = ival
;
857 if (NotChar(b
)) return errWrongType
;
858 ((char*)slots
)[array
->size
++] = slotRawChar(b
);
861 if (NotSym(b
)) return errWrongType
;
862 ((PyrSymbol
**)slots
)[array
->size
++] = slotRawSymbol(b
);
865 err
= slotDoubleVal(b
, &fval
);
867 ((float*)slots
)[array
->size
++] = fval
;
870 err
= slotDoubleVal(b
, &fval
);
872 ((double*)slots
)[array
->size
++] = fval
;
879 int prArrayInsert(struct VMGlobals
*g
, int numArgsPushed
);
880 int prArrayInsert(struct VMGlobals
*g
, int numArgsPushed
)
882 PyrSlot
*a
, *b
, *c
, *slots1
, *slots2
;
883 PyrObject
*array
, *oldarray
;
884 int maxelems
, elemsize
, format
, tag
;
885 int err
, ival
, size
, index
, remain
, numbytes
;
888 a
= g
->sp
- 2; // array
889 b
= g
->sp
- 1; // index
891 if (NotInt(b
)) return errWrongType
;
893 array
= slotRawObject(a
);
894 if (array
->obj_flags
& obj_immutable
) return errImmutableObject
;
895 format
= slotRawObject(a
)->obj_format
;
896 tag
= gFormatElemTag
[format
];
899 index
= slotRawInt(b
);
900 index
= sc_clip(index
, 0, size
);
901 remain
= size
- index
;
903 elemsize
= gFormatElemSize
[format
];
904 maxelems
= MAXINDEXSIZE(array
);
905 if (size
+1 > maxelems
) {
908 numbytes
= sizeof(PyrSlot
) << (array
->obj_sizeclass
+ 1);
909 array
= g
->gc
->New(numbytes
, 0, format
, true);
911 array
->classptr
= oldarray
->classptr
;
913 array
->size
= size
+1;
915 slots1
= array
->slots
;
916 slots2
= oldarray
->slots
;
918 memcpy(slots1
, slots2
, index
* elemsize
);
924 slotCopy(&slots1
[index
],c
);
925 if (remain
) memcpy(slots1
+ index
+ 1, slots2
+ index
, remain
* elemsize
);
926 if (!g
->gc
->ObjIsGrey(array
)) g
->gc
->ToGrey(array
);
929 err
= slotIntVal(c
, &ival
);
931 ((int32
*)slots1
)[index
] = ival
;
933 memcpy((int*)slots1
+ index
+ 1, (int*)slots2
+ index
,
938 err
= slotIntVal(c
, &ival
);
940 ((int16
*)slots1
)[index
] = ival
;
942 memcpy((short*)slots1
+ index
+ 1, (short*)slots2
+ index
,
947 err
= slotIntVal(c
, &ival
);
949 ((int8
*)slots1
)[index
] = ival
;
951 memcpy((char*)slots1
+ index
+ 1, (char*)slots2
+ index
,
956 if (NotChar(c
)) return errWrongType
;
957 ((char*)slots1
)[index
] = slotRawInt(c
);
959 memcpy((char*)slots1
+ index
+ 1, (char*)slots2
+ index
,
964 if (NotSym(c
)) return errWrongType
;
965 ((PyrSymbol
**)slots1
)[index
] = slotRawSymbol(c
);
967 memcpy((int*)slots1
+ index
+ 1, (int*)slots2
+ index
,
972 err
= slotDoubleVal(c
, &fval
);
974 ((float*)slots1
)[index
] = fval
;
976 memcpy((float*)slots1
+ index
+ 1, (float*)slots2
+ index
,
981 err
= slotDoubleVal(c
, &fval
);
983 ((double*)slots1
)[index
] = fval
;
985 memcpy((double*)slots1
+ index
+ 1, (double*)slots2
+ index
,
991 array
->size
= size
+1;
992 slots1
= array
->slots
;
995 if (remain
) memmove(slots1
+ index
+ 1, slots1
+ index
, remain
* elemsize
);
996 slotCopy(&slots1
[index
],c
);
997 if (!g
->gc
->ObjIsGrey(array
)) g
->gc
->ToGrey(array
);
1001 memmove((int*)slots1
+ index
+ 1, (int*)slots1
+ index
,
1004 err
= slotIntVal(c
, &ival
);
1005 if (err
) return err
;
1006 ((int32
*)slots1
)[index
] = ival
;
1010 memmove((short*)slots1
+ index
+ 1, (short*)slots1
+ index
,
1013 err
= slotIntVal(c
, &ival
);
1014 if (err
) return err
;
1015 ((int16
*)slots1
)[index
] = ival
;
1019 memmove((char*)slots1
+ index
+ 1, (char*)slots1
+ index
,
1022 err
= slotIntVal(c
, &ival
);
1023 if (err
) return err
;
1024 ((int8
*)slots1
)[index
] = ival
;
1028 memmove((char*)slots1
+ index
+ 1, (char*)slots1
+ index
,
1031 if (NotChar(c
)) return errWrongType
;
1032 ((char*)slots1
)[index
] = slotRawInt(c
);
1036 memmove((int*)slots1
+ index
+ 1, (int*)slots1
+ index
,
1039 if (NotSym(c
)) return errWrongType
;
1040 ((PyrSymbol
**)slots1
)[index
] = slotRawSymbol(c
);
1044 memmove((float*)slots1
+ index
+ 1, (float*)slots1
+ index
,
1047 err
= slotDoubleVal(c
, &fval
);
1048 if (err
) return err
;
1049 ((float*)slots1
)[index
] = fval
;
1053 memmove((double*)slots1
+ index
+ 1, (double*)slots1
+ index
,
1056 err
= slotDoubleVal(c
, &fval
);
1057 if (err
) return err
;
1058 ((double*)slots1
)[index
] = fval
;
1065 int prArrayFill(struct VMGlobals
*g
, int numArgsPushed
);
1066 int prArrayFill(struct VMGlobals
*g
, int numArgsPushed
)
1068 PyrSlot
*a
, *b
, *slots
;
1080 array
= slotRawObject(a
);
1081 format
= slotRawObject(a
)->obj_format
;
1082 tag
= gFormatElemTag
[format
];
1084 if (GetTag(b) != tag) return errWrongType;
1085 } else if (tag == 0) {
1086 if (NotFloat(b)) return errWrongType;
1087 } // else format is obj_slot, any tag is acceptable*/
1088 slots
= array
->slots
;
1091 if (array
->obj_flags
& obj_immutable
) return errImmutableObject
;
1092 for (i
=0; i
<array
->size
; ++i
) {
1093 slotCopy(&slots
[i
],b
);
1095 g
->gc
->GCWrite(array
, b
);
1098 err
= slotIntVal(b
, &ival
);
1099 if (err
) return err
;
1100 for (i
=0; i
<array
->size
; ++i
) {
1101 ((int32
*)slots
)[i
] = ival
;
1105 err
= slotIntVal(b
, &ival
);
1106 if (err
) return err
;
1107 for (i
=0; i
<array
->size
; ++i
) {
1108 ((int16
*)slots
)[i
] = ival
;
1112 err
= slotIntVal(b
, &ival
);
1113 if (err
) return err
;
1114 for (i
=0; i
<array
->size
; ++i
) {
1115 ((int8
*)slots
)[i
] = ival
;
1119 if (NotChar(b
)) return errWrongType
;
1120 ival
= slotRawInt(b
);
1121 for (i
=0; i
<array
->size
; ++i
) {
1122 ((char*)slots
)[i
] = ival
;
1126 if (NotSym(b
)) return errWrongType
;
1127 sym
= slotRawSymbol(b
);
1128 for (i
=0; i
<array
->size
; ++i
) {
1129 ((PyrSymbol
**)slots
)[i
] = sym
;
1133 err
= slotDoubleVal(b
, &fval
);
1134 if (err
) return err
;
1135 for (i
=0; i
<array
->size
; ++i
) {
1136 ((float*)slots
)[i
] = fval
;
1140 err
= slotDoubleVal(b
, &fval
);
1141 if (err
) return err
;
1142 for (i
=0; i
<array
->size
; ++i
) {
1143 ((double*)slots
)[i
] = fval
;
1150 int prArrayPop(struct VMGlobals
*g
, int numArgsPushed
);
1151 int prArrayPop(struct VMGlobals
*g
, int numArgsPushed
)
1161 array
= slotRawObject(a
);
1162 if (array
->obj_flags
& obj_immutable
) return errImmutableObject
;
1163 if (array
->size
> 0) {
1164 format
= array
->obj_format
;
1165 slots
= array
->slots
;
1168 slotCopy(a
,&slots
[--array
->size
]);
1171 z
= ((int32
*)slots
)[--array
->size
];
1175 z
= ((int16
*)slots
)[--array
->size
];
1179 z
= ((int8
*)slots
)[--array
->size
];
1183 z
= ((char*)slots
)[--array
->size
];
1187 sym
= ((PyrSymbol
**)slots
)[--array
->size
];
1191 SetFloat(a
, ((float*)slots
)[--array
->size
]);
1194 SetFloat(a
, slotRawFloat(&slots
[--array
->size
]));
1203 int prArrayExtend(struct VMGlobals
*g
, int numArgsPushed
);
1204 int prArrayExtend(struct VMGlobals
*g
, int numArgsPushed
)
1206 int numbytes
, elemsize
, format
;
1209 PyrSlot
*a
= g
->sp
- 2; // array
1210 PyrSlot
*b
= g
->sp
- 1; // size
1211 PyrSlot
*c
= g
->sp
; // filler item
1214 if (NotInt(b
)) return errWrongType
;
1215 PyrObject
* aobj
= slotRawObject(a
);
1216 if (slotRawInt(b
) <= aobj
->size
) {
1217 aobj
->size
= slotRawInt(b
);
1221 format
= aobj
->obj_format
;
1222 if (slotRawInt(b
) > MAXINDEXSIZE(aobj
)) {
1223 elemsize
= gFormatElemSize
[format
];
1224 numbytes
= slotRawInt(b
) * elemsize
;
1226 PyrObject
*obj
= g
->gc
->New(numbytes
, 0, format
, true);
1227 obj
->classptr
= aobj
->classptr
;
1228 obj
->size
= aobj
->size
;
1229 memcpy(obj
->slots
, aobj
->slots
, aobj
->size
* elemsize
);
1235 int fillSize
= slotRawInt(b
) - aobj
->size
;
1240 PyrSlot
*slots
= aobj
->slots
;
1243 fillSlots(slots
+ aobj
->size
, fillSize
, c
);
1244 g
->gc
->GCWrite(aobj
, c
);
1247 int32
* ptr
= (int32
*)slots
+ aobj
->size
;
1248 err
= slotIntVal(c
, &ival
);
1249 if (err
) return err
;
1250 for (int i
=0; i
<fillSize
; ++i
) ptr
[i
] = ival
;
1253 int16
* ptr
= (int16
*)slots
+ aobj
->size
;
1254 err
= slotIntVal(c
, &ival
);
1255 if (err
) return err
;
1256 for (int i
=0; i
<fillSize
; ++i
) ptr
[i
] = ival
;
1259 int8
* ptr
= (int8
*)slots
+ aobj
->size
;
1260 err
= slotIntVal(c
, &ival
);
1261 if (err
) return err
;
1262 for (int i
=0; i
<fillSize
; ++i
) ptr
[i
] = ival
;
1265 char* ptr
= (char*)slots
+ aobj
->size
;
1266 if (NotChar(c
)) return errWrongType
;
1267 ival
= slotRawChar(c
);
1268 for (int i
=0; i
<fillSize
; ++i
) ptr
[i
] = ival
;
1271 PyrSymbol
** ptr
= (PyrSymbol
**)slots
+ aobj
->size
;
1272 if (NotSym(c
)) return errWrongType
;
1273 PyrSymbol
*sym
= slotRawSymbol(c
);
1274 for (int i
=0; i
<fillSize
; ++i
) ptr
[i
] = sym
;
1277 float* ptr
= (float*)slots
+ aobj
->size
;
1278 err
= slotFloatVal(c
, &fval
);
1279 for (int i
=0; i
<fillSize
; ++i
) ptr
[i
] = fval
;
1282 double* ptr
= (double*)slots
+ aobj
->size
;
1283 err
= slotDoubleVal(c
, &dval
);
1284 for (int i
=0; i
<fillSize
; ++i
) ptr
[i
] = dval
;
1288 aobj
->size
= slotRawInt(b
);
1292 int prArrayGrow(struct VMGlobals
*g
, int numArgsPushed
);
1293 int prArrayGrow(struct VMGlobals
*g
, int numArgsPushed
)
1296 PyrObject
*obj
, *aobj
;
1297 int numbytes
, elemsize
, format
;
1302 if (NotInt(b
)) return errWrongType
;
1303 if (slotRawInt(b
) <= 0) return errNone
;
1304 aobj
= slotRawObject(a
);
1306 if (aobj
->size
+ slotRawInt(b
) <= MAXINDEXSIZE(aobj
)) return errNone
;
1308 format
= aobj
->obj_format
;
1309 elemsize
= gFormatElemSize
[format
];
1310 numbytes
= ((aobj
->size
+ slotRawInt(b
)) * elemsize
);
1312 obj
= g
->gc
->New(numbytes
, 0, format
, true);
1313 obj
->classptr
= aobj
->classptr
;
1314 obj
->size
= aobj
->size
;
1315 memcpy(obj
->slots
, aobj
->slots
, aobj
->size
* elemsize
);
1321 int prArrayGrowClear(struct VMGlobals
*g
, int numArgsPushed
);
1322 int prArrayGrowClear(struct VMGlobals
*g
, int numArgsPushed
)
1325 PyrObject
*obj
, *aobj
;
1326 int numbytes
, elemsize
, format
;
1331 if (NotInt(b
)) return errWrongType
;
1332 if (slotRawInt(b
) <= 0) return errNone
;
1333 aobj
= slotRawObject(a
);
1335 if (aobj
->size
+ slotRawInt(b
) <= MAXINDEXSIZE(aobj
)) {
1338 format
= aobj
->obj_format
;
1339 elemsize
= gFormatElemSize
[format
];
1340 numbytes
= ((aobj
->size
+ slotRawInt(b
)) * elemsize
);
1342 obj
= g
->gc
->New(numbytes
, 0, format
, true);
1343 obj
->classptr
= aobj
->classptr
;
1344 memcpy(obj
->slots
, aobj
->slots
, aobj
->size
* elemsize
);
1347 if (obj
->obj_format
== obj_slot
) {
1348 nilSlots(obj
->slots
+ aobj
->size
, slotRawInt(b
));
1350 memset((char*)(obj
->slots
) + aobj
->size
* gFormatElemSize
[format
],
1351 0, slotRawInt(b
) * gFormatElemSize
[format
]);
1353 obj
->size
= aobj
->size
+ slotRawInt(b
);
1359 int prArrayCat(struct VMGlobals
*g
, int numArgsPushed
);
1360 int prArrayCat(struct VMGlobals
*g
, int numArgsPushed
)
1363 PyrObject
*obj
, *aobj
, *bobj
;
1365 int numbytes
, format
;
1370 if (NotObj(b
) || slotRawObject(a
)->classptr
!= slotRawObject(b
)->classptr
) return errWrongType
;
1371 aobj
= slotRawObject(a
);
1372 bobj
= slotRawObject(b
);
1373 size
= aobj
->size
+ bobj
->size
;
1374 format
= aobj
->obj_format
;
1375 assert(aobj
->obj_format
== bobj
->obj_format
);
1376 elemsize
= gFormatElemSize
[format
];
1377 numbytes
= (size
* elemsize
);
1379 obj
= g
->gc
->New(numbytes
, 0, format
, true);
1380 obj
->classptr
= aobj
->classptr
;
1382 memcpy(obj
->slots
, aobj
->slots
, aobj
->size
* elemsize
);
1383 memcpy((char*)obj
->slots
+ aobj
->size
* elemsize
,
1384 bobj
->slots
, bobj
->size
* elemsize
);
1391 int prArrayAddAll(struct VMGlobals
*g
, int numArgsPushed
);
1392 int prArrayAddAll(struct VMGlobals
*g
, int numArgsPushed
)
1395 PyrObject
*obj
, *aobj
;
1396 int elemsize
, newindexedsize
, newsizebytes
, asize
, bsize
;
1402 if (NotObj(b
) || slotRawObject(a
)->classptr
!= slotRawObject(b
)->classptr
) return errWrongType
;
1403 aobj
= slotRawObject(a
);
1404 format
= aobj
->obj_format
;
1405 elemsize
= gFormatElemSize
[format
];
1407 bsize
= slotRawObject(b
)->size
;
1408 newindexedsize
= asize
+ bsize
;
1409 newsizebytes
= newindexedsize
* elemsize
;
1411 if (newindexedsize
> MAXINDEXSIZE(aobj
)) {
1412 obj
= g
->gc
->New(newsizebytes
, 0, format
, true);
1413 obj
->classptr
= aobj
->classptr
;
1414 memcpy(obj
->slots
, aobj
->slots
, asize
* elemsize
);
1418 if (format
== obj_slot
&& !g
->gc
->ObjIsGrey(obj
)) {
1422 obj
->size
= newindexedsize
;
1423 memcpy((char*)obj
->slots
+ asize
* elemsize
,
1424 slotRawObject(b
)->slots
, bsize
* elemsize
);
1429 int prArrayOverwrite(struct VMGlobals
*g
, int numArgsPushed
);
1430 int prArrayOverwrite(struct VMGlobals
*g
, int numArgsPushed
)
1433 PyrObject
*obj
, *aobj
;
1434 int err
, elemsize
, newindexedsize
, newsizebytes
, pos
, asize
, bsize
;
1441 if (NotObj(b
) || slotRawObject(a
)->classptr
!= slotRawObject(b
)->classptr
) return errWrongType
;
1442 err
= slotIntVal(c
, &pos
);
1443 if (err
) return errWrongType
;
1444 if (pos
< 0 || pos
> slotRawObject(a
)->size
) return errIndexOutOfRange
;
1446 aobj
= slotRawObject(a
);
1447 format
= aobj
->obj_format
;
1448 elemsize
= gFormatElemSize
[format
];
1450 bsize
= slotRawObject(b
)->size
;
1451 newindexedsize
= pos
+ bsize
;
1452 newindexedsize
= sc_max(asize
, newindexedsize
);
1453 newsizebytes
= newindexedsize
* elemsize
;
1455 if (newindexedsize
> MAXINDEXSIZE(aobj
)) {
1456 obj
= g
->gc
->New(newsizebytes
, 0, format
, true);
1457 obj
->classptr
= aobj
->classptr
;
1458 memcpy(obj
->slots
, aobj
->slots
, asize
* elemsize
);
1462 if (format
== obj_slot
&& !g
->gc
->ObjIsGrey(obj
)) {
1466 obj
->size
= newindexedsize
;
1467 memcpy((char*)(obj
->slots
) + pos
* elemsize
,
1468 slotRawObject(b
)->slots
, bsize
* elemsize
);
1473 int prArrayReverse(struct VMGlobals
*g
, int numArgsPushed
)
1475 PyrSlot
*a
, *slots1
, *slots2
;
1476 PyrObject
*obj1
, *obj2
;
1480 obj1
= slotRawObject(a
);
1482 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1483 slots1
= obj1
->slots
;
1484 slots2
= obj2
->slots
;
1485 for (i
=0, j
=size
-1; i
<size
; ++i
,--j
) {
1486 slotCopy(&slots2
[j
],&slots1
[i
]);
1493 int prArrayScramble(struct VMGlobals
*g
, int numArgsPushed
)
1495 PyrSlot
*a
, *slots1
, *slots2
, temp
;
1496 PyrObject
*obj1
, *obj2
;
1497 int i
, j
, k
, m
, size
;
1500 obj1
= slotRawObject(a
);
1502 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1503 slots1
= obj1
->slots
;
1504 slots2
= obj2
->slots
;
1505 memcpy(slots2
, slots1
, size
* sizeof(PyrSlot
));
1508 for (i
=0, m
=k
; i
<k
-1; ++i
, --m
) {
1509 j
= i
+ g
->rgen
->irand(m
);
1510 slotCopy(&temp
,&slots2
[i
]);
1511 slotCopy(&slots2
[i
],&slots2
[j
]);
1512 slotCopy(&slots2
[j
],&temp
);
1520 int prArrayRotate(struct VMGlobals
*g
, int numArgsPushed
)
1522 PyrSlot
*a
, *b
, *slots
;
1523 PyrObject
*obj1
, *obj2
;
1528 if (NotInt(b
)) return errWrongType
;
1530 obj1
= slotRawObject(a
);
1532 n
= sc_mod((int)slotRawInt(b
), (int)size
);
1533 slots
= obj1
->slots
;
1534 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1535 for (i
=0, j
=n
; i
<size
; ++i
) {
1536 slotCopy(&obj2
->slots
[j
],&slots
[i
]);
1537 if (++j
>= size
) j
=0;
1544 int prArrayStutter(struct VMGlobals
*g
, int numArgsPushed
)
1546 PyrSlot
*a
, *b
, *slots1
, *slots2
;
1547 PyrObject
*obj1
, *obj2
;
1548 int i
, j
, k
, m
, n
, size
;
1552 if (NotInt(b
)) return errWrongType
;
1554 obj1
= slotRawObject(a
);
1558 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1559 slots1
= obj1
->slots
;
1560 slots2
= obj2
->slots
;
1561 for (i
=0,j
=0; i
<m
; ++i
) {
1562 for (k
=0; k
<n
; ++k
,++j
) {
1563 slotCopy(&slots2
[j
],&slots1
[i
]);
1571 int prArrayMirror(struct VMGlobals
*g
, int numArgsPushed
)
1574 PyrObject
*obj1
, *obj2
;
1579 obj1
= slotRawObject(a
);
1580 slots
= obj1
->slots
;
1581 size
= obj1
->size
* 2 - 1;
1582 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1584 // copy first part of list
1585 memcpy(obj2
->slots
, slots
, obj1
->size
* sizeof(PyrSlot
));
1588 for (i
=0, j
=size
-1; i
<k
; ++i
,--j
) {
1589 slotCopy(&obj2
->slots
[j
],&slots
[i
]);
1595 int prArrayMirror1(struct VMGlobals
*g
, int numArgsPushed
)
1598 PyrObject
*obj1
, *obj2
;
1603 obj1
= slotRawObject(a
);
1604 slots
= obj1
->slots
;
1605 size
= obj1
->size
* 2 - 2;
1606 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1608 // copy first part of list
1609 memcpy(obj2
->slots
, slots
, obj1
->size
* sizeof(PyrSlot
));
1612 for (i
=1, j
=size
-1; i
<k
; ++i
,--j
) {
1613 slotCopy(&obj2
->slots
[j
],&slots
[i
]);
1619 int prArrayMirror2(struct VMGlobals
*g
, int numArgsPushed
)
1622 PyrObject
*obj1
, *obj2
;
1627 obj1
= slotRawObject(a
);
1628 slots
= obj1
->slots
;
1629 size
= obj1
->size
* 2;
1630 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1632 // copy first part of list
1633 memcpy(obj2
->slots
, slots
, obj1
->size
* sizeof(PyrSlot
));
1636 for (i
=0, j
=size
-1; i
<k
; ++i
,--j
) {
1637 slotCopy(&obj2
->slots
[j
],&slots
[i
]);
1644 int prArrayExtendWrap(struct VMGlobals
*g
, int numArgsPushed
)
1646 PyrSlot
*a
, *b
, *slots
;
1647 PyrObject
*obj1
, *obj2
;
1652 if (NotInt(b
)) return errWrongType
;
1654 obj1
= slotRawObject(a
);
1655 size
= slotRawInt(b
);
1656 if(obj1
->size
> 0) {
1657 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1659 slots
= obj2
->slots
;
1660 // copy first part of list
1661 memcpy(slots
, obj1
->slots
, sc_min(size
, obj1
->size
) * sizeof(PyrSlot
));
1662 if (size
> obj1
->size
) {
1665 for (i
=0,j
=m
; j
<size
; ++i
,++j
) {
1666 slotCopy(&slots
[j
],&slots
[i
]);
1670 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, true, true);
1676 int prArrayExtendFold(struct VMGlobals
*g
, int numArgsPushed
)
1678 PyrSlot
*a
, *b
, *slots
;
1679 PyrObject
*obj1
, *obj2
;
1684 if (NotInt(b
)) return errWrongType
;
1686 obj1
= slotRawObject(a
);
1687 size
= slotRawInt(b
);
1688 if(obj1
->size
> 0) {
1689 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1691 slots
= obj2
->slots
;
1692 // copy first part of list
1693 memcpy(slots
, obj1
->slots
, sc_min(size
, obj1
->size
) * sizeof(PyrSlot
));
1694 if (size
> obj1
->size
) {
1697 for (i
=0,j
=m
; j
<size
; ++i
,++j
) {
1698 slotCopy(&slots
[j
], &slots
[sc_fold(j
,0,m
-1)]);
1702 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, true, true);
1708 int prArrayExtendLast(struct VMGlobals
*g
, int numArgsPushed
)
1710 PyrSlot
*a
, *b
, *slots
, last
;
1711 PyrObject
*obj1
, *obj2
;
1716 if (NotInt(b
)) return errWrongType
;
1718 obj1
= slotRawObject(a
);
1719 size
= slotRawInt(b
);
1720 if(obj1
->size
> 0) {
1721 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1723 slots
= obj2
->slots
;
1724 // copy first part of list
1725 memcpy(slots
, obj1
->slots
, sc_min(size
, obj1
->size
) * sizeof(PyrSlot
));
1726 if (size
> obj1
->size
) {
1729 slotCopy(&last
,&slots
[m
-1]);
1730 for (i
=0,j
=m
; j
<size
; ++i
,++j
) {
1731 slotCopy(&slots
[j
],&last
);
1735 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, true, true);
1741 int prArrayPermute(struct VMGlobals
*g
, int numArgsPushed
)
1743 PyrSlot
*a
, *b
, *slots1
, *slots2
, temp
;
1744 PyrObject
*obj1
, *obj2
;
1745 int i
, j
, m
, z
, size
;
1749 if (NotInt(b
)) return errWrongType
;
1751 obj1
= slotRawObject(a
);
1753 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1755 slots1
= obj1
->slots
;
1756 slots2
= obj2
->slots
;
1757 memcpy(slots2
, slots1
, size
* sizeof(PyrSlot
));
1759 for (i
=0, m
=size
; i
<size
-1; ++i
, --m
) {
1760 j
= i
+ sc_mod((int)z
, (int)(size
-i
));
1761 z
= sc_div(z
,size
-i
);
1762 slotCopy(&temp
,&slots2
[i
]);
1763 slotCopy(&slots2
[i
],&slots2
[j
]);
1764 slotCopy(&slots2
[j
],&temp
);
1771 int prArrayAllTuples(struct VMGlobals
*g
, int numArgsPushed
)
1773 PyrSlot
*a
, *b
, *slots1
, *slots2
, *slots3
;
1774 PyrObject
*obj1
, *obj2
, *obj3
;
1778 if (NotInt(b
)) return errWrongType
;
1779 int maxSize
= slotRawInt(b
);
1781 obj1
= slotRawObject(a
);
1782 slots1
= obj1
->slots
;
1784 int tupSize
= obj1
->size
;
1785 for (int i
=0; i
< tupSize
; ++i
) {
1786 if (isKindOfSlot(slots1
+i
, class_array
)) {
1787 newSize
*= slotRawObject(&slots1
[i
])->size
;
1790 if (newSize
> maxSize
) newSize
= maxSize
;
1792 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, newSize
, false, true);
1793 slots2
= obj2
->slots
;
1794 SetObject(b
, obj2
); // store reference on stack, so both source and destination objects can be reached by the gc
1796 for (int i
=0; i
< newSize
; ++i
) {
1798 obj3
= instantiateObject(g
->gc
, obj1
->classptr
, tupSize
, false, true);
1799 slots3
= obj3
->slots
;
1800 for (int j
=tupSize
-1; j
>= 0; --j
) {
1801 if (isKindOfSlot(slots1
+j
, class_array
)) {
1802 PyrObject
*obj4
= slotRawObject(&slots1
[j
]);
1803 slotCopy(&slots3
[j
], &obj4
->slots
[k
% obj4
->size
]);
1804 g
->gc
->GCWrite(obj3
, obj4
);
1807 slotCopy(&slots3
[j
], &slots1
[j
]);
1810 obj3
->size
= tupSize
;
1811 SetObject(obj2
->slots
+i
, obj3
);
1812 g
->gc
->GCWriteNew(obj2
, obj3
);
1819 int prArrayPyramid(struct VMGlobals
*g
, int numArgsPushed
)
1821 PyrSlot
*a
, *b
, *slots
;
1822 PyrObject
*obj1
, *obj2
;
1823 int i
, j
, k
, n
, m
, numslots
, x
;
1827 if (NotInt(b
)) return errWrongType
;
1829 obj1
= slotRawObject(a
);
1830 slots
= obj1
->slots
;
1831 m
= sc_clip(slotRawInt(b
), 1, 10);
1832 x
= numslots
= obj1
->size
;
1836 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1837 for (i
=0,k
=0; i
<numslots
; ++i
) {
1838 for (j
=0; j
<=i
; ++j
, ++k
) {
1839 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1846 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1847 for (i
=0,k
=0; i
<numslots
; ++i
) {
1848 for (j
=numslots
-1-i
; j
<=numslots
-1; ++j
, ++k
) {
1849 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1856 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1857 for (i
=0,k
=0; i
<numslots
; ++i
) {
1858 for (j
=0; j
<=numslots
-1-i
; ++j
, ++k
) {
1859 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1866 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1867 for (i
=0,k
=0; i
<numslots
; ++i
) {
1868 for (j
=i
; j
<=numslots
-1; ++j
, ++k
) {
1869 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1876 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1877 for (i
=0,k
=0; i
<numslots
; ++i
) {
1878 for (j
=0; j
<=i
; ++j
, ++k
) {
1879 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1882 for (i
=0; i
<numslots
-1; ++i
) {
1883 for (j
=0; j
<=numslots
-2-i
; ++j
, ++k
) {
1884 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1891 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1892 for (i
=0,k
=0; i
<numslots
; ++i
) {
1893 for (j
=numslots
-1-i
; j
<=numslots
-1; ++j
, ++k
) {
1894 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1897 for (i
=0; i
<numslots
-1; ++i
) {
1898 for (j
=i
+1; j
<=numslots
-1; ++j
, ++k
) {
1899 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1906 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1907 for (i
=0,k
=0; i
<numslots
; ++i
) {
1908 for (j
=0; j
<=numslots
-1-i
; ++j
, ++k
) {
1909 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1912 for (i
=1; i
<numslots
; ++i
) {
1913 for (j
=0; j
<=i
; ++j
, ++k
) {
1914 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1921 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1922 for (i
=0,k
=0; i
<numslots
; ++i
) {
1923 for (j
=i
; j
<=numslots
-1; ++j
, ++k
) {
1924 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1927 for (i
=1; i
<numslots
; ++i
) {
1928 for (j
=numslots
-1-i
; j
<=numslots
-1; ++j
, ++k
) {
1929 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1936 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1937 for (i
=0,k
=0; i
<numslots
; ++i
) {
1938 for (j
=0; j
<=i
; ++j
, ++k
) {
1939 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1942 for (i
=0; i
<numslots
-1; ++i
) {
1943 for (j
=i
+1; j
<=numslots
-1; ++j
, ++k
) {
1944 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1951 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1952 for (i
=0,k
=0; i
<numslots
; ++i
) {
1953 for (j
=numslots
-1-i
; j
<=numslots
-1; ++j
, ++k
) {
1954 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1957 for (i
=0; i
<numslots
-1; ++i
) {
1958 for (j
=0; j
<=numslots
-2-i
; ++j
, ++k
) {
1959 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1969 int prArraySlide(struct VMGlobals
*g
, int numArgsPushed
)
1971 PyrSlot
*a
, *b
, *c
, *slots
;
1972 PyrObject
*obj1
, *obj2
;
1973 int h
, i
, j
, k
, n
, m
, numslots
, numwin
;
1978 if (NotInt(b
)) return errWrongType
;
1979 if (NotInt(c
)) return errWrongType
;
1981 obj1
= slotRawObject(a
);
1982 slots
= obj1
->slots
;
1985 numwin
= (obj1
->size
+ n
- m
) / n
;
1986 numslots
= numwin
* m
;
1987 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, numslots
, false, true);
1988 for (i
=h
=k
=0; i
<numwin
; ++i
,h
+=n
) {
1989 for (j
=h
; j
<m
+h
; ++j
) {
1990 slotCopy(&obj2
->slots
[k
++],&slots
[j
]);
1998 int prArrayLace(struct VMGlobals
*g
, int numArgsPushed
)
2000 PyrSlot
*a
, *b
, *slots
, *slot
;
2001 PyrObject
*obj1
, *obj2
, *obj3
;
2002 int i
, j
, k
, n
, m
, numLists
, len
;
2006 obj1
= slotRawObject(a
);
2007 slots
= obj1
->slots
;
2008 numLists
= obj1
->size
;
2011 for (j
=0; j
<numLists
; ++j
) {
2013 if(isKindOfSlot(slot
, class_array
)) {
2014 len
= slotRawObject(slot
)->size
;
2015 if(j
==0 || n
>len
) { n
= len
; }
2017 return errFailed
; // this primitive only handles Arrays.
2022 } else if (IsInt(b
)) {
2025 return errWrongType
;
2030 if(obj1
->size
> 0) {
2031 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
2032 for (i
=j
=k
=0; i
<n
; ++i
) {
2033 if (IsObj(&slots
[k
])) {
2034 obj3
= slotRawObject(&slots
[k
]);
2035 if (isKindOf(obj3
, class_list
)) {
2036 obj3
= slotRawObject(&obj3
->slots
[0]); // get the list's array
2038 if (obj3
&& isKindOf(obj3
, class_array
)) {
2040 slotCopy(&obj2
->slots
[i
],&obj3
->slots
[m
]);
2042 slotCopy(&obj2
->slots
[i
],&slots
[k
]);
2045 slotCopy(&obj2
->slots
[i
],&slots
[k
]);
2047 k
= (k
+1) % obj1
->size
;
2051 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, true, true);
2058 int prArrayContainsSeqColl(struct VMGlobals
*g
, int numArgsPushed
)
2060 PyrSlot
*a
, *slot
, *endptr
;
2065 obj
= slotRawObject(a
);
2067 slot
= obj
->slots
- 1;
2068 endptr
= slot
+ size
;
2069 while (slot
< endptr
) {
2072 if (isKindOf(slotRawObject(slot
), class_sequenceable_collection
)) {
2082 int prArrayNormalizeSum(struct VMGlobals
*g
, int numArgsPushed
)
2084 PyrSlot
*a
, *slots2
;
2085 PyrObject
*obj1
, *obj2
;
2087 double w
, sum
, rsum
;
2090 obj1
= slotRawObject(a
);
2092 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
2093 slots2
= obj2
->slots
;
2095 for (i
=0; i
<size
; ++i
) {
2096 err
= getIndexedDouble(obj1
, i
, &w
);
2097 if (err
) return err
;
2099 SetFloat(&slots2
[i
], w
);
2102 for (i
=0; i
<size
; ++i
) {
2103 double d
= slotRawFloat(&slots2
[i
]);
2104 SetRaw(&slots2
[i
], d
* rsum
);
2114 int prArrayWIndex(struct VMGlobals
*g
, int numArgsPushed
)
2118 int i
, j
, size
, err
;
2124 r
= g
->rgen
->frand();
2125 obj
= slotRawObject(a
);
2129 for (i
=0; i
<size
; ++i
) {
2130 err
= getIndexedDouble(obj
, i
, &w
);
2131 if (err
) return err
;
2161 int prArrayEnvAt(struct VMGlobals
*g
, int numArgsPushed
)
2163 PyrSlot
*a
= g
->sp
- 1;
2166 PyrObject
* env
= slotRawObject(a
);
2167 PyrSlot
* slots
= env
->slots
;
2169 // Env:asArray always gives at least 8 array elements
2170 if(env
->size
< 8) return errFailed
;
2173 int err
= slotDoubleVal(b
, &time
);
2174 if (err
) return err
;
2177 err
= slotDoubleVal(slots
+ kEnv_initLevel
, &begLevel
);
2178 if (err
) return err
;
2181 err
= slotIntVal(slots
+ kEnv_numStages
, &numStages
);
2182 if (err
) return err
;
2184 double begTime
= 0.;
2185 double endTime
= 0.;
2187 for (int i
=0; i
<numStages
; ++i
) {
2188 double dur
, endLevel
;
2192 err
= slotDoubleVal(slots
+ 0, &endLevel
);
2193 if (err
) return err
;
2194 err
= slotDoubleVal(slots
+ 1, &dur
);
2195 if (err
) return err
;
2199 //post("%d %g %g %g %g %g\n", i, time, begTime, endTime, dur, endLevel);
2201 if (time
< endTime
) {
2205 err
= slotIntVal(slots
+ 2, &shape
);
2206 if (err
) return err
;
2209 double pos
= (time
- begTime
) / dur
;
2211 //post(" shape %d pos %g\n", shape, pos);
2219 level
= pos
* (endLevel
- begLevel
) + begLevel
;
2221 case shape_Exponential
:
2222 level
= begLevel
* pow(endLevel
/ begLevel
, pos
);
2225 level
= begLevel
+ (endLevel
- begLevel
) * (-cos(pi
* pos
) * 0.5 + 0.5);
2229 if (begLevel
< endLevel
)
2230 level
= begLevel
+ (endLevel
- begLevel
) * sin(pi2
* pos
);
2232 level
= endLevel
- (endLevel
- begLevel
) * sin(pi2
- pi2
* pos
);
2236 err
= slotDoubleVal(slots
+ 3, &curve
);
2237 if (err
) return err
;
2239 if (fabs(curve
) < 0.0001) {
2240 level
= pos
* (endLevel
- begLevel
) + begLevel
;
2242 double denom
= 1. - exp(curve
);
2243 double numer
= 1. - exp(pos
* curve
);
2244 level
= begLevel
+ (endLevel
- begLevel
) * (numer
/denom
);
2247 case shape_Squared
:
2249 double sqrtBegLevel
= sqrt(begLevel
);
2250 double sqrtEndLevel
= sqrt(endLevel
);
2251 double sqrtLevel
= pos
* (sqrtEndLevel
- sqrtBegLevel
) + sqrtBegLevel
;
2252 level
= sqrtLevel
* sqrtLevel
;
2257 double cbrtBegLevel
= pow(begLevel
, 0.3333333);
2258 double cbrtEndLevel
= pow(endLevel
, 0.3333333);
2259 double cbrtLevel
= pos
* (cbrtEndLevel
- cbrtBegLevel
) + cbrtBegLevel
;
2260 level
= cbrtLevel
* cbrtLevel
* cbrtLevel
;
2269 begLevel
= endLevel
;
2272 SetFloat(a
, begLevel
);
2278 int prArrayIndexOfGreaterThan(struct VMGlobals
*g
, int numArgsPushed
)
2280 PyrSlot
*a
, *b
, *slots
;
2288 obj
= slotRawObject(a
);
2293 err
= slotDoubleVal(b
, &s
);
2294 if (err
) return err
;
2296 for (i
=0; i
<size
; ++i
) {
2297 err
= getIndexedDouble(obj
, i
, &w
);
2298 if (err
) return err
;
2312 int prArrayUnlace(struct VMGlobals
*g
, int numArgsPushed
)
2314 PyrSlot
*a
, *b
, *c
, *slots
, *slots2
, *slots3
;
2315 PyrObject
*obj1
, *obj2
, *obj3
;
2316 int i
, j
, k
, clump
, numLists
, size
, size3
, err
;
2322 obj1
= slotRawObject(a
);
2323 slots
= obj1
->slots
;
2326 err
= slotIntVal(b
, &numLists
);
2327 if (err
) return err
;
2329 err
= slotIntVal(c
, &clump
);
2330 if (err
) return err
;
2332 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, numLists
, false, true);
2333 obj2
->size
= numLists
;
2334 slots2
= obj2
->slots
;
2336 SetObject(b
, obj2
); // store reference on stack, so both source and destination objects can be reached by the gc
2338 size3
= size
/ numLists
;
2339 size3
= size3
- (size3
% clump
);
2340 if(size3
< 1) return errFailed
;
2342 for(i
=0; i
<numLists
; ++i
) {
2343 obj3
= instantiateObject(g
->gc
, obj1
->classptr
, size3
, false, true);
2345 slots3
= obj3
->slots
;
2346 for(j
=0; j
<size3
; j
+=clump
) {
2347 for(k
=0; k
<clump
; ++k
) {
2348 slotCopy(&slots3
[j
+k
],&slots
[i
*clump
+ k
+ j
*numLists
]);
2351 SetObject(slots2
+ i
, obj3
);
2359 void initArrayPrimitives();
2360 void initArrayPrimitives()
2364 base
= nextPrimitiveIndex();
2367 definePrimitive(base
, index
++, "_BasicSize", basicSize
, 1, 0);
2368 definePrimitive(base
, index
++, "_BasicMaxSize", basicMaxSize
, 1, 0);
2370 definePrimitive(base
, index
++, "_BasicSwap", basicSwap
, 3, 0);
2371 definePrimitive(base
, index
++, "_BasicAt", basicAt
, 2, 0);
2372 definePrimitive(base
, index
++, "_BasicRemoveAt", basicRemoveAt
, 2, 0);
2373 definePrimitive(base
, index
++, "_BasicTakeAt", basicTakeAt
, 2, 0);
2374 definePrimitive(base
, index
++, "_BasicClipAt", basicClipAt
, 2, 0);
2375 definePrimitive(base
, index
++, "_BasicWrapAt", basicWrapAt
, 2, 0);
2376 definePrimitive(base
, index
++, "_BasicFoldAt", basicFoldAt
, 2, 0);
2377 definePrimitive(base
, index
++, "_BasicPut", basicPut
, 3, 0);
2378 definePrimitive(base
, index
++, "_BasicClipPut", basicClipPut
, 3, 0);
2379 definePrimitive(base
, index
++, "_BasicWrapPut", basicWrapPut
, 3, 0);
2380 definePrimitive(base
, index
++, "_BasicFoldPut", basicFoldPut
, 3, 0);
2382 definePrimitive(base
, index
++, "_ArrayExtend", prArrayExtend
, 3, 0);
2383 definePrimitive(base
, index
++, "_ArrayGrow", prArrayGrow
, 2, 0);
2384 definePrimitive(base
, index
++, "_ArrayGrowClear", prArrayGrowClear
, 2, 0);
2385 definePrimitive(base
, index
++, "_ArrayAdd", prArrayAdd
, 2, 0);
2386 definePrimitive(base
, index
++, "_ArrayInsert", prArrayInsert
, 3, 0);
2387 definePrimitive(base
, index
++, "_ArrayFill", prArrayFill
, 2, 0);
2388 definePrimitive(base
, index
++, "_ArrayPop", prArrayPop
, 1, 0);
2389 definePrimitive(base
, index
++, "_ArrayCat", prArrayCat
, 2, 0);
2390 definePrimitive(base
, index
++, "_ArrayPutEach", prArrayPutEach
, 3, 0);
2391 definePrimitive(base
, index
++, "_ArrayAddAll", prArrayAddAll
, 2, 0);
2392 definePrimitive(base
, index
++, "_ArrayPutSeries", prArrayPutSeries
, 5, 0);
2393 definePrimitive(base
, index
++, "_ArrayOverwrite", prArrayOverwrite
, 3, 0);
2394 definePrimitive(base
, index
++, "_ArrayIndexOf", prArrayIndexOf
, 2, 0);
2396 definePrimitive(base
, index
++, "_ArrayNormalizeSum", prArrayNormalizeSum
, 1, 0);
2397 definePrimitive(base
, index
++, "_ArrayWIndex", prArrayWIndex
, 1, 0);
2398 definePrimitive(base
, index
++, "_ArrayReverse", prArrayReverse
, 1, 0);
2399 definePrimitive(base
, index
++, "_ArrayScramble", prArrayScramble
, 1, 0);
2400 definePrimitive(base
, index
++, "_ArrayMirror", prArrayMirror
, 1, 0);
2401 definePrimitive(base
, index
++, "_ArrayMirror1", prArrayMirror1
, 1, 0);
2402 definePrimitive(base
, index
++, "_ArrayMirror2", prArrayMirror2
, 1, 0);
2403 definePrimitive(base
, index
++, "_ArrayRotate", prArrayRotate
, 2, 0);
2404 definePrimitive(base
, index
++, "_ArrayPermute", prArrayPermute
, 2, 0);
2405 definePrimitive(base
, index
++, "_ArrayAllTuples", prArrayAllTuples
, 2, 0);
2406 definePrimitive(base
, index
++, "_ArrayPyramid", prArrayPyramid
, 2, 0);
2407 definePrimitive(base
, index
++, "_ArrayRotate", prArrayRotate
, 2, 0);
2408 definePrimitive(base
, index
++, "_ArrayExtendWrap", prArrayExtendWrap
, 2, 0);
2409 definePrimitive(base
, index
++, "_ArrayExtendFold", prArrayExtendFold
, 2, 0);
2410 definePrimitive(base
, index
++, "_ArrayExtendLast", prArrayExtendLast
, 2, 0);
2411 definePrimitive(base
, index
++, "_ArrayLace", prArrayLace
, 2, 0);
2412 definePrimitive(base
, index
++, "_ArrayStutter", prArrayStutter
, 2, 0);
2413 definePrimitive(base
, index
++, "_ArraySlide", prArraySlide
, 3, 0);
2414 definePrimitive(base
, index
++, "_ArrayContainsSeqColl", prArrayContainsSeqColl
, 1, 0);
2416 definePrimitive(base
, index
++, "_ArrayEnvAt", prArrayEnvAt
, 2, 0);
2417 definePrimitive(base
, index
++, "_ArrayIndexOfGreaterThan", prArrayIndexOfGreaterThan
, 2, 0);
2418 definePrimitive(base
, index
++, "_ArrayUnlace", prArrayUnlace
, 3, 0);
2425 #include "SCPlugin.h"
2428 extern "C" { SCPlugIn
* loadPlugIn(void); }
2432 // define plug in object
2433 class APlugIn
: public SCPlugIn
2439 virtual void AboutToCompile();
2444 // constructor for plug in
2449 // destructor for plug in
2452 void APlugIn::AboutToCompile()
2454 // this is called each time the class library is compiled.
2455 initArrayPrimitives();
2458 // This function is called when the plug in is loaded into SC.
2459 // It returns an instance of APlugIn.
2460 SCPlugIn
* loadPlugIn()
2462 return new APlugIn();