New doc system done for core
[io.git] / libs / iovm / source / IoSeq_mutable.c
blob1f7a4e5d5bb5e46d3517f7dcef1047eac71de8f6
2 //metadoc Sequence copyright Steve Dekorte 2002
3 //metadoc Sequence license BSD revised
4 /*metadoc Sequence description
5 A Sequence is a container for a list of data elements. Typically these elements are each 1 byte in size. A Sequence can be either mutable or immutable. When immutable, only the read-only methods can be used.
6 <p>
7 Terminology
8 <ul>
9 <li> Buffer: A mutable Sequence of single byte elements, typically in a binary encoding
10 <li> Symbol or String: A unique immutable Sequence, typically in a character encoding
11 </ul>
13 //metadoc Sequence category Core
15 #include "IoSeq.h"
16 #include "IoState.h"
17 #include "IoCFunction.h"
18 #include "IoObject.h"
19 #include "IoNumber.h"
20 #include "IoMessage.h"
21 #include "IoList.h"
22 #include "IoMap.h"
23 #include <ctype.h>
24 #include <errno.h>
26 #define DATA(self) ((UArray *)IoObject_dataPointer(self))
28 #define IO_ASSERT_NOT_SYMBOL(self) IoAssertNotSymbol(self, m)
29 #define IO_ASSERT_NUMBER_ENCODING(self) IOASSERT(DATA(self)->encoding == CENCODING_NUMBER, "operation not valid on non-number encodings")
31 static void IoAssertNotSymbol(IoSeq *self, IoMessage *m)
33 if (ISSYMBOL(self))
35 IoState_error_(IOSTATE, m,
36 "'%s' cannot be called on an immutable Sequence",
37 CSTRING(IoMessage_name(m)));
41 IoObject *IoSeq_setItemType(IoSeq *self, IoObject *locals, IoMessage *m)
43 /*doc MutableSequence setItemType(aTypeName)
44 Sets the underlying machine type for the elements.
45 Valid names are uint8, uint16, uint32, uint64, int8, int16, int32,
46 int64, float32, and float64. Note that 64 bit types are only available
47 on platforms that support such types. Returns self.
50 CTYPE itemType;
51 IoSeq *typeName;
53 IO_ASSERT_NOT_SYMBOL(self);
55 typeName = IoMessage_locals_symbolArgAt_(m, locals, 0);
56 itemType = CTYPE_forName(CSTRING(typeName));
58 IOASSERT(itemType != -1, "invalid item type name");
60 UArray_setItemType_(DATA(self), itemType);
62 return self;
65 IoObject *IoSeq_convertToItemType(IoSeq *self, IoObject *locals, IoMessage *m)
67 IoSymbol *typeName = IoMessage_locals_symbolArgAt_(m, locals, 0);
68 CTYPE itemType = CTYPE_forName(CSTRING(typeName));
70 IO_ASSERT_NOT_SYMBOL(self);
72 IOASSERT(itemType != -1, "invalid item type name");
74 UArray_convertToItemType_(DATA(self), itemType);
75 return self;
78 IoObject *IoSeq_convertToFixedSizeType(IoSeq *self, IoObject *locals, IoMessage *m)
80 IO_ASSERT_NOT_SYMBOL(self);
81 UArray_convertToFixedSizeType(DATA(self));
82 return self;
85 IoObject *IoSeq_setEncoding(IoSeq *self, IoObject *locals, IoMessage *m)
87 /*doc MutableSequence setEncoding(encodingName)
88 Sets the encoding flag of the receiver (only the encoding flag,
89 itemSize and itemType will change, no conversion is done between UTF
90 encodings - you can use convertToUTF8, etc methods for conversions).
91 Valid encodings are number, utf8, utf16, and utf32. Returns self.
94 CENCODING encoding;
95 IoSeq *encodingName;
97 IO_ASSERT_NOT_SYMBOL(self);
99 encodingName = IoMessage_locals_symbolArgAt_(m, locals, 0);
100 encoding = CENCODING_forName(CSTRING(encodingName));
102 IOASSERT(encoding != -1, "invalid encoding name");
104 UArray_setEncoding_(DATA(self), encoding);
106 return self;
109 void IoSeq_rawCopy_(IoSeq *self, IoSeq *other)
111 UArray_copy_(DATA(self), DATA(other));
114 IoObject *IoSeq_copy(IoSeq *self, IoObject *locals, IoMessage *m)
116 /*doc MutableSequence copy(aSequence)
117 Replaces the bytes of the receiver with a copy of those in aSequence. Returns self.
120 IO_ASSERT_NOT_SYMBOL(self);
122 IoSeq_rawCopy_(self, IoMessage_locals_seqArgAt_(m, locals, 0));
123 return self;
126 IoObject *IoSeq_appendSeq(IoSeq *self, IoObject *locals, IoMessage *m)
128 /*doc MutableSequence appendSeq(object1, object2, ...)
129 Calls asString on the arguments and appends the string to the receiver. Returns self.
132 int i;
134 IO_ASSERT_NOT_SYMBOL(self);
135 IOASSERT(IoMessage_argCount(m), "requires at least one argument");
137 for (i = 0; i < IoMessage_argCount(m); i ++)
139 UArray_append_(DATA(self), DATA(IoMessage_locals_valueAsStringArgAt_(m, locals, i)));
141 return self;
144 IoObject *IoSeq_append(IoSeq *self, IoObject *locals, IoMessage *m)
146 /*doc MutableSequence append(aNumber)
147 Appends aNumber (cast to a byte) to the receiver. Returns self.
150 int i;
152 IO_ASSERT_NOT_SYMBOL(self);
153 IOASSERT(IoMessage_argCount(m), "requires at least one argument");
155 for (i = 0; i < IoMessage_argCount(m); i ++)
157 UArray_appendDouble_(DATA(self), IoMessage_locals_doubleArgAt_(m, locals, i));
160 return self;
163 IoObject *IoSeq_atInsertSeq(IoSeq *self, IoObject *locals, IoMessage *m)
166 /*doc MutableSequence atInsertSeq(indexNumber, object)
167 Calls asString on object and inserts the string at position indexNumber. Returns self.
170 size_t n = IoMessage_locals_sizetArgAt_(m, locals, 0);
171 IoSeq *otherSeq = IoMessage_locals_valueAsStringArgAt_(m, locals, 1);
173 IO_ASSERT_NOT_SYMBOL(self);
175 IOASSERT(n <= UArray_size(DATA(self)), "insert index out of sequence bounds");
177 UArray_at_putAll_(DATA(self), n, DATA(otherSeq));
179 return self;
183 IoObject *IoSeq_atInsert(IoSeq *self, IoObject *locals, IoMessage *m)
185 doc MutableSequence atInsert(indexNumber, valueNumber)
186 Inserts valueNumber at position indexNumber. Returns self.")
188 size_t n = IoMessage_locals_sizetArgAt_(m, locals, 0);
189 IoNumber *value = IoMessage_locals_numberArgAt_(m, locals, 1);
191 IO_ASSERT_NOT_SYMBOL(self);
194 UArray_at_putAll_(DATA(self), n, DATA(otherSeq));
195 return self;
199 // removing ---------------------------------------
201 IoObject *IoSeq_removeAt(IoSeq *self, IoObject *locals, IoMessage *m)
203 /*doc MutableSequence removeAt(index)
204 Removes the item at index. Returns self.
207 long i = IoMessage_locals_longArgAt_(m, locals, 0);
209 IO_ASSERT_NOT_SYMBOL(self);
211 i = UArray_wrapPos_(DATA(self), i);
213 UArray_removeRange(DATA(self), i, 1);
214 return self;
217 IoObject *IoSeq_removeSlice(IoSeq *self, IoObject *locals, IoMessage *m)
219 /*doc MutableSequence removeSlice(startIndex, endIndex)
220 Removes the items from startIndex to endIndex.
221 Returns self.
224 long start = IoMessage_locals_longArgAt_(m, locals, 0);
225 long end = IoMessage_locals_longArgAt_(m, locals, 1);
227 IO_ASSERT_NOT_SYMBOL(self);
229 start = UArray_wrapPos_(DATA(self), start);
230 end = UArray_wrapPos_(DATA(self), end);
232 UArray_removeRange(DATA(self), start, end - start + 1);
233 return self;
236 IoObject *IoSeq_removeLast(IoSeq *self, IoObject *locals, IoMessage *m)
238 /*doc MutableSequence removeLast
239 Removes the last element from the receiver. Returns self.
242 IO_ASSERT_NOT_SYMBOL(self);
243 UArray_removeLast(DATA(self));
244 return self;
247 IoObject *IoSeq_setSize(IoSeq *self, IoObject *locals, IoMessage *m)
249 /*doc MutableSequence setSize(aNumber)
250 Sets the length in bytes of the receiver to aNumber. Return self.
253 size_t len = IoMessage_locals_sizetArgAt_(m, locals, 0);
254 IO_ASSERT_NOT_SYMBOL(self);
255 UArray_setSize_(DATA(self), len);
256 return self;
259 void IoSeq_rawPio_reallocateToSize_(IoSeq *self, size_t size)
261 if (ISSYMBOL(self))
263 IoState_error_(IOSTATE, NULL, "attempt to resize an immutable Sequence");
266 UArray_sizeTo_(DATA(self), size);
269 IoObject *IoSeq_preallocateToSize(IoSeq *self, IoObject *locals, IoMessage *m)
271 /*doc MutableSequence preallocateToSize(aNumber)
272 If needed, resize the memory alloced for the receivers
273 byte array to be large enough to fit the number of bytes specified by
274 aNumber. This is useful for pio_reallocating the memory so it doesn't
275 keep getting allocated as the Sequence is appended to. This operation
276 will not change the Sequence's length or contents. Returns self.
279 size_t newSize = IoMessage_locals_sizetArgAt_(m, locals, 0);
280 IO_ASSERT_NOT_SYMBOL(self);
281 UArray_sizeTo_(DATA(self), newSize);
282 return self;
285 IoObject *IoSeq_replaceSeq(IoSeq *self, IoObject *locals, IoMessage *m)
287 /*doc MutableSequence replaceSeq(aSequence, anotherSequence)
288 Returns a new Sequence with all occurances of aSequence
289 replaced with anotherSequence in the receiver. Returns self.
292 IoSeq *subSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
293 IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 1);
294 IO_ASSERT_NOT_SYMBOL(self);
295 UArray_replace_with_(DATA(self), DATA(subSeq), DATA(otherSeq));
296 return self;
299 IoObject *IoSeq_removeSeq(IoSeq *self, IoObject *locals, IoMessage *m)
301 /*doc MutableSequence removeSeq(aSequence)
302 Removes occurances of aSequence from the receiver.
305 IoSeq *subSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
306 IO_ASSERT_NOT_SYMBOL(self);
307 UArray_remove_(DATA(self), DATA(subSeq));
308 return self;
312 IoObject *IoSeq_replaceFirstSeq(IoSeq *self, IoObject *locals, IoMessage *m)
314 /*doc MutableSequence replaceFirstSeq(aSequence, anotherSequence, optionalStartIndex)
315 Returns a new Sequence with the first occurance of aSequence
316 replaced with anotherSequence in the receiver. If optionalStartIndex is
317 provided, the search for aSequence begins at that index. Returns self.
320 IoSeq *subSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
321 IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 1);
322 size_t startIndex = 0;
324 if (IoMessage_argCount(m) > 2)
326 IoMessage_locals_longArgAt_(m, locals, 1);
329 IO_ASSERT_NOT_SYMBOL(self);
332 UArray *a = DATA(self);
333 UArray *b = DATA(subSeq);
334 UArray *c = DATA(otherSeq);
335 long i = UArray_find_from_(a, b, startIndex);
336 if(i != -1)
338 UArray_removeRange(a, startIndex, UArray_size(b));
339 UArray_at_putAll_(a, startIndex, c);
342 return self;
345 IoObject *IoSeq_atPut(IoSeq *self, IoObject *locals, IoMessage *m)
347 /*doc MutableSequence atPut(aNumberIndex, aNumber)
348 Sets the value at the index specified by aNumberIndex to aNumber. Returns self.
351 size_t i = IoMessage_locals_longArgAt_(m, locals, 0);
352 UArray *a = DATA(self);
354 IO_ASSERT_NOT_SYMBOL(self);
356 if (UArray_isFloatType(a))
358 double v = IoMessage_locals_doubleArgAt_(m, locals, 1);
359 UArray_at_putDouble_(a, i, v);
361 else
363 long v = IoMessage_locals_longArgAt_(m, locals, 1);
364 UArray_at_putLong_(a, i, v);
367 return self;
370 IoObject *IoSeq_lowercase(IoSeq *self, IoObject *locals, IoMessage *m)
372 /*doc MutableSequence Lowercase
373 Returns a copy of the receiver with all characters made Lowercase.
376 IO_ASSERT_NOT_SYMBOL(self);
377 UArray_tolower(DATA(self));
378 return self;
381 IoObject *IoSeq_uppercase(IoSeq *self, IoObject *locals, IoMessage *m)
383 /*doc MutableSequence uppercase
384 Makes all characters of the receiver uppercase.
387 IO_ASSERT_NOT_SYMBOL(self);
388 UArray_toupper(DATA(self));
389 return self;
392 // clip --------------------------------------
394 IoObject *IoSeq_clipBeforeSeq(IoSeq *self, IoObject *locals, IoMessage *m)
396 /*doc MutableSequence clipBeforeSeq(aSequence)
397 Clips receiver before aSequence.
400 IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
401 IO_ASSERT_NOT_SYMBOL(self);
402 UArray_clipBefore_(DATA(self), DATA(otherSeq));
403 return self;
406 IoObject *IoSeq_clipAfterSeq(IoSeq *self, IoObject *locals, IoMessage *m)
408 /*doc MutableSequence clipAfterSeq(aSequence)
409 Removes the contents of the receiver after the end of
410 the first occurance of aSequence. Returns true if anything was
411 removed, or false otherwise.
414 IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
416 IO_ASSERT_NOT_SYMBOL(self);
417 UArray_clipAfter_(DATA(self), DATA(otherSeq));
418 return self;
421 IoObject *IoSeq_clipBeforeEndOfSeq(IoSeq *self, IoObject *locals, IoMessage *m)
423 /*doc MutableSequence clipBeforeEndOfSeq(aSequence)
424 Removes the contents of the receiver before the end of
425 the first occurance of aSequence. Returns true if anything was
426 removed, or false otherwise.
429 IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
430 IO_ASSERT_NOT_SYMBOL(self);
431 UArray_clipBeforeEndOf_(DATA(self), DATA(otherSeq));
432 return self;
435 IoObject *IoSeq_clipAfterStartOfSeq(IoSeq *self, IoObject *locals, IoMessage *m)
437 /*doc MutableSequence clipAfterStartOfSeq(aSequence)
438 Removes the contents of the receiver after the beginning of
439 the first occurance of aSequence. Returns true if anything was
440 removed, or false otherwise.
443 IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
444 IO_ASSERT_NOT_SYMBOL(self);
445 UArray_clipAfterStartOf_(DATA(self), DATA(otherSeq));
446 return self;
449 // -----------------------------------------
451 IoObject *IoSeq_empty(IoSeq *self, IoObject *locals, IoMessage *m)
453 /*doc MutableSequence clear
454 Sets all bytes in the receiver to 0x0 and sets
455 it's length to 0. Returns self.
458 IO_ASSERT_NOT_SYMBOL(self);
459 UArray_clear(DATA(self));
460 UArray_setSize_(DATA(self), 0);
461 return self;
464 int IoSeq_byteCompare(const void *a, const void *b)
466 char aa = *(char *)a;
467 char bb = *(char *)b;
469 if (aa < bb)
471 return -1;
474 if (aa == bb)
476 return 0;
479 return 1;
482 IoObject *IoSeq_sort(IoSeq *self, IoObject *locals, IoMessage *m)
484 UArray *a = DATA(self);
485 IO_ASSERT_NOT_SYMBOL(self);
487 if(UArray_itemType(a) == CTYPE_uintptr_t)
489 UArray_sortBy_(a, (UArraySortCallback *)IoObject_compare);
491 else
493 UArray_sort(a);
496 return self;
499 IoObject *IoSeq_replaceMap(IoSeq *self, IoObject *locals, IoMessage *m)
501 /*doc MutableSequence replaceMap(aMap)
502 In the receiver, the keys of aMap replaced with it's values. Returns self.
505 IoMap *map = IoMessage_locals_mapArgAt_(m, locals, 0);
506 UArray *ba = DATA(self);
508 IO_ASSERT_NOT_SYMBOL(self);
510 PHASH_FOREACH(IoMap_rawHash(map), k, v,
512 IoSymbol *subSeq = k;
513 IoSymbol *otherSeq = v;
515 if (ISSEQ(otherSeq))
517 UArray_replace_with_(ba, DATA(subSeq), DATA(otherSeq));
519 else
521 IoState_error_(IOSTATE, m,
522 "argument 0 to method '%s' must be a Map with Sequence values, not '%s'",
523 CSTRING(IoMessage_name(m)), IoObject_name(otherSeq));
528 return self;
531 // translate ------------------------------------------------------
533 IoObject *IoSeq_translate(IoSeq *self, IoObject *locals, IoMessage *m)
535 /*doc MutableSequence translate(fromChars, toChars)
536 In the receiver, the characters in fromChars are replaced with those in the same positions in toChars. Returns self.
539 UArray *ba = DATA(self);
540 UArray *fc = DATA(IoMessage_locals_seqArgAt_(m, locals, 0));
541 UArray *tc = DATA(IoMessage_locals_seqArgAt_(m, locals, 1));
543 IO_ASSERT_NOT_SYMBOL(self);
545 if (UArray_size(tc) != UArray_size(fc))
547 IoState_error_(IOSTATE, m, "translation strings must be of the same length");
550 UArray_translate(ba, fc, tc);
552 return self;
555 // reverse --------------------------------------------------------
557 IoObject *IoSeq_reverse(IoSeq *self, IoObject *locals, IoMessage *m)
559 /*doc MutableSequence reverse
560 Reverses the bytes in the receiver, in-place.
563 IO_ASSERT_NOT_SYMBOL(self);
565 UArray_reverse(DATA(self));
566 return self;
570 // strip ----------------------------------------------------------
572 IoObject *IoSeq_strip(IoSeq *self, IoObject *locals, IoMessage *m)
574 /*doc MutableSequence strip(optionalSequence)
575 Trims the whitespace (or optionalSequence) off both ends:
577 <code>
578 " Trim this string \r\n" strip
579 ==> "Trim this string"
580 </code>
583 IO_ASSERT_NOT_SYMBOL(self);
585 if (IoMessage_argCount(m) > 0)
587 IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
588 UArray_strip_(DATA(self), DATA(other));
590 else
592 UArray space = UArray_stackAllocedWithCString_(WHITESPACE);
593 UArray_strip_(DATA(self), &space);
596 return self;
599 IoObject *IoSeq_lstrip(IoSeq *self, IoObject *locals, IoMessage *m)
601 /*doc MutableSequence lstrip(aSequence)
602 Strips the characters in aSequence
603 stripped from the beginning of the receiver. Example:
604 <code>
605 "Keep the tail" lstrip(" eKp")
606 ==> "the tail"
607 </code>
610 IO_ASSERT_NOT_SYMBOL(self);
612 if (IoMessage_argCount(m) > 0)
614 IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
615 UArray_lstrip_(DATA(self), DATA(other));
617 else
619 UArray space = UArray_stackAllocedWithCString_(WHITESPACE);
620 UArray_lstrip_(DATA(self), &space);
623 return self;
626 IoObject *IoSeq_rstrip(IoSeq *self, IoObject *locals, IoMessage *m)
628 /*doc MutableSequence rstrip(aSequence)
629 Strips the characters in
630 aSequence stripped from the end of the receiver. Example:
631 <code>
632 "Cut the tail off" rstrip(" afilot")
633 ==> "Cut the"
634 </code>
637 IO_ASSERT_NOT_SYMBOL(self);
639 if (IoMessage_argCount(m) > 0)
641 IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
642 UArray_rstrip_(DATA(self), DATA(other));
644 else
646 UArray space = UArray_stackAllocedWithCString_(WHITESPACE);
647 UArray_rstrip_(DATA(self), &space);
650 return self;
653 // -----------------------------------------------------------
655 IoObject *IoSeq_escape(IoSeq *self, IoObject *locals, IoMessage *m)
657 /*doc MutableSequence escape
658 Escape characters in the receiver are replaced with escape codes.
659 For example a string containing a single return character would contain the
660 following 2 characters after being escaped: "\n". Returns self.
663 IO_ASSERT_NOT_SYMBOL(self);
664 UArray_escape(DATA(self));
665 return self;
668 IoObject *IoSeq_unescape(IoSeq *self, IoObject *locals, IoMessage *m)
670 /*doc MutableSequence unescape
671 Escape codes replaced with escape characters. Returns self.
674 IO_ASSERT_NOT_SYMBOL(self);
675 UArray_unescape(DATA(self));
676 return self;
679 IoObject *IoSeq_removePrefix(IoSeq *self, IoObject *locals, IoMessage *m)
681 /*doc MutableSequence removePrefix(aSequence)
682 If the receiver begins with aSequence, it is removed. Returns self.
685 IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
687 IO_ASSERT_NOT_SYMBOL(self);
689 if (UArray_beginsWith_(DATA(self), DATA(other)))
691 UArray_removeRange(DATA(self), 0, UArray_size(DATA(other)));
694 return self;
697 IoObject *IoSeq_removeSuffix(IoSeq *self, IoObject *locals, IoMessage *m)
699 /*doc MutableSequence removeSuffix(aSequence)
700 If the receiver end with aSequence, it is removed. Returns self.
703 IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
705 IO_ASSERT_NOT_SYMBOL(self);
707 if (UArray_endsWith_(DATA(self), DATA(other)))
709 UArray *ba = DATA(self);
710 UArray_removeRange(ba,
711 UArray_size(ba) - UArray_size(DATA(other)),
712 UArray_size(ba));
715 return self;
718 IoObject *IoSeq_capitalize(IoSeq *self, IoObject *locals, IoMessage *m)
720 /*doc MutableSequence capitalize
721 First charater of the receiver is made uppercase.
724 int firstChar = UArray_firstLong(DATA(self));
726 IO_ASSERT_NOT_SYMBOL(self);
727 UArray_at_putLong_(DATA(self), 0, toupper(firstChar));
728 return self;
731 IoObject *IoSeq_appendPathSeq(IoSeq *self, IoObject *locals, IoMessage *m)
733 /*doc MutableSequence appendPathSeq(aSeq)
734 Appends argument to the receiver such that there is one
735 and only one path separator between the two. Returns self.
738 IoSeq *component = IoMessage_locals_seqArgAt_(m, locals, 0);
740 IO_ASSERT_NOT_SYMBOL(self);
741 UArray_appendPath_(DATA(self), DATA(component));
742 return self;
745 IoObject *IoSeq_interpolateInPlace(IoSeq *self, IoObject *locals, IoMessage *m)
747 /*doc MutableSequence interpolateInPlace(optionalContext)
748 Replaces all #{expression} with expression evaluated in the optionalContext.
749 If optionalContext not given, the current context is used. Returns self.
752 IoObject *context;
753 UArray *string;
754 UArray *code;
755 IoObject *evaluatedCode;
756 IoSeq *codeString;
757 UArray *evaluatedCodeAsString = NULL;
758 const char *label;
759 int from, to;
760 UArray begin = UArray_stackAllocedWithCString_("#{");
761 UArray end = UArray_stackAllocedWithCString_("}");
763 IO_ASSERT_NOT_SYMBOL(self);
765 context = IoMessage_locals_valueArgAt_(m, locals, 0);
766 string = DATA(self);
767 label = "IoSeq_interpolateInPlace()";
768 from = 0;
770 context = (context == IONIL(self)) ? locals : context;
772 IoState_pushRetainPool(IOSTATE);
774 for(;;)
776 IoState_clearTopPool(IOSTATE);
778 from = UArray_find_from_(string, &begin, from);
779 if (from == -1) break;
781 to = UArray_find_from_(string, &end, from);
782 if (to == -1) break;
784 code = UArray_slice(string, from + 2, to);
785 codeString = IoSeq_newWithUArray_copy_(IOSTATE, code, 0);
787 if (UArray_size(code) == 0)
789 // we don't want "#{}" to interpolate into "nil"
790 evaluatedCodeAsString = DATA(IoState_doCString_(IOSTATE, "Sequence clone"));
792 else
794 IoMessage *em = IoMessage_newWithName_andCachedArg_(IOSTATE, IOSYMBOL("doString"), codeString);
795 evaluatedCode = IoObject_perform(context, context, em);
796 evaluatedCode = IoObject_perform(evaluatedCode, context, IOSTATE->asStringMessage);
798 if (ISSEQ(evaluatedCode))
800 evaluatedCodeAsString = DATA(evaluatedCode);
804 //UArray_free(code);
806 if (evaluatedCodeAsString == NULL)
808 break;
811 UArray_removeRange(string, from, to-from+1);
812 UArray_at_putAll_(string, from, evaluatedCodeAsString);
813 from = from + UArray_size(evaluatedCodeAsString);
816 IoState_popRetainPool(IOSTATE);
818 if (from >= 0 && to >= 0)
820 IOASSERT(evaluatedCodeAsString != NULL, "bad asString results");
823 return self;
826 // math ---------------------------------------------------------------------
828 IoObject *IoSeq_addEquals(IoSeq *self, IoObject *locals, IoMessage *m)
830 IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
832 IO_ASSERT_NOT_SYMBOL(self);
833 IO_ASSERT_NUMBER_ENCODING(self);
835 if (ISSEQ(other))
837 UArray_add_(DATA(self), DATA(other));
839 else if (ISNUMBER(other))
841 double value = IoNumber_asDouble(other);
842 UArray_addScalarDouble_(DATA(self), value);
844 else
846 IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
849 return self;
852 IoObject *IoSeq_subtractEquals(IoSeq *self, IoObject *locals, IoMessage *m)
854 IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
856 IO_ASSERT_NOT_SYMBOL(self);
857 IO_ASSERT_NUMBER_ENCODING(self);
859 if (ISSEQ(other))
861 UArray_subtract_(DATA(self), DATA(other));
863 else if (ISNUMBER(other))
865 double value = IoNumber_asDouble(other);
866 UArray_subtractScalarDouble_(DATA(self), value);
868 else
870 IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
873 return self;
876 IoObject *IoSeq_multiplyEquals(IoSeq *self, IoObject *locals, IoMessage *m)
878 IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
880 IO_ASSERT_NOT_SYMBOL(self);
881 IO_ASSERT_NUMBER_ENCODING(self);
883 if (ISSEQ(other))
885 UArray_multiply_(DATA(self), DATA(other));
887 else if (ISNUMBER(other))
889 double value = IoNumber_asDouble(other);
890 UArray_multiplyScalarDouble_(DATA(self), value);
892 else
894 IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
897 return self;
900 IoObject *IoSeq_divideEquals(IoSeq *self, IoObject *locals, IoMessage *m)
902 IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
904 IO_ASSERT_NOT_SYMBOL(self);
905 IO_ASSERT_NUMBER_ENCODING(self);
907 if (ISSEQ(other))
909 UArray_divide_(DATA(self), DATA(other));
911 else if (ISNUMBER(other))
913 double value = IoNumber_asDouble(other);
914 UArray_divideScalarDouble_(DATA(self), value);
916 else
918 IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
921 return self;
924 IoObject *IoSeq_clone(IoSeq *self)
926 return IoSeq_newWithUArray_copy_(IOSTATE, DATA(self), 1);
929 IoObject *IoSeq_add(IoSeq *self, IoObject *locals, IoMessage *m)
931 return IoSeq_addEquals(IoSeq_clone(self), locals, m);
934 IoObject *IoSeq_subtract(IoSeq *self, IoObject *locals, IoMessage *m)
936 return IoSeq_subtractEquals(IoSeq_clone(self), locals, m);
939 IoObject *IoSeq_multiply(IoSeq *self, IoObject *locals, IoMessage *m)
941 return IoSeq_multiplyEquals(IoSeq_clone(self), locals, m);
944 IoObject *IoSeq_divide(IoSeq *self, IoObject *locals, IoMessage *m)
946 return IoSeq_divideEquals(IoSeq_clone(self), locals, m);
949 IoObject *IoSeq_dotProduct(IoSeq *self, IoObject *locals, IoMessage *m)
951 IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
952 IO_ASSERT_NOT_SYMBOL(self);
953 return IONUMBER(UArray_dotProduct_(DATA(self), DATA(other)));
956 IoObject *IoSeq_setItemsToLong_(IoSeq *self, IoObject *locals, IoMessage *m)
958 long v = IoMessage_locals_longArgAt_(m, locals, 0);
959 IO_ASSERT_NOT_SYMBOL(self);
960 UArray_setItemsToLong_(DATA(self), v);
961 return self;
964 IoObject *IoSeq_setItemsToDouble_(IoSeq *self, IoObject *locals, IoMessage *m)
966 double v = IoMessage_locals_doubleArgAt_(m, locals, 0);
967 IO_ASSERT_NOT_SYMBOL(self);
968 UArray_setItemsToLong_(DATA(self), v);
969 return self;
972 IoObject *IoSeq_set_(IoSeq *self, IoObject *locals, IoMessage *m)
974 double i, max = IoMessage_argCount(m);
975 IO_ASSERT_NOT_SYMBOL(self);
977 for (i = 0; i < max; i ++)
979 double v = IoMessage_locals_doubleArgAt_(m, locals, i);
980 UArray_at_putDouble_(DATA(self), i, v);
983 return self;
986 #define IoSeqMutateNoArgNoResultOp(name) \
987 IoObject *IoSeq_ ## name (IoSeq *self, IoObject *locals, IoMessage *m) \
988 { IO_ASSERT_NOT_SYMBOL(self); UArray_ ## name (DATA(self)); return self; }
990 IoSeqMutateNoArgNoResultOp(negate);
991 IoSeqMutateNoArgNoResultOp(rangeFill);
993 IoSeqMutateNoArgNoResultOp(sin);
994 IoSeqMutateNoArgNoResultOp(cos);
995 IoSeqMutateNoArgNoResultOp(tan);
997 IoSeqMutateNoArgNoResultOp(asin);
998 IoSeqMutateNoArgNoResultOp(acos);
999 IoSeqMutateNoArgNoResultOp(atan);
1001 IoSeqMutateNoArgNoResultOp(sinh);
1002 IoSeqMutateNoArgNoResultOp(cosh);
1003 IoSeqMutateNoArgNoResultOp(tanh);
1005 IoSeqMutateNoArgNoResultOp(exp);
1006 IoSeqMutateNoArgNoResultOp(log);
1007 IoSeqMutateNoArgNoResultOp(log10);
1009 IoSeqMutateNoArgNoResultOp(ceil);
1010 IoSeqMutateNoArgNoResultOp(floor);
1011 IoSeqMutateNoArgNoResultOp(abs);
1013 IoSeqMutateNoArgNoResultOp(square);
1014 IoSeqMutateNoArgNoResultOp(sqrt);
1015 IoSeqMutateNoArgNoResultOp(normalize);
1017 #define IoSeqNoArgNumberResultOp(name) \
1018 IoObject *IoSeq_ ## name (IoSeq *self, IoObject *locals, IoMessage *m) \
1019 { return IONUMBER(UArray_ ## name (DATA(self))); }
1021 IoSeqNoArgNumberResultOp(sumAsDouble);
1022 IoSeqNoArgNumberResultOp(productAsDouble);
1023 IoSeqNoArgNumberResultOp(minAsDouble);
1024 IoSeqNoArgNumberResultOp(maxAsDouble);
1025 IoSeqNoArgNumberResultOp(arithmeticMeanAsDouble);
1026 IoSeqNoArgNumberResultOp(arithmeticMeanSquareAsDouble);
1027 IoSeqNoArgNumberResultOp(hash);
1029 #define IoSeqLongArgNumberResultOp(name) \
1030 IoObject *IoSeq_ ## name (IoSeq *self, IoObject *locals, IoMessage *m) \
1031 { return IONUMBER(UArray_ ## name (DATA(self), IoMessage_locals_longArgAt_(m, locals, 0))); }
1033 //IoSeqLongArgNumberResultOp(setAllBitsTo_);
1034 IoSeqLongArgNumberResultOp(byteAt_);
1035 IoSeqLongArgNumberResultOp(bitAt_);
1036 IoSeqNoArgNumberResultOp(bitCount);
1038 #define IoSeqSeqArgNoResultOp(name) \
1039 IoObject *IoSeq_ ## name (IoSeq *self, IoObject *locals, IoMessage *m) \
1040 { IO_ASSERT_NOT_SYMBOL(self); UArray_ ## name (DATA(self), DATA(IoMessage_locals_seqArgAt_(m, locals, 0))); return self; }
1042 IoSeqSeqArgNoResultOp(bitwiseOr_);
1043 IoSeqSeqArgNoResultOp(bitwiseAnd_);
1044 IoSeqSeqArgNoResultOp(bitwiseXor_);
1045 IoSeqMutateNoArgNoResultOp(bitwiseNot);
1047 IoSeqSeqArgNoResultOp(logicalOr_);
1048 IoSeqSeqArgNoResultOp(logicalAnd_);
1050 IoSeqSeqArgNoResultOp(Max);
1051 IoSeqSeqArgNoResultOp(Min);
1053 /*doc MutableSequence removeOddIndexes
1054 Removes odd indexes in the receiver.
1055 For example, list(1,2,3) removeOddIndexes == list(2). Returns self.
1058 /*doc MutableSequence removeEvenIndexes
1059 Removes even indexes in the receiver.
1060 For example, list(1,2,3) removeEvenIndexes == list(1, 3). Returns self.
1063 /*doc MutableSequence duplicateIndexes
1064 Duplicates all indexes in the receiver.
1065 For example, list(1,2,3) duplicateIndexes == list(1,1,2,2,3,3). Returns self.")
1068 IoSeqMutateNoArgNoResultOp(duplicateIndexes);
1069 IoSeqMutateNoArgNoResultOp(removeOddIndexes);
1070 IoSeqMutateNoArgNoResultOp(removeEvenIndexes);
1072 IoSeqMutateNoArgNoResultOp(clear);
1075 void IoSeq_addMutableMethods(IoSeq *self)
1077 IoMethodTable methodTable[] = {
1078 {"setItemType", IoSeq_setItemType},
1079 {"setEncoding", IoSeq_setEncoding},
1080 {"convertToItemType", IoSeq_convertToItemType},
1081 {"convertToFixedSizeType", IoSeq_convertToFixedSizeType},
1082 {"copy", IoSeq_copy},
1083 {"appendSeq", IoSeq_appendSeq},
1084 {"append", IoSeq_append},
1085 {"atInsertSeq", IoSeq_atInsertSeq},
1086 {"removeAt", IoSeq_removeAt},
1087 {"removeSlice", IoSeq_removeSlice},
1088 {"removeLast", IoSeq_removeLast},
1089 {"setSize", IoSeq_setSize},
1090 {"preallocateToSize", IoSeq_preallocateToSize},
1091 {"replaceSeq", IoSeq_replaceSeq},
1092 {"removeSeq", IoSeq_removeSeq},
1093 {"replaceFirstSeq", IoSeq_replaceFirstSeq},
1094 {"atPut", IoSeq_atPut},
1095 {"lowercase", IoSeq_lowercase},
1096 {"uppercase", IoSeq_uppercase},
1097 {"translate", IoSeq_translate},
1099 {"clipBeforeSeq", IoSeq_clipBeforeSeq},
1100 {"clipAfterSeq", IoSeq_clipAfterSeq},
1101 {"clipBeforeEndOfSeq", IoSeq_clipBeforeEndOfSeq},
1102 {"clipAfterStartOfSeq", IoSeq_clipAfterStartOfSeq},
1104 {"empty", IoSeq_empty},
1105 {"sort", IoSeq_sort},
1106 {"reverse", IoSeq_reverse},
1107 {"replaceMap", IoSeq_replaceMap},
1109 {"strip", IoSeq_strip},
1110 {"lstrip", IoSeq_lstrip},
1111 {"rstrip", IoSeq_rstrip},
1113 {"zero", IoSeq_clear},
1115 {"escape", IoSeq_escape},
1116 {"unescape", IoSeq_unescape},
1117 {"removePrefix", IoSeq_removePrefix},
1118 {"removeSuffix", IoSeq_removeSuffix},
1119 {"capitalize", IoSeq_capitalize},
1120 {"appendPathSeq", IoSeq_appendPathSeq},
1122 {"interpolateInPlace", IoSeq_interpolateInPlace},
1124 {"+=", IoSeq_addEquals},
1125 {"-=", IoSeq_subtractEquals},
1126 {"*=", IoSeq_multiplyEquals},
1127 {"/=", IoSeq_divideEquals},
1129 {"+", IoSeq_add},
1130 {"-", IoSeq_subtract},
1131 {"*", IoSeq_multiply},
1132 {"/", IoSeq_divide},
1135 {"dotProduct", IoSeq_dotProduct},
1136 {"sum", IoSeq_sumAsDouble},
1137 {"product", IoSeq_productAsDouble},
1138 {"min", IoSeq_minAsDouble},
1139 {"max", IoSeq_maxAsDouble},
1140 {"mean", IoSeq_arithmeticMeanAsDouble},
1141 {"meanSquare", IoSeq_arithmeticMeanSquareAsDouble},
1142 {"square", IoSeq_square},
1143 {"sqrt", IoSeq_sqrt},
1144 {"normalize", IoSeq_normalize},
1145 {"hash", IoSeq_hash},
1147 {"abs", IoSeq_abs},
1148 {"ceil", IoSeq_ceil},
1149 {"floor", IoSeq_floor},
1150 {"log", IoSeq_log},
1151 {"log10", IoSeq_log10},
1152 {"negate", IoSeq_negate},
1153 {"rangeFill", IoSeq_rangeFill},
1154 {"Min", IoSeq_Min},
1155 {"Max", IoSeq_Min},
1157 {"sin", IoSeq_sin},
1158 {"cos", IoSeq_cos},
1159 {"tan", IoSeq_tan},
1161 {"asin", IoSeq_asin},
1162 {"acos", IoSeq_acos},
1163 {"atan", IoSeq_atan},
1165 {"sinh", IoSeq_sinh},
1166 {"cosh", IoSeq_cosh},
1167 {"tanh", IoSeq_tanh},
1169 {"removeOddIndexes", IoSeq_removeOddIndexes},
1170 {"removeEvenIndexes", IoSeq_removeEvenIndexes},
1171 {"duplicateIndexes", IoSeq_duplicateIndexes},
1174 //{"setAllBitsTo", IoSeq_setAllBitsTo_},
1175 {"byteAt", IoSeq_byteAt_},
1176 {"bitAt", IoSeq_bitAt_},
1177 {"bitCount", IoSeq_bitCount},
1179 {"bitwiseOr", IoSeq_bitwiseOr_},
1180 {"bitwiseAnd", IoSeq_bitwiseAnd_},
1181 {"bitwiseXor", IoSeq_bitwiseXor_},
1182 {"bitwiseNot", IoSeq_bitwiseNot},
1184 {"logicalOr", IoSeq_logicalOr_},
1185 {"setItemsToLong", IoSeq_setItemsToLong_},
1186 {"setItemsToDouble", IoSeq_setItemsToDouble_},
1187 {"set", IoSeq_set_},
1189 {NULL, NULL},
1192 IoObject_addMethodTable_(self, methodTable);