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
->IsImmutable()) 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
->IsImmutable()) 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
->IsImmutable()) 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 (obj
->IsImmutable()) return errImmutableObject
;
457 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
458 return errNotAnIndexableObject
;
460 if (NotObj(a
)) return errWrongType
;
461 int err
= slotIntVal(b
, &index
);
464 if (index
< 0 || index
>= obj
->size
) return errIndexOutOfRange
;
465 return putIndexedSlot(g
, obj
, c
, index
);
466 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
467 PyrObject
*indexArray
= slotRawObject(b
);
468 int size
= slotRawObject(b
)->size
;
470 for (int i
=0; i
<size
; ++i
) {
472 int err
= getIndexedInt(indexArray
, i
, &index
);
474 if (index
< 0 || index
>= obj
->size
) return errIndexOutOfRange
;
475 err
= putIndexedSlot(g
, obj
, c
, index
);
479 } else return errIndexNotAnInteger
;
482 int basicClipPut(struct VMGlobals
*g
, int numArgsPushed
)
492 obj
= slotRawObject(a
);
493 if (obj
->IsImmutable()) return errImmutableObject
;
494 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
495 return errNotAnIndexableObject
;
497 if (NotObj(a
)) return errWrongType
;
498 int err
= slotIntVal(b
, &index
);
501 index
= sc_clip(index
, 0, obj
->size
- 1);
502 return putIndexedSlot(g
, obj
, c
, index
);
503 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
504 PyrObject
*indexArray
= slotRawObject(b
);
505 int size
= slotRawObject(b
)->size
;
507 for (int i
=0; i
<size
; ++i
) {
509 int err
= getIndexedInt(indexArray
, i
, &index
);
511 index
= sc_clip(index
, 0, obj
->size
- 1);
512 err
= putIndexedSlot(g
, obj
, c
, index
);
516 } else return errIndexNotAnInteger
;
519 int basicWrapPut(struct VMGlobals
*g
, int numArgsPushed
)
529 obj
= slotRawObject(a
);
530 if (obj
->IsImmutable()) return errImmutableObject
;
531 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
532 return errNotAnIndexableObject
;
534 if (NotObj(a
)) return errWrongType
;
535 int err
= slotIntVal(b
, &index
);
538 index
= sc_mod((int)index
, (int)obj
->size
);
539 return putIndexedSlot(g
, obj
, c
, index
);
540 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
541 PyrObject
*indexArray
= slotRawObject(b
);
542 int size
= slotRawObject(b
)->size
;
544 for (int i
=0; i
<size
; ++i
) {
546 int err
= getIndexedInt(indexArray
, i
, &index
);
548 index
= sc_mod((int)index
, (int)obj
->size
);
549 err
= putIndexedSlot(g
, obj
, c
, index
);
553 } else return errIndexNotAnInteger
;
556 int basicFoldPut(struct VMGlobals
*g
, int numArgsPushed
)
566 obj
= slotRawObject(a
);
567 if (obj
->IsImmutable()) return errImmutableObject
;
568 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
569 return errNotAnIndexableObject
;
571 if (NotObj(a
)) return errWrongType
;
572 int err
= slotIntVal(b
, &index
);
575 index
= sc_fold(index
, 0, obj
->size
-1);
576 return putIndexedSlot(g
, obj
, c
, index
);
577 } else if (isKindOfSlot(b
, class_arrayed_collection
)) {
578 PyrObject
*indexArray
= slotRawObject(b
);
579 int size
= slotRawObject(b
)->size
;
581 for (int i
=0; i
<size
; ++i
) {
583 int err
= getIndexedInt(indexArray
, i
, &index
);
585 index
= sc_fold(index
, 0, obj
->size
-1);
586 err
= putIndexedSlot(g
, obj
, c
, index
);
590 } else return errIndexNotAnInteger
;
593 int prArrayPutEach(struct VMGlobals
*g
, int numArgsPushed
)
602 obj
= slotRawObject(a
);
603 if (obj
->IsImmutable()) return errImmutableObject
;
604 if (!(slotRawInt(&obj
->classptr
->classFlags
) & classHasIndexableInstances
))
605 return errNotAnIndexableObject
;
607 if (!isKindOfSlot(b
, class_arrayed_collection
)) return errWrongType
;
608 if (!isKindOfSlot(c
, class_arrayed_collection
)) return errWrongType
;
610 PyrSlot
*indices
= slotRawObject(b
)->slots
;
611 PyrSlot
*values
= slotRawObject(c
)->slots
;
612 int size
= slotRawObject(b
)->size
;
613 int valsize
= slotRawObject(c
)->size
;
615 for (int i
=0; i
<size
; ++i
) {
617 int err
= slotIntVal(indices
+ i
, &index
);
619 if (index
< 0 || index
>= obj
->size
) return errIndexOutOfRange
;
620 int valindex
= sc_mod(i
, valsize
);
621 err
= putIndexedSlot(g
, obj
, values
+ valindex
, index
);
629 int prArrayAssocAt(struct VMGlobals
*g
, int numArgsPushed
)
638 obj
= slotRawObject(a
);
640 int size
= obj
->size
;
641 if (obj
->obj_format
== obj_slot
) {
642 PyrSlot
*slots
= obj
->slots
;
643 for (int i
=0; i
<size
; i
+=2) {
644 if (SlotEq(slots
+i
, b
)) {
645 if (i
+1 >= size
) return errFailed
;
646 slotCopy(a
,&slots
[i
+1]);
653 for (int i
=0; i
<size
; i
+=2) {
654 getIndexedSlot(obj
, &slot
, i
);
655 if (SlotEq(&slot
, b
)) {
656 if (i
+1 >= size
) return errFailed
;
657 getIndexedSlot(obj
, &slot
, i
+1);
664 if (!found
) SetNil(a
);
670 int prArrayAssocPut(struct VMGlobals
*g
, int numArgsPushed
)
680 obj
= slotRawObject(a
);
681 if (obj
->IsImmutable()) return errImmutableObject
;
683 int size
= obj
->size
;
684 if (obj
->obj_format
== obj_slot
) {
685 PyrSlot
*slots
= obj
->slots
;
686 for (int i
=0; i
<size
; i
+=2) {
687 if (SlotEq(slots
+i
, b
)) {
688 if (i
+1 >= size
) return errFailed
;
689 slotCopy(&slots
[i
+1],c
);
690 g
->gc
->GCWrite(obj
, c
);
697 for (int i
=0; i
<size
; i
+=2) {
698 getIndexedSlot(obj
, &slot
, i
);
699 if (SlotEq(&slot
, b
)) {
700 if (i
+1 >= size
) return errFailed
;
701 putIndexedSlot(g
, obj
, &slot
, i
+1);
702 g
->gc
->GCWrite(obj
, c
);
708 if (!found
) SetNil(a
);
713 int prArrayIndexOf(struct VMGlobals
*g
, int numArgsPushed
)
722 obj
= slotRawObject(a
);
724 int size
= obj
->size
;
725 if (obj
->obj_format
== obj_slot
) {
726 PyrSlot
*slots
= obj
->slots
;
727 for (int i
=0; i
<size
; ++i
) {
728 if (SlotEq(slots
+i
, b
)) {
736 for (int i
=0; i
<size
; ++i
) {
737 getIndexedSlot(obj
, &slot
, i
);
738 if (SlotEq(&slot
, b
)) {
745 if (!found
) SetNil(a
);
751 int prArrayPutSeries(struct VMGlobals
*g
, int numArgsPushed
)
753 PyrSlot
*a
, *b
, *c
, *d
, *e
;
761 PyrObject
*inobj
= slotRawObject(a
);
762 if (inobj
->IsImmutable()) return errImmutableObject
;
764 int size
= inobj
->size
;
766 if (NotInt(b
) && NotNil(b
)) return errWrongType
;
767 if (NotInt(c
) && NotNil(c
)) return errWrongType
;
768 if (NotInt(d
) && NotNil(d
)) return errWrongType
;
770 int first
= IsInt(b
) ? slotRawInt(b
) : 0;
771 int last
= IsInt(d
) ? slotRawInt(d
) : size
- 1;
772 int second
= IsInt(c
) ? slotRawInt(c
) : (first
< last
? first
+ 1 : first
- 1);
774 int step
= second
- first
;
776 first
= sc_clip(first
, 0, size
-1);
777 last
= sc_clip(last
, 0, size
-1);
781 if (step
== 0) return errFailed
;
783 for (int i
=first
; i
<=last
; ++i
) {
784 err
= putIndexedSlot(g
, inobj
, e
, i
);
787 } else if (step
== -1) {
788 for (int i
=last
; i
>=first
; --i
) {
789 err
= putIndexedSlot(g
, inobj
, e
, i
);
792 } else if (step
> 0) {
793 int length
= (last
- first
) / step
+ 1;
795 for (int i
=first
, j
=0; j
<length
; i
+=step
, ++j
) {
796 err
= putIndexedSlot(g
, inobj
, e
, i
);
799 } else if (step
< 0) {
800 int length
= (first
- last
) / -step
+ 1;
802 for (int i
=first
, j
=0; j
<length
; i
+=step
, ++j
) {
803 err
= putIndexedSlot(g
, inobj
, e
, i
);
811 int prArrayAdd(struct VMGlobals
*g
, int numArgsPushed
)
813 PyrSlot
*a
, *b
, *slots
;
814 int maxelems
, elemsize
, format
, tag
, numbytes
;
821 PyrObject
*array
= slotRawObject(a
);
822 if (array
->IsImmutable()) return errImmutableObject
;
824 format
= slotRawObject(a
)->obj_format
;
825 tag
= gFormatElemTag
[format
];
827 if (GetTag(b) != tag) return errWrongType;
828 } else if (tag == 0) {
829 if (NotFloat(b)) return errWrongType;
830 } // else format is obj_slot, any tag is acceptable*/
831 elemsize
= gFormatElemSize
[format
];
832 maxelems
= MAXINDEXSIZE(array
);
833 if (array
->size
>= maxelems
|| array
->IsImmutable()) {
834 numbytes
= sizeof(PyrSlot
) << (array
->obj_sizeclass
+ 1);
835 array
= g
->gc
->New(numbytes
, 0, format
, true);
836 array
->classptr
= slotRawObject(a
)->classptr
;
837 array
->size
= slotRawObject(a
)->size
;
838 memcpy(array
->slots
, slotRawObject(a
)->slots
, slotRawObject(a
)->size
* elemsize
);
841 slots
= array
->slots
;
844 slotCopy(&slots
[array
->size
++],b
);
845 g
->gc
->GCWrite(array
, b
);
848 err
= slotIntVal(b
, &ival
);
850 ((int32
*)slots
)[array
->size
++] = ival
;
853 err
= slotIntVal(b
, &ival
);
855 ((int16
*)slots
)[array
->size
++] = ival
;
858 err
= slotIntVal(b
, &ival
);
860 ((int8
*)slots
)[array
->size
++] = ival
;
863 if (NotChar(b
)) return errWrongType
;
864 ((char*)slots
)[array
->size
++] = slotRawChar(b
);
867 if (NotSym(b
)) return errWrongType
;
868 ((PyrSymbol
**)slots
)[array
->size
++] = slotRawSymbol(b
);
871 err
= slotDoubleVal(b
, &fval
);
873 ((float*)slots
)[array
->size
++] = fval
;
876 err
= slotDoubleVal(b
, &fval
);
878 ((double*)slots
)[array
->size
++] = fval
;
884 int prArrayInsert(struct VMGlobals
*g
, int numArgsPushed
)
886 PyrSlot
*a
, *b
, *c
, *slots1
, *slots2
;
887 PyrObject
*array
, *oldarray
;
891 a
= g
->sp
- 2; // array
892 b
= g
->sp
- 1; // index
894 if (NotInt(b
)) return errWrongType
;
896 array
= slotRawObject(a
);
897 const int format
= slotRawObject(a
)->obj_format
;
898 const int tag
= gFormatElemTag
[format
];
900 const int size
= array
->size
;
901 int index
= slotRawInt(b
);
902 index
= sc_clip(index
, 0, size
);
903 const int remain
= size
- index
;
905 const int elemsize
= gFormatElemSize
[format
];
906 const int maxelems
= MAXINDEXSIZE(array
);
907 if (size
+1 > maxelems
|| array
->IsImmutable()) {
910 const int numbytes
= sizeof(PyrSlot
) << (array
->obj_sizeclass
+ 1);
911 array
= g
->gc
->New(numbytes
, 0, format
, true);
913 array
->classptr
= oldarray
->classptr
;
915 array
->size
= size
+1;
917 slots1
= array
->slots
;
918 slots2
= oldarray
->slots
;
920 memcpy(slots1
, slots2
, index
* elemsize
);
925 slotCopy(&slots1
[index
],c
);
926 if (remain
) memcpy(slots1
+ index
+ 1, slots2
+ index
, remain
* elemsize
);
927 if (!g
->gc
->ObjIsGrey(array
)) g
->gc
->ToGrey(array
);
930 err
= slotIntVal(c
, &ival
);
932 ((int32
*)slots1
)[index
] = ival
;
934 memcpy((int*)slots1
+ index
+ 1, (int*)slots2
+ index
,
939 err
= slotIntVal(c
, &ival
);
941 ((int16
*)slots1
)[index
] = ival
;
943 memcpy((short*)slots1
+ index
+ 1, (short*)slots2
+ index
,
948 err
= slotIntVal(c
, &ival
);
950 ((int8
*)slots1
)[index
] = ival
;
952 memcpy((char*)slots1
+ index
+ 1, (char*)slots2
+ index
,
957 if (NotChar(c
)) return errWrongType
;
958 ((char*)slots1
)[index
] = slotRawInt(c
);
960 memcpy((char*)slots1
+ index
+ 1, (char*)slots2
+ index
,
965 if (NotSym(c
)) return errWrongType
;
966 ((PyrSymbol
**)slots1
)[index
] = slotRawSymbol(c
);
968 memcpy((int*)slots1
+ index
+ 1, (int*)slots2
+ index
,
973 err
= slotDoubleVal(c
, &fval
);
975 ((float*)slots1
)[index
] = fval
;
977 memcpy((float*)slots1
+ index
+ 1, (float*)slots2
+ index
,
982 err
= slotDoubleVal(c
, &fval
);
984 ((double*)slots1
)[index
] = fval
;
986 memcpy((double*)slots1
+ index
+ 1, (double*)slots2
+ index
,
992 array
->size
= size
+1;
993 slots1
= array
->slots
;
996 if (remain
) memmove(slots1
+ index
+ 1, slots1
+ index
, remain
* elemsize
);
997 slotCopy(&slots1
[index
],c
);
998 if (!g
->gc
->ObjIsGrey(array
)) g
->gc
->ToGrey(array
);
1002 memmove((int*)slots1
+ index
+ 1, (int*)slots1
+ index
,
1005 err
= slotIntVal(c
, &ival
);
1006 if (err
) return err
;
1007 ((int32
*)slots1
)[index
] = ival
;
1011 memmove((short*)slots1
+ index
+ 1, (short*)slots1
+ index
,
1014 err
= slotIntVal(c
, &ival
);
1015 if (err
) return err
;
1016 ((int16
*)slots1
)[index
] = ival
;
1020 memmove((char*)slots1
+ index
+ 1, (char*)slots1
+ index
,
1023 err
= slotIntVal(c
, &ival
);
1024 if (err
) return err
;
1025 ((int8
*)slots1
)[index
] = ival
;
1029 memmove((char*)slots1
+ index
+ 1, (char*)slots1
+ index
,
1032 if (NotChar(c
)) return errWrongType
;
1033 ((char*)slots1
)[index
] = slotRawInt(c
);
1037 memmove((int*)slots1
+ index
+ 1, (int*)slots1
+ index
,
1040 if (NotSym(c
)) return errWrongType
;
1041 ((PyrSymbol
**)slots1
)[index
] = slotRawSymbol(c
);
1045 memmove((float*)slots1
+ index
+ 1, (float*)slots1
+ index
,
1048 err
= slotDoubleVal(c
, &fval
);
1049 if (err
) return err
;
1050 ((float*)slots1
)[index
] = fval
;
1054 memmove((double*)slots1
+ index
+ 1, (double*)slots1
+ index
,
1057 err
= slotDoubleVal(c
, &fval
);
1058 if (err
) return err
;
1059 ((double*)slots1
)[index
] = fval
;
1067 int prArrayFill(struct VMGlobals
*g
, int numArgsPushed
)
1069 PyrSlot
*a
, *b
, *slots
;
1081 array
= slotRawObject(a
);
1082 format
= slotRawObject(a
)->obj_format
;
1083 tag
= gFormatElemTag
[format
];
1085 if (GetTag(b) != tag) return errWrongType;
1086 } else if (tag == 0) {
1087 if (NotFloat(b)) return errWrongType;
1088 } // else format is obj_slot, any tag is acceptable*/
1089 slots
= array
->slots
;
1092 if (array
->IsImmutable()) return errImmutableObject
;
1093 for (i
=0; i
<array
->size
; ++i
) {
1094 slotCopy(&slots
[i
],b
);
1096 g
->gc
->GCWrite(array
, b
);
1099 err
= slotIntVal(b
, &ival
);
1100 if (err
) return err
;
1101 for (i
=0; i
<array
->size
; ++i
) {
1102 ((int32
*)slots
)[i
] = ival
;
1106 err
= slotIntVal(b
, &ival
);
1107 if (err
) return err
;
1108 for (i
=0; i
<array
->size
; ++i
) {
1109 ((int16
*)slots
)[i
] = ival
;
1113 err
= slotIntVal(b
, &ival
);
1114 if (err
) return err
;
1115 for (i
=0; i
<array
->size
; ++i
) {
1116 ((int8
*)slots
)[i
] = ival
;
1120 if (NotChar(b
)) return errWrongType
;
1121 ival
= slotRawInt(b
);
1122 for (i
=0; i
<array
->size
; ++i
) {
1123 ((char*)slots
)[i
] = ival
;
1127 if (NotSym(b
)) return errWrongType
;
1128 sym
= slotRawSymbol(b
);
1129 for (i
=0; i
<array
->size
; ++i
) {
1130 ((PyrSymbol
**)slots
)[i
] = sym
;
1134 err
= slotDoubleVal(b
, &fval
);
1135 if (err
) return err
;
1136 for (i
=0; i
<array
->size
; ++i
) {
1137 ((float*)slots
)[i
] = fval
;
1141 err
= slotDoubleVal(b
, &fval
);
1142 if (err
) return err
;
1143 for (i
=0; i
<array
->size
; ++i
) {
1144 ((double*)slots
)[i
] = fval
;
1151 int prArrayPop(struct VMGlobals
*g
, int numArgsPushed
)
1161 array
= slotRawObject(a
);
1162 if (array
->IsImmutable()) 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
]));
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
) || aobj
->IsImmutable()) {
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
)
1295 PyrObject
*obj
, *aobj
;
1296 int numbytes
, elemsize
, format
;
1301 if (NotInt(b
)) return errWrongType
;
1302 if (slotRawInt(b
) <= 0) return errNone
;
1303 aobj
= slotRawObject(a
);
1305 if (aobj
->size
+ slotRawInt(b
) <= MAXINDEXSIZE(aobj
)) return errNone
;
1307 format
= aobj
->obj_format
;
1308 elemsize
= gFormatElemSize
[format
];
1309 numbytes
= ((aobj
->size
+ slotRawInt(b
)) * elemsize
);
1311 obj
= g
->gc
->New(numbytes
, 0, format
, true);
1312 obj
->classptr
= aobj
->classptr
;
1313 obj
->size
= aobj
->size
;
1314 memcpy(obj
->slots
, aobj
->slots
, aobj
->size
* elemsize
);
1320 int prArrayGrowClear(struct VMGlobals
*g
, int numArgsPushed
)
1323 PyrObject
*obj
, *aobj
;
1324 int numbytes
, elemsize
, format
;
1329 if (NotInt(b
)) return errWrongType
;
1330 if (slotRawInt(b
) <= 0) return errNone
;
1331 aobj
= slotRawObject(a
);
1333 if (aobj
->size
+ slotRawInt(b
) <= MAXINDEXSIZE(aobj
) && aobj
->IsMutable()) {
1336 format
= aobj
->obj_format
;
1337 elemsize
= gFormatElemSize
[format
];
1338 numbytes
= ((aobj
->size
+ slotRawInt(b
)) * elemsize
);
1340 obj
= g
->gc
->New(numbytes
, 0, format
, true);
1341 obj
->classptr
= aobj
->classptr
;
1342 memcpy(obj
->slots
, aobj
->slots
, aobj
->size
* elemsize
);
1345 if (obj
->obj_format
== obj_slot
) {
1346 nilSlots(obj
->slots
+ aobj
->size
, slotRawInt(b
));
1348 memset((char*)(obj
->slots
) + aobj
->size
* gFormatElemSize
[format
],
1349 0, slotRawInt(b
) * gFormatElemSize
[format
]);
1351 obj
->size
= aobj
->size
+ slotRawInt(b
);
1357 int prArrayCat(struct VMGlobals
*g
, int numArgsPushed
)
1360 PyrObject
*obj
, *aobj
, *bobj
;
1362 int numbytes
, format
;
1367 if (NotObj(b
) || slotRawObject(a
)->classptr
!= slotRawObject(b
)->classptr
) return errWrongType
;
1368 aobj
= slotRawObject(a
);
1369 bobj
= slotRawObject(b
);
1370 size
= aobj
->size
+ bobj
->size
;
1371 format
= aobj
->obj_format
;
1372 assert(aobj
->obj_format
== bobj
->obj_format
);
1373 elemsize
= gFormatElemSize
[format
];
1374 numbytes
= (size
* elemsize
);
1376 obj
= g
->gc
->New(numbytes
, 0, format
, true);
1377 obj
->classptr
= aobj
->classptr
;
1379 memcpy(obj
->slots
, aobj
->slots
, aobj
->size
* elemsize
);
1380 memcpy((char*)obj
->slots
+ aobj
->size
* elemsize
,
1381 bobj
->slots
, bobj
->size
* elemsize
);
1388 int prArrayAddAll(struct VMGlobals
*g
, int numArgsPushed
)
1391 PyrObject
*obj
, *aobj
;
1392 int elemsize
, newindexedsize
, newsizebytes
, asize
, bsize
;
1398 if (NotObj(b
) || slotRawObject(a
)->classptr
!= slotRawObject(b
)->classptr
) return errWrongType
;
1399 aobj
= slotRawObject(a
);
1401 format
= aobj
->obj_format
;
1402 elemsize
= gFormatElemSize
[format
];
1404 bsize
= slotRawObject(b
)->size
;
1405 newindexedsize
= asize
+ bsize
;
1406 newsizebytes
= newindexedsize
* elemsize
;
1408 if (newindexedsize
> MAXINDEXSIZE(aobj
) || aobj
->IsImmutable()) {
1409 obj
= g
->gc
->New(newsizebytes
, 0, format
, true);
1410 obj
->classptr
= aobj
->classptr
;
1411 memcpy(obj
->slots
, aobj
->slots
, asize
* elemsize
);
1415 if (format
== obj_slot
&& !g
->gc
->ObjIsGrey(obj
))
1418 obj
->size
= newindexedsize
;
1419 memcpy((char*)obj
->slots
+ asize
* elemsize
, slotRawObject(b
)->slots
, bsize
* elemsize
);
1424 int prArrayOverwrite(struct VMGlobals
*g
, int numArgsPushed
)
1427 PyrObject
*obj
, *aobj
;
1428 int err
, elemsize
, newindexedsize
, newsizebytes
, pos
, asize
, bsize
;
1435 if (NotObj(b
) || slotRawObject(a
)->classptr
!= slotRawObject(b
)->classptr
) return errWrongType
;
1436 err
= slotIntVal(c
, &pos
);
1437 if (err
) return errWrongType
;
1438 if (pos
< 0 || pos
> slotRawObject(a
)->size
) return errIndexOutOfRange
;
1440 aobj
= slotRawObject(a
);
1441 format
= aobj
->obj_format
;
1442 elemsize
= gFormatElemSize
[format
];
1444 bsize
= slotRawObject(b
)->size
;
1445 newindexedsize
= pos
+ bsize
;
1446 newindexedsize
= sc_max(asize
, newindexedsize
);
1447 newsizebytes
= newindexedsize
* elemsize
;
1449 if (newindexedsize
> MAXINDEXSIZE(aobj
) || aobj
->IsImmutable()) {
1450 obj
= g
->gc
->New(newsizebytes
, 0, format
, true);
1451 obj
->classptr
= aobj
->classptr
;
1452 memcpy(obj
->slots
, aobj
->slots
, asize
* elemsize
);
1456 if (format
== obj_slot
&& !g
->gc
->ObjIsGrey(obj
))
1460 obj
->size
= newindexedsize
;
1461 memcpy((char*)(obj
->slots
) + pos
* elemsize
, slotRawObject(b
)->slots
, bsize
* elemsize
);
1466 int prArrayReverse(struct VMGlobals
*g
, int numArgsPushed
)
1468 PyrSlot
*a
, *slots1
, *slots2
;
1469 PyrObject
*obj1
, *obj2
;
1473 obj1
= slotRawObject(a
);
1475 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1476 slots1
= obj1
->slots
;
1477 slots2
= obj2
->slots
;
1478 for (i
=0, j
=size
-1; i
<size
; ++i
,--j
) {
1479 slotCopy(&slots2
[j
],&slots1
[i
]);
1486 int prArrayScramble(struct VMGlobals
*g
, int numArgsPushed
)
1488 PyrSlot
*a
, *slots1
, *slots2
, temp
;
1489 PyrObject
*obj1
, *obj2
;
1490 int i
, j
, k
, m
, size
;
1493 obj1
= slotRawObject(a
);
1495 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1496 slots1
= obj1
->slots
;
1497 slots2
= obj2
->slots
;
1498 memcpy(slots2
, slots1
, size
* sizeof(PyrSlot
));
1501 for (i
=0, m
=k
; i
<k
-1; ++i
, --m
) {
1502 j
= i
+ g
->rgen
->irand(m
);
1503 slotCopy(&temp
,&slots2
[i
]);
1504 slotCopy(&slots2
[i
],&slots2
[j
]);
1505 slotCopy(&slots2
[j
],&temp
);
1513 int prArrayRotate(struct VMGlobals
*g
, int numArgsPushed
)
1515 PyrSlot
*a
, *b
, *slots
;
1516 PyrObject
*obj1
, *obj2
;
1521 if (NotInt(b
)) return errWrongType
;
1523 obj1
= slotRawObject(a
);
1525 n
= sc_mod((int)slotRawInt(b
), (int)size
);
1526 slots
= obj1
->slots
;
1527 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1528 for (i
=0, j
=n
; i
<size
; ++i
) {
1529 slotCopy(&obj2
->slots
[j
],&slots
[i
]);
1530 if (++j
>= size
) j
=0;
1537 int prArrayStutter(struct VMGlobals
*g
, int numArgsPushed
)
1539 PyrSlot
*a
, *b
, *slots1
, *slots2
;
1540 PyrObject
*obj1
, *obj2
;
1541 int i
, j
, k
, m
, n
, size
;
1545 if (NotInt(b
)) return errWrongType
;
1547 obj1
= slotRawObject(a
);
1551 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1552 slots1
= obj1
->slots
;
1553 slots2
= obj2
->slots
;
1554 for (i
=0,j
=0; i
<m
; ++i
) {
1555 for (k
=0; k
<n
; ++k
,++j
) {
1556 slotCopy(&slots2
[j
],&slots1
[i
]);
1564 int prArrayMirror(struct VMGlobals
*g
, int numArgsPushed
)
1567 PyrObject
*obj1
, *obj2
;
1572 obj1
= slotRawObject(a
);
1573 slots
= obj1
->slots
;
1574 size
= obj1
->size
* 2 - 1;
1575 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1577 // copy first part of list
1578 memcpy(obj2
->slots
, slots
, obj1
->size
* sizeof(PyrSlot
));
1581 for (i
=0, j
=size
-1; i
<k
; ++i
,--j
) {
1582 slotCopy(&obj2
->slots
[j
],&slots
[i
]);
1588 int prArrayMirror1(struct VMGlobals
*g
, int numArgsPushed
)
1591 PyrObject
*obj1
, *obj2
;
1596 obj1
= slotRawObject(a
);
1597 slots
= obj1
->slots
;
1598 size
= obj1
->size
* 2 - 2;
1599 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1601 // copy first part of list
1602 memcpy(obj2
->slots
, slots
, obj1
->size
* sizeof(PyrSlot
));
1605 for (i
=1, j
=size
-1; i
<k
; ++i
,--j
) {
1606 slotCopy(&obj2
->slots
[j
],&slots
[i
]);
1612 int prArrayMirror2(struct VMGlobals
*g
, int numArgsPushed
)
1615 PyrObject
*obj1
, *obj2
;
1620 obj1
= slotRawObject(a
);
1621 slots
= obj1
->slots
;
1622 size
= obj1
->size
* 2;
1623 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1625 // copy first part of list
1626 memcpy(obj2
->slots
, slots
, obj1
->size
* sizeof(PyrSlot
));
1629 for (i
=0, j
=size
-1; i
<k
; ++i
,--j
) {
1630 slotCopy(&obj2
->slots
[j
],&slots
[i
]);
1637 int prArrayExtendWrap(struct VMGlobals
*g
, int numArgsPushed
)
1639 PyrSlot
*a
, *b
, *slots
;
1640 PyrObject
*obj1
, *obj2
;
1645 if (NotInt(b
)) return errWrongType
;
1647 size
= slotRawInt(b
);
1651 obj1
= slotRawObject(a
);
1653 if(obj1
->size
> 0) {
1654 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1656 slots
= obj2
->slots
;
1657 // copy first part of list
1658 memcpy(slots
, obj1
->slots
, sc_min(size
, obj1
->size
) * sizeof(PyrSlot
));
1659 if (size
> obj1
->size
) {
1662 for (i
=0,j
=m
; j
<size
; ++i
,++j
) {
1663 slotCopy(&slots
[j
],&slots
[i
]);
1667 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, true, true);
1673 int prArrayExtendFold(struct VMGlobals
*g
, int numArgsPushed
)
1675 PyrSlot
*a
, *b
, *slots
;
1676 PyrObject
*obj1
, *obj2
;
1681 if (NotInt(b
)) return errWrongType
;
1683 size
= slotRawInt(b
);
1687 obj1
= slotRawObject(a
);
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 size
= slotRawInt(b
);
1722 obj1
= slotRawObject(a
);
1723 if(obj1
->size
> 0) {
1724 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1726 slots
= obj2
->slots
;
1727 // copy first part of list
1728 memcpy(slots
, obj1
->slots
, sc_min(size
, obj1
->size
) * sizeof(PyrSlot
));
1729 if (size
> obj1
->size
) {
1732 slotCopy(&last
,&slots
[m
-1]);
1733 for (i
=0,j
=m
; j
<size
; ++i
,++j
)
1734 slotCopy(&slots
[j
],&last
);
1738 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, true, true);
1744 int prArrayPermute(struct VMGlobals
*g
, int numArgsPushed
)
1746 PyrSlot
*a
, *b
, *slots1
, *slots2
, temp
;
1747 PyrObject
*obj1
, *obj2
;
1748 int i
, j
, m
, z
, size
;
1752 if (NotInt(b
)) return errWrongType
;
1754 obj1
= slotRawObject(a
);
1756 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
1758 slots1
= obj1
->slots
;
1759 slots2
= obj2
->slots
;
1760 memcpy(slots2
, slots1
, size
* sizeof(PyrSlot
));
1762 for (i
=0, m
=size
; i
<size
-1; ++i
, --m
) {
1763 j
= i
+ sc_mod((int)z
, (int)(size
-i
));
1764 z
= sc_div(z
,size
-i
);
1765 slotCopy(&temp
,&slots2
[i
]);
1766 slotCopy(&slots2
[i
],&slots2
[j
]);
1767 slotCopy(&slots2
[j
],&temp
);
1774 int prArrayAllTuples(struct VMGlobals
*g
, int numArgsPushed
)
1776 PyrSlot
*a
, *b
, *slots1
, *slots2
, *slots3
;
1777 PyrObject
*obj1
, *obj2
, *obj3
;
1781 if (NotInt(b
)) return errWrongType
;
1782 int maxSize
= slotRawInt(b
);
1784 obj1
= slotRawObject(a
);
1785 slots1
= obj1
->slots
;
1787 int tupSize
= obj1
->size
;
1788 for (int i
=0; i
< tupSize
; ++i
) {
1789 if (isKindOfSlot(slots1
+i
, class_array
)) {
1790 newSize
*= slotRawObject(&slots1
[i
])->size
;
1793 if (newSize
> maxSize
) newSize
= maxSize
;
1795 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, newSize
, false, true);
1796 slots2
= obj2
->slots
;
1797 SetObject(b
, obj2
); // store reference on stack, so both source and destination objects can be reached by the gc
1799 for (int i
=0; i
< newSize
; ++i
) {
1801 obj3
= instantiateObject(g
->gc
, obj1
->classptr
, tupSize
, false, true);
1802 slots3
= obj3
->slots
;
1803 for (int j
=tupSize
-1; j
>= 0; --j
) {
1804 if (isKindOfSlot(slots1
+j
, class_array
)) {
1805 PyrObject
*obj4
= slotRawObject(&slots1
[j
]);
1806 slotCopy(&slots3
[j
], &obj4
->slots
[k
% obj4
->size
]);
1807 g
->gc
->GCWrite(obj3
, obj4
);
1810 slotCopy(&slots3
[j
], &slots1
[j
]);
1813 obj3
->size
= tupSize
;
1814 SetObject(obj2
->slots
+i
, obj3
);
1815 g
->gc
->GCWriteNew(obj2
, obj3
);
1822 int prArrayPyramid(struct VMGlobals
*g
, int numArgsPushed
)
1824 PyrSlot
*a
, *b
, *slots
;
1825 PyrObject
*obj1
, *obj2
;
1826 int i
, j
, k
, n
, m
, numslots
, x
;
1830 if (NotInt(b
)) return errWrongType
;
1832 obj1
= slotRawObject(a
);
1833 slots
= obj1
->slots
;
1834 m
= sc_clip(slotRawInt(b
), 1, 10);
1835 x
= numslots
= obj1
->size
;
1839 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1840 for (i
=0,k
=0; i
<numslots
; ++i
) {
1841 for (j
=0; j
<=i
; ++j
, ++k
) {
1842 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1849 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1850 for (i
=0,k
=0; i
<numslots
; ++i
) {
1851 for (j
=numslots
-1-i
; j
<=numslots
-1; ++j
, ++k
) {
1852 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1859 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1860 for (i
=0,k
=0; i
<numslots
; ++i
) {
1861 for (j
=0; j
<=numslots
-1-i
; ++j
, ++k
) {
1862 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1869 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1870 for (i
=0,k
=0; i
<numslots
; ++i
) {
1871 for (j
=i
; j
<=numslots
-1; ++j
, ++k
) {
1872 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1879 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1880 for (i
=0,k
=0; i
<numslots
; ++i
) {
1881 for (j
=0; j
<=i
; ++j
, ++k
) {
1882 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1885 for (i
=0; i
<numslots
-1; ++i
) {
1886 for (j
=0; j
<=numslots
-2-i
; ++j
, ++k
) {
1887 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1894 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1895 for (i
=0,k
=0; i
<numslots
; ++i
) {
1896 for (j
=numslots
-1-i
; j
<=numslots
-1; ++j
, ++k
) {
1897 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1900 for (i
=0; i
<numslots
-1; ++i
) {
1901 for (j
=i
+1; j
<=numslots
-1; ++j
, ++k
) {
1902 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1909 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1910 for (i
=0,k
=0; i
<numslots
; ++i
) {
1911 for (j
=0; j
<=numslots
-1-i
; ++j
, ++k
) {
1912 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1915 for (i
=1; i
<numslots
; ++i
) {
1916 for (j
=0; j
<=i
; ++j
, ++k
) {
1917 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1924 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1925 for (i
=0,k
=0; i
<numslots
; ++i
) {
1926 for (j
=i
; j
<=numslots
-1; ++j
, ++k
) {
1927 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1930 for (i
=1; i
<numslots
; ++i
) {
1931 for (j
=numslots
-1-i
; j
<=numslots
-1; ++j
, ++k
) {
1932 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1939 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1940 for (i
=0,k
=0; i
<numslots
; ++i
) {
1941 for (j
=0; j
<=i
; ++j
, ++k
) {
1942 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1945 for (i
=0; i
<numslots
-1; ++i
) {
1946 for (j
=i
+1; j
<=numslots
-1; ++j
, ++k
) {
1947 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1954 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
1955 for (i
=0,k
=0; i
<numslots
; ++i
) {
1956 for (j
=numslots
-1-i
; j
<=numslots
-1; ++j
, ++k
) {
1957 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1960 for (i
=0; i
<numslots
-1; ++i
) {
1961 for (j
=0; j
<=numslots
-2-i
; ++j
, ++k
) {
1962 slotCopy(&obj2
->slots
[k
],&slots
[j
]);
1972 int prArraySlide(struct VMGlobals
*g
, int numArgsPushed
)
1974 PyrSlot
*a
, *b
, *c
, *slots
;
1975 PyrObject
*obj1
, *obj2
;
1976 int h
, i
, j
, k
, n
, m
, numslots
, numwin
;
1981 if (NotInt(b
)) return errWrongType
;
1982 if (NotInt(c
)) return errWrongType
;
1984 obj1
= slotRawObject(a
);
1985 slots
= obj1
->slots
;
1988 numwin
= (obj1
->size
+ n
- m
) / n
;
1989 numslots
= numwin
* m
;
1990 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, numslots
, false, true);
1991 for (i
=h
=k
=0; i
<numwin
; ++i
,h
+=n
) {
1992 for (j
=h
; j
<m
+h
; ++j
) {
1993 slotCopy(&obj2
->slots
[k
++],&slots
[j
]);
2001 int prArrayLace(struct VMGlobals
*g
, int numArgsPushed
)
2003 PyrSlot
*a
, *b
, *slots
, *slot
;
2004 PyrObject
*obj1
, *obj2
, *obj3
;
2005 int i
, j
, k
, n
, m
, numLists
, len
;
2009 obj1
= slotRawObject(a
);
2010 slots
= obj1
->slots
;
2011 numLists
= obj1
->size
;
2014 for (j
=0; j
<numLists
; ++j
) {
2016 if(isKindOfSlot(slot
, class_array
)) {
2017 len
= slotRawObject(slot
)->size
;
2018 if(j
==0 || n
>len
) { n
= len
; }
2020 return errFailed
; // this primitive only handles Arrays.
2025 } else if (IsInt(b
)) {
2028 return errWrongType
;
2033 if(obj1
->size
> 0) {
2034 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, false, true);
2035 for (i
=j
=k
=0; i
<n
; ++i
) {
2036 if (IsObj(&slots
[k
])) {
2037 obj3
= slotRawObject(&slots
[k
]);
2038 if (isKindOf(obj3
, class_list
)) {
2039 obj3
= slotRawObject(&obj3
->slots
[0]); // get the list's array
2041 if (obj3
&& isKindOf(obj3
, class_array
)) {
2043 slotCopy(&obj2
->slots
[i
],&obj3
->slots
[m
]);
2045 slotCopy(&obj2
->slots
[i
],&slots
[k
]);
2048 slotCopy(&obj2
->slots
[i
],&slots
[k
]);
2050 k
= (k
+1) % obj1
->size
;
2054 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, n
, true, true);
2061 int prArrayContainsSeqColl(struct VMGlobals
*g
, int numArgsPushed
)
2063 PyrSlot
*a
, *slot
, *endptr
;
2068 obj
= slotRawObject(a
);
2070 slot
= obj
->slots
- 1;
2071 endptr
= slot
+ size
;
2072 while (slot
< endptr
) {
2075 if (isKindOf(slotRawObject(slot
), class_sequenceable_collection
)) {
2085 int prArrayNormalizeSum(struct VMGlobals
*g
, int numArgsPushed
)
2087 PyrSlot
*a
, *slots2
;
2088 PyrObject
*obj1
, *obj2
;
2090 double w
, sum
, rsum
;
2093 obj1
= slotRawObject(a
);
2095 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, size
, false, true);
2096 slots2
= obj2
->slots
;
2098 for (i
=0; i
<size
; ++i
) {
2099 err
= getIndexedDouble(obj1
, i
, &w
);
2100 if (err
) return err
;
2102 SetFloat(&slots2
[i
], w
);
2105 for (i
=0; i
<size
; ++i
) {
2106 double d
= slotRawFloat(&slots2
[i
]);
2107 SetRaw(&slots2
[i
], d
* rsum
);
2117 int prArrayWIndex(struct VMGlobals
*g
, int numArgsPushed
)
2121 int i
, j
, size
, err
;
2127 r
= g
->rgen
->frand();
2128 obj
= slotRawObject(a
);
2132 for (i
=0; i
<size
; ++i
) {
2133 err
= getIndexedDouble(obj
, i
, &w
);
2134 if (err
) return err
;
2164 int prArrayEnvAt(struct VMGlobals
*g
, int numArgsPushed
)
2166 PyrSlot
*a
= g
->sp
- 1;
2169 PyrObject
* env
= slotRawObject(a
);
2170 PyrSlot
* slots
= env
->slots
;
2172 // Env:asArray always gives at least 8 array elements
2173 if(env
->size
< 8) return errFailed
;
2176 int err
= slotDoubleVal(b
, &time
);
2177 if (err
) return err
;
2180 err
= slotDoubleVal(slots
+ kEnv_initLevel
, &begLevel
);
2181 if (err
) return err
;
2184 err
= slotIntVal(slots
+ kEnv_numStages
, &numStages
);
2185 if (err
) return err
;
2187 double begTime
= 0.;
2188 double endTime
= 0.;
2190 for (int i
=0; i
<numStages
; ++i
) {
2191 double dur
, endLevel
;
2195 err
= slotDoubleVal(slots
+ 0, &endLevel
);
2196 if (err
) return err
;
2197 err
= slotDoubleVal(slots
+ 1, &dur
);
2198 if (err
) return err
;
2202 //post("%d %g %g %g %g %g\n", i, time, begTime, endTime, dur, endLevel);
2204 if (time
< endTime
) {
2208 err
= slotIntVal(slots
+ 2, &shape
);
2209 if (err
) return err
;
2212 double pos
= (time
- begTime
) / dur
;
2214 //post(" shape %d pos %g\n", shape, pos);
2222 level
= pos
* (endLevel
- begLevel
) + begLevel
;
2224 case shape_Exponential
:
2225 level
= begLevel
* pow(endLevel
/ begLevel
, pos
);
2228 level
= begLevel
+ (endLevel
- begLevel
) * (-cos(pi
* pos
) * 0.5 + 0.5);
2232 if (begLevel
< endLevel
)
2233 level
= begLevel
+ (endLevel
- begLevel
) * sin(pi2
* pos
);
2235 level
= endLevel
- (endLevel
- begLevel
) * sin(pi2
- pi2
* pos
);
2239 err
= slotDoubleVal(slots
+ 3, &curve
);
2240 if (err
) return err
;
2242 if (fabs(curve
) < 0.0001) {
2243 level
= pos
* (endLevel
- begLevel
) + begLevel
;
2245 double denom
= 1. - exp(curve
);
2246 double numer
= 1. - exp(pos
* curve
);
2247 level
= begLevel
+ (endLevel
- begLevel
) * (numer
/denom
);
2250 case shape_Squared
:
2252 double sqrtBegLevel
= sqrt(begLevel
);
2253 double sqrtEndLevel
= sqrt(endLevel
);
2254 double sqrtLevel
= pos
* (sqrtEndLevel
- sqrtBegLevel
) + sqrtBegLevel
;
2255 level
= sqrtLevel
* sqrtLevel
;
2260 double cbrtBegLevel
= pow(begLevel
, 0.3333333);
2261 double cbrtEndLevel
= pow(endLevel
, 0.3333333);
2262 double cbrtLevel
= pos
* (cbrtEndLevel
- cbrtBegLevel
) + cbrtBegLevel
;
2263 level
= cbrtLevel
* cbrtLevel
* cbrtLevel
;
2272 begLevel
= endLevel
;
2275 SetFloat(a
, begLevel
);
2281 int prArrayIndexOfGreaterThan(struct VMGlobals
*g
, int numArgsPushed
)
2283 PyrSlot
*a
, *b
, *slots
;
2291 obj
= slotRawObject(a
);
2296 err
= slotDoubleVal(b
, &s
);
2297 if (err
) return err
;
2299 for (i
=0; i
<size
; ++i
) {
2300 err
= getIndexedDouble(obj
, i
, &w
);
2301 if (err
) return err
;
2315 int prArrayUnlace(struct VMGlobals
*g
, int numArgsPushed
)
2317 PyrSlot
*a
, *b
, *c
, *slots
, *slots2
, *slots3
;
2318 PyrObject
*obj1
, *obj2
, *obj3
;
2319 int i
, j
, k
, clump
, numLists
, size
, size3
, err
;
2325 obj1
= slotRawObject(a
);
2326 slots
= obj1
->slots
;
2329 err
= slotIntVal(b
, &numLists
);
2330 if (err
) return err
;
2332 err
= slotIntVal(c
, &clump
);
2333 if (err
) return err
;
2335 obj2
= instantiateObject(g
->gc
, obj1
->classptr
, numLists
, false, true);
2336 obj2
->size
= numLists
;
2337 slots2
= obj2
->slots
;
2339 SetObject(b
, obj2
); // store reference on stack, so both source and destination objects can be reached by the gc
2341 size3
= size
/ numLists
;
2342 size3
= size3
- (size3
% clump
);
2343 if(size3
< 1) return errFailed
;
2345 for(i
=0; i
<numLists
; ++i
) {
2346 obj3
= instantiateObject(g
->gc
, obj1
->classptr
, size3
, false, true);
2348 slots3
= obj3
->slots
;
2349 for(j
=0; j
<size3
; j
+=clump
) {
2350 for(k
=0; k
<clump
; ++k
) {
2351 slotCopy(&slots3
[j
+k
],&slots
[i
*clump
+ k
+ j
*numLists
]);
2354 SetObject(slots2
+ i
, obj3
);
2362 void initArrayPrimitives()
2366 base
= nextPrimitiveIndex();
2369 definePrimitive(base
, index
++, "_BasicSize", basicSize
, 1, 0);
2370 definePrimitive(base
, index
++, "_BasicMaxSize", basicMaxSize
, 1, 0);
2372 definePrimitive(base
, index
++, "_BasicSwap", basicSwap
, 3, 0);
2373 definePrimitive(base
, index
++, "_BasicAt", basicAt
, 2, 0);
2374 definePrimitive(base
, index
++, "_BasicRemoveAt", basicRemoveAt
, 2, 0);
2375 definePrimitive(base
, index
++, "_BasicTakeAt", basicTakeAt
, 2, 0);
2376 definePrimitive(base
, index
++, "_BasicClipAt", basicClipAt
, 2, 0);
2377 definePrimitive(base
, index
++, "_BasicWrapAt", basicWrapAt
, 2, 0);
2378 definePrimitive(base
, index
++, "_BasicFoldAt", basicFoldAt
, 2, 0);
2379 definePrimitive(base
, index
++, "_BasicPut", basicPut
, 3, 0);
2380 definePrimitive(base
, index
++, "_BasicClipPut", basicClipPut
, 3, 0);
2381 definePrimitive(base
, index
++, "_BasicWrapPut", basicWrapPut
, 3, 0);
2382 definePrimitive(base
, index
++, "_BasicFoldPut", basicFoldPut
, 3, 0);
2384 definePrimitive(base
, index
++, "_ArrayExtend", prArrayExtend
, 3, 0);
2385 definePrimitive(base
, index
++, "_ArrayGrow", prArrayGrow
, 2, 0);
2386 definePrimitive(base
, index
++, "_ArrayGrowClear", prArrayGrowClear
, 2, 0);
2387 definePrimitive(base
, index
++, "_ArrayAdd", prArrayAdd
, 2, 0);
2388 definePrimitive(base
, index
++, "_ArrayInsert", prArrayInsert
, 3, 0);
2389 definePrimitive(base
, index
++, "_ArrayFill", prArrayFill
, 2, 0);
2390 definePrimitive(base
, index
++, "_ArrayPop", prArrayPop
, 1, 0);
2391 definePrimitive(base
, index
++, "_ArrayCat", prArrayCat
, 2, 0);
2392 definePrimitive(base
, index
++, "_ArrayPutEach", prArrayPutEach
, 3, 0);
2393 definePrimitive(base
, index
++, "_ArrayAddAll", prArrayAddAll
, 2, 0);
2394 definePrimitive(base
, index
++, "_ArrayPutSeries", prArrayPutSeries
, 5, 0);
2395 definePrimitive(base
, index
++, "_ArrayOverwrite", prArrayOverwrite
, 3, 0);
2396 definePrimitive(base
, index
++, "_ArrayIndexOf", prArrayIndexOf
, 2, 0);
2398 definePrimitive(base
, index
++, "_ArrayNormalizeSum", prArrayNormalizeSum
, 1, 0);
2399 definePrimitive(base
, index
++, "_ArrayWIndex", prArrayWIndex
, 1, 0);
2400 definePrimitive(base
, index
++, "_ArrayReverse", prArrayReverse
, 1, 0);
2401 definePrimitive(base
, index
++, "_ArrayScramble", prArrayScramble
, 1, 0);
2402 definePrimitive(base
, index
++, "_ArrayMirror", prArrayMirror
, 1, 0);
2403 definePrimitive(base
, index
++, "_ArrayMirror1", prArrayMirror1
, 1, 0);
2404 definePrimitive(base
, index
++, "_ArrayMirror2", prArrayMirror2
, 1, 0);
2405 definePrimitive(base
, index
++, "_ArrayRotate", prArrayRotate
, 2, 0);
2406 definePrimitive(base
, index
++, "_ArrayPermute", prArrayPermute
, 2, 0);
2407 definePrimitive(base
, index
++, "_ArrayAllTuples", prArrayAllTuples
, 2, 0);
2408 definePrimitive(base
, index
++, "_ArrayPyramid", prArrayPyramid
, 2, 0);
2409 definePrimitive(base
, index
++, "_ArrayRotate", prArrayRotate
, 2, 0);
2410 definePrimitive(base
, index
++, "_ArrayExtendWrap", prArrayExtendWrap
, 2, 0);
2411 definePrimitive(base
, index
++, "_ArrayExtendFold", prArrayExtendFold
, 2, 0);
2412 definePrimitive(base
, index
++, "_ArrayExtendLast", prArrayExtendLast
, 2, 0);
2413 definePrimitive(base
, index
++, "_ArrayLace", prArrayLace
, 2, 0);
2414 definePrimitive(base
, index
++, "_ArrayStutter", prArrayStutter
, 2, 0);
2415 definePrimitive(base
, index
++, "_ArraySlide", prArraySlide
, 3, 0);
2416 definePrimitive(base
, index
++, "_ArrayContainsSeqColl", prArrayContainsSeqColl
, 1, 0);
2418 definePrimitive(base
, index
++, "_ArrayEnvAt", prArrayEnvAt
, 2, 0);
2419 definePrimitive(base
, index
++, "_ArrayIndexOfGreaterThan", prArrayIndexOfGreaterThan
, 2, 0);
2420 definePrimitive(base
, index
++, "_ArrayUnlace", prArrayUnlace
, 3, 0);
2427 #include "SCPlugin.h"
2430 extern "C" { SCPlugIn
* loadPlugIn(void); }
2434 // define plug in object
2435 class APlugIn
: public SCPlugIn
2441 virtual void AboutToCompile();
2446 // constructor for plug in
2451 // destructor for plug in
2454 void APlugIn::AboutToCompile()
2456 // this is called each time the class library is compiled.
2457 initArrayPrimitives();
2460 // This function is called when the plug in is loaded into SC.
2461 // It returns an instance of APlugIn.
2462 SCPlugIn
* loadPlugIn()
2464 return new APlugIn();