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.
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
13 //metadoc Sequence category Core
17 #include "IoCFunction.h"
20 #include "IoMessage.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
)
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.
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
);
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
);
78 IoObject
*IoSeq_convertToFixedSizeType(IoSeq
*self
, IoObject
*locals
, IoMessage
*m
)
80 IO_ASSERT_NOT_SYMBOL(self
);
81 UArray_convertToFixedSizeType(DATA(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.
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
);
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));
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.
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
)));
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.
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
));
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
));
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));
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);
217 IoObject
*IoSeq_removeSlice(IoSeq
*self
, IoObject
*locals
, IoMessage
*m
)
219 /*doc MutableSequence removeSlice(startIndex, endIndex)
220 Removes the items from startIndex to endIndex.
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);
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
));
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
);
259 void IoSeq_rawPio_reallocateToSize_(IoSeq
*self
, size_t size
)
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
);
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
));
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
));
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
);
338 UArray_removeRange(a
, startIndex
, UArray_size(b
));
339 UArray_at_putAll_(a
, startIndex
, c
);
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
);
363 long v
= IoMessage_locals_longArgAt_(m
, locals
, 1);
364 UArray_at_putLong_(a
, i
, v
);
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
));
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
));
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
));
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
));
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
));
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
));
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);
464 int IoSeq_byteCompare(const void *a
, const void *b
)
466 char aa
= *(char *)a
;
467 char bb
= *(char *)b
;
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
);
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
;
517 UArray_replace_with_(ba
, DATA(subSeq
), DATA(otherSeq
));
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
));
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
);
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
));
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:
578 " Trim this string \r\n" strip
579 ==> "Trim this string"
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
));
592 UArray space
= UArray_stackAllocedWithCString_(WHITESPACE
);
593 UArray_strip_(DATA(self
), &space
);
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:
605 "Keep the tail" lstrip(" eKp")
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
));
619 UArray space
= UArray_stackAllocedWithCString_(WHITESPACE
);
620 UArray_lstrip_(DATA(self
), &space
);
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:
632 "Cut the tail off" rstrip(" afilot")
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
));
646 UArray space
= UArray_stackAllocedWithCString_(WHITESPACE
);
647 UArray_rstrip_(DATA(self
), &space
);
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
));
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
));
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
)));
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
)),
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
));
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
));
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.
755 IoObject
*evaluatedCode
;
757 UArray
*evaluatedCodeAsString
= NULL
;
760 UArray begin
= UArray_stackAllocedWithCString_("#{");
761 UArray end
= UArray_stackAllocedWithCString_("}");
763 IO_ASSERT_NOT_SYMBOL(self
);
765 context
= IoMessage_locals_valueArgAt_(m
, locals
, 0);
767 label
= "IoSeq_interpolateInPlace()";
770 context
= (context
== IONIL(self
)) ? locals
: context
;
772 IoState_pushRetainPool(IOSTATE
);
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
);
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"));
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
);
806 if (evaluatedCodeAsString
== NULL
)
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");
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
);
837 UArray_add_(DATA(self
), DATA(other
));
839 else if (ISNUMBER(other
))
841 double value
= IoNumber_asDouble(other
);
842 UArray_addScalarDouble_(DATA(self
), value
);
846 IoMessage_locals_numberArgAt_errorForType_(self
, locals
, 0, "Sequence or Number");
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
);
861 UArray_subtract_(DATA(self
), DATA(other
));
863 else if (ISNUMBER(other
))
865 double value
= IoNumber_asDouble(other
);
866 UArray_subtractScalarDouble_(DATA(self
), value
);
870 IoMessage_locals_numberArgAt_errorForType_(self
, locals
, 0, "Sequence or Number");
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
);
885 UArray_multiply_(DATA(self
), DATA(other
));
887 else if (ISNUMBER(other
))
889 double value
= IoNumber_asDouble(other
);
890 UArray_multiplyScalarDouble_(DATA(self
), value
);
894 IoMessage_locals_numberArgAt_errorForType_(self
, locals
, 0, "Sequence or Number");
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
);
909 UArray_divide_(DATA(self
), DATA(other
));
911 else if (ISNUMBER(other
))
913 double value
= IoNumber_asDouble(other
);
914 UArray_divideScalarDouble_(DATA(self
), value
);
918 IoMessage_locals_numberArgAt_errorForType_(self
, locals
, 0, "Sequence or Number");
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
);
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
);
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
);
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
},
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
},
1148 {"ceil", IoSeq_ceil
},
1149 {"floor", IoSeq_floor
},
1151 {"log10", IoSeq_log10
},
1152 {"negate", IoSeq_negate
},
1153 {"rangeFill", IoSeq_rangeFill
},
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_
},
1192 IoObject_addMethodTable_(self
, methodTable
);