3 docCopyright("Steve Dekorte", 2002)
4 docLicense("BSD revised")
6 docDescription("""A Message object encapsulates the action of a message send. Blocks are composed of a Message and its children.
16 Important; Modifying the message tree of a block currently in use may cause
17 a crash if a garbage collection cycle occurs. If the implementation were
18 changed to retain every called message, this could be avoided.
19 But the cost to performance seems to outweigh the need to cover this case for now.
26 #include "IoMessage.h"
32 #include "IoCFunction.h"
39 #include "IoMessage_parser.h"
40 #include "IoMessage_opShuffle.h"
42 #define DATA(self) ((IoMessageData *)IoObject_dataPointer(self))
44 void IoMessage_writeToStream_(IoMessage
*self
, BStream
*stream
)
46 UArray
*ba
= IoMessage_description(self
);
47 BStream_writeTaggedUArray_(stream
, ba
);
51 void IoMessage_readFromStream_(IoMessage
*self
, BStream
*stream
)
53 const char *code
= BStream_readTaggedCString(stream
);
54 IoMessage
*m
= IoMessage_newFromText_label_(IOSTATE
, (char *)code
, "[from store]");
55 IoMessage_copy_(self
, m
);
58 IoObject
*IoMessage_activate(IoMessage
*self
, IoObject
*target
, IoObject
*locals
, IoMessage
*m
, IoObject
*slotContext
)
60 //printf("activating self %s\n", CSTRING(IoMessage_name(self)));
61 //printf("activating m %s\n", CSTRING(IoMessage_name(m)));
63 return IoMessage_locals_performOn_(self
, locals
, locals
);
64 //return IoObject_perform(locals, locals, self);
67 IoTag
*IoMessage_newTag(void *state
)
69 IoTag
*tag
= IoTag_newWithName_("Message");
70 IoTag_state_(tag
, state
);
71 IoTag_cloneFunc_(tag
, (IoTagCloneFunc
*)IoMessage_rawClone
);
72 IoTag_freeFunc_(tag
, (IoTagFreeFunc
*)IoMessage_free
);
73 IoTag_markFunc_(tag
, (IoTagMarkFunc
*)IoMessage_mark
);
74 IoTag_writeToStreamFunc_(tag
, (IoTagWriteToStreamFunc
*)IoMessage_writeToStream_
);
75 IoTag_readFromStreamFunc_(tag
, (IoTagReadFromStreamFunc
*)IoMessage_readFromStream_
);
76 IoTag_activateFunc_(tag
, (IoTagActivateFunc
*)IoMessage_activate
);
80 IoMessage
*IoMessage_proto(void *state
)
82 IoMethodTable methodTable
[] = {
83 {"clone", IoMessage_clone
},
85 {"name", IoMessage_protoName
},
86 {"setName", IoMessage_protoSetName
},
88 {"next", IoMessage_next
},
89 {"setNext", IoMessage_setNext
},
90 {"isEndOfLine", IoMessage_isEOL
},
91 {"nextIgnoreEndOfLines", IoMessage_nextIgnoreEOLs
},
92 {"last", IoMessage_last
},
93 {"lastBeforeEndOfLine", IoMessage_lastBeforeEOL
},
95 {"argAt", IoMessage_argAt
},
96 {"arguments", IoMessage_arguments
},
97 {"setArguments", IoMessage_setArguments
},
98 {"appendArg", IoMessage_appendArg
},
99 {"appendCachedArg", IoMessage_appendCachedArg
},
100 {"argCount", IoMessage_argCount_
},
102 {"cachedResult", IoMessage_cachedResult
},
103 {"setCachedResult", IoMessage_setCachedResult
},
104 {"removeCachedResult", IoMessage_removeCachedResult
},
105 {"hasCachedResult", IoMessage_hasCachedResult
},
107 {"lineNumber", IoMessage_lineNumber
},
108 {"setLineNumber", IoMessage_setLineNumber
},
110 {"characterNumber", IoMessage_characterNumber
},
111 {"setCharacterNumber", IoMessage_setCharacterNumber
},
113 {"label", IoMessage_label
},
114 {"setLabel", IoMessage_setLabel
},
116 {"code", IoMessage_descriptionString
},
117 {"doInContext", IoMessage_doInContext
},
118 {"fromString", IoMessage_fromString
},
119 {"argsEvaluatedIn", IoMessage_argsEvaluatedIn
},
120 {"asString", IoMessage_asString
},
122 {"asMessageWithEvaluatedArgs", IoMessage_asMessageWithEvaluatedArgs
},
124 {"opShuffle", IoMessage_opShuffle
},
125 {"opShuffleC", IoMessage_opShuffle
},
130 IoObject
*self
= IoObject_new(state
);
132 IoObject_setDataPointer_(self
, io_calloc(1, sizeof(IoMessageData
)));
133 d
= IoObject_dataPointer(self
);
135 IoObject_tag_(self
, IoMessage_newTag(state
));
136 d
->args
= List_new();
137 d
->name
= IOSYMBOL("[unnamed]");
138 d
->label
= IOSYMBOL("[unlabeled]");
139 //d->charNumber = -1;
141 IoState_registerProtoWithFunc_((IoState
*)state
, self
, IoMessage_proto
);
143 IoObject_addMethodTable_(self
, methodTable
);
147 IoMessage
*IoMessage_rawClone(IoMessage
*proto
)
149 IoObject
*self
= IoObject_rawClonePrimitive(proto
);
151 IoObject_setDataPointer_(self
, io_calloc(1, sizeof(IoMessageData
)));
152 DATA(self
)->args
= List_new();
153 DATA(self
)->name
= DATA(proto
)->name
;
154 DATA(self
)->label
= DATA(proto
)->label
;
155 /* any clone really needs to be a deep copy */
159 IoMessage
*IoMessage_new(void *state
)
161 IoObject
*proto
= IoState_protoWithInitFunction_((IoState
*)state
, IoMessage_proto
);
162 IoObject
*self
= IOCLONE(proto
);
166 // Message shallowCopy := method(Message clone setName(name) setArguments(arguments))
168 void IoMessage_copy_(IoMessage
*self
, IoMessage
*other
)
170 DATA(self
)->name
= IOREF(DATA(other
)->name
);
173 List
*l1
= DATA(self
)->args
;
174 List
*l2
= DATA(other
)->args
;
175 int i
, max
= List_size(l2
);
178 for (i
= 0; i
< max
; i
++)
180 List_append_(l1
, IOREF(List_rawAt_(l2
, i
)));
184 if (DATA(other
)->next
) IOREF(DATA(other
)->next
);
185 DATA(self
)->next
= DATA(other
)->next
;
187 if (DATA(other
)->cachedResult
) IOREF(DATA(other
)->cachedResult
);
188 DATA(self
)->cachedResult
= DATA(other
)->cachedResult
;
190 IoMessage_rawCopySourceLocation(self
, other
);
193 void IoMessage_rawCopySourceLocation(IoMessage
*self
, IoMessage
*other
)
195 //DATA(self)->charNumber = DATA(other)->charNumber;
196 DATA(self
)->lineNumber
= DATA(other
)->lineNumber
;
198 if (DATA(other
)->label
) IOREF(DATA(other
)->label
);
199 DATA(self
)->label
= DATA(other
)->label
;
202 IoMessage
*IoMessage_deepCopyOf_(IoMessage
*self
)
204 IoMessage
*child
= IoMessage_new(IOSTATE
);
207 /*printf("deep copying: %s\n", UArray_asCString(IoMessage_description(self)));*/
208 for (i
= 0; i
< IoMessage_argCount(self
); i
++)
210 List_append_(DATA(child
)->args
,
211 IOREF(IoMessage_deepCopyOf_(LIST_AT_(DATA(self
)->args
, i
))));
214 DATA(child
)->name
= IOREF(DATA(self
)->name
);
215 IoMessage_cachedResult_(child
, (IoObject
*)DATA(self
)->cachedResult
);
217 if (DATA(self
)->next
)
219 DATA(child
)->next
= IOREF(IoMessage_deepCopyOf_(DATA(self
)->next
));
221 /*printf("deep copy result: %s\n", UArray_asCString(IoMessage_description(child)));*/
225 IoMessage
*IoMessage_newWithName_(void *state
, IoSymbol
*symbol
)
227 IoMessage
*self
= IoMessage_new(state
);
228 DATA(self
)->name
= IOREF(symbol
);
232 IoMessage
*IoMessage_newWithName_label_(void *state
, IoSymbol
*symbol
, IoSymbol
*label
)
234 IoMessage
*self
= IoMessage_new(state
);
235 DATA(self
)->name
= IOREF(symbol
);
236 DATA(self
)->label
= IOREF(label
);
240 IoMessage
*IoMessage_newWithName_returnsValue_(void *state
, IoSymbol
*symbol
, IoObject
*v
)
242 IoMessage
*self
= IoMessage_new(state
);
243 DATA(self
)->name
= IOREF(symbol
);
244 DATA(self
)->cachedResult
= IOREF(v
);
248 IoMessage
*IoMessage_newWithName_andCachedArg_(void *state
, IoSymbol
*symbol
, IoObject
*arg
)
250 IoMessage
*self
= IoMessage_newWithName_(state
, symbol
);
251 IoMessage_addCachedArg_(self
, arg
);
255 void IoMessage_mark(IoMessage
*self
)
257 IoObject_shouldMarkIfNonNull(DATA(self
)->name
);
259 if (DATA(self
)->args
)
261 LIST_FOREACH(DATA(self
)->args
, i
, v
, IoObject_shouldMark(v
));
264 IoObject_shouldMarkIfNonNull(DATA(self
)->cachedResult
);
265 IoObject_shouldMarkIfNonNull((IoObject
*)DATA(self
)->next
);
266 IoObject_shouldMarkIfNonNull((IoObject
*)DATA(self
)->label
);
269 void IoMessage_free(IoMessage
*self
)
271 if (DATA(self
)->args
)
273 List_free(DATA(self
)->args
);
276 io_free(IoObject_dataPointer(self
));
279 List
*IoMessage_args(IoMessage
*self
)
281 return DATA(self
)->args
;
284 void IoMessage_cachedResult_(IoMessage
*self
, IoObject
*v
)
286 DATA(self
)->cachedResult
= v
? IOREF(v
) : NULL
;
289 void IoMessage_label_(IoMessage
*self
, IoSymbol
*ioSymbol
) /* sets label for children too */
291 DATA(self
)->label
= IOREF(ioSymbol
);
292 List_do_with_(DATA(self
)->args
, (ListDoWithCallback
*)IoMessage_label_
, ioSymbol
);
294 if (DATA(self
)->next
)
296 IoMessage_label_(DATA(self
)->next
, ioSymbol
);
300 int IoMessage_rawLineNumber(IoMessage
*self
)
302 return DATA(self
)->lineNumber
;
305 void IoMessage_rawSetLineNumber_(IoMessage
*self
, int n
)
307 DATA(self
)->lineNumber
= n
;
310 void IoMessage_rawSetCharNumber_(IoMessage
*self
, int n
)
312 //DATA(self)->charNumber = n;
315 int IoMessage_rawCharNumber(IoMessage
*self
)
317 return 0; //DATA(self)->charNumber;
320 List
*IoMessage_rawArgList(IoMessage
*self
)
322 return DATA(self
)->args
;
325 unsigned char IoMessage_isNotCached(IoMessage
*self
)
327 return !(DATA(self
)->cachedResult
);
330 unsigned char IoMessage_needsEvaluation(IoMessage
*self
)
332 List
*args
= DATA(self
)->args
;
333 int a
= List_detect_(args
, (ListDetectCallback
*)IoMessage_isNotCached
) != NULL
;
340 if (DATA(self
)->next
&& IoMessage_needsEvaluation(DATA(self
)->next
))
348 void IoMessage_addCachedArg_(IoMessage
*self
, IoObject
*v
)
350 IoMessage
*m
= IoMessage_new(IOSTATE
);
351 IoMessage_cachedResult_(m
, v
);
352 IoMessage_addArg_(self
, m
);
355 void IoMessage_setCachedArg_to_(IoMessage
*self
, int n
, IoObject
*v
)
359 while (!(arg
= List_at_(DATA(self
)->args
, n
)))
361 IoMessage_addArg_(self
, IoMessage_new(IOSTATE
));
364 IoMessage_cachedResult_(arg
, v
);
367 void IoMessage_setCachedArg_toInt_(IoMessage
*self
, int n
, int anInt
)
369 // optimized to avoid creating a number unless necessary
371 IoMessage
*arg
= NULL
;
373 while (!(arg
= List_at_(DATA(self
)->args
, n
)))
375 List_append_(DATA(self
)->args
, IOREF(IoMessage_new(IOSTATE
)));
378 DATA(arg
)->cachedResult
= IOREF(IONUMBER(anInt
));
381 IoObject
*IoMessage_lineNumber(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
384 docSlot("lineNumber",
385 "Returns the line number of the message. The charcter number
386 is typically the line number in the source text from with the message was read. ")
389 return IONUMBER(DATA(self
)->lineNumber
);
392 IoObject
*IoMessage_setLineNumber(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
395 docSlot("setLineNumber(aNumber)", "Sets the line number of the message. Returns self.")
398 DATA(self
)->lineNumber
= IoMessage_locals_intArgAt_(m
, locals
, 0);
402 IoObject
*IoMessage_characterNumber(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
405 docSlot("characterNumber",
406 "Returns the message character number. The charcter number is typically
407 the beggining character index in the source text from with the message was read. ")
411 //return IONUMBER(DATA(self)->charNumber);
414 IoObject
*IoMessage_setCharacterNumber(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
417 docSlot("setCharacterNumber(aNumber)",
418 "Sets the character number of the message. Returns self.")
421 //DATA(self)->charNumber = IoMessage_locals_intArgAt_(m , locals, 0);
425 IoObject
*IoMessage_label(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
429 "Returns the message label. The label is typically set the the
430 name of the file from which the source code for the message was read.")
433 return DATA(self
)->label
;
436 IoObject
*IoMessage_setLabel(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
439 docSlot("setLabel(aString)", "Sets the label of the message and its children. Returns self.")
442 IoMessage_label_(self
, IoMessage_locals_symbolArgAt_(m
, locals
, 0));
446 // --- perform --------------------------------------------------------
448 IoObject
*IoMessage_doInContext(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
451 docSlot("doInContext(anObject, locals)", "Evaluates the receiver in the context of anObject. ")
454 IoObject
*context
= IoMessage_locals_valueArgAt_(m
, (IoObject
*)locals
, 0);
455 if (IoMessage_argCount(m
) >= 2)
457 locals
= IoMessage_locals_valueArgAt_(m
, (IoObject
*)locals
, 1);
461 // Default to using the context as the locals so that the common case of,
462 // call argAt(2) doInContext(call sender) is easier.
465 return IoMessage_locals_performOn_(self
, locals
, context
);
468 //#define IO_DEBUG_STACK
470 IoObject
*IoMessage_locals_performOn_(IoMessage
*self
, IoObject
*locals
, IoObject
*target
)
472 IoState
*state
= IOSTATE
;
474 IoObject
*result
= target
;
475 //IoObject *semicolonSymbol = state->semicolonSymbol;
482 //printf("%s %i\n", CSTRING(IoMessage_name(m)), state->stopStatus);
483 //printf("%s\n", CSTRING(IoMessage_name(m)));
486 if(md
->name
== state
->semicolonSymbol
)
492 result
= md
->cachedResult
; // put it on the stack?
496 char *s = CSTRING(DATA(m)->name);
498 if (strcmp(s, "clone") == 0)
500 printf("found '%s'\n", s);
507 IoState_pushRetainPool(state
);
508 #ifdef IOMESSAGE_INLINE_PERFORM
509 if(IoObject_tag(target
)->performFunc
== NULL
)
511 result
= IoObject_perform(target
, locals
, m
);
515 result
= IoObject_tag(target
)->performFunc(target
, locals
, m
);
518 result
= IoObject_tag(target
)->performFunc(target
, locals
, m
);
520 IoState_popRetainPoolExceptFor_(state
, result
);
523 //IoObject_freeIfUnreferenced(target);
526 if (state
->stopStatus
!= MESSAGE_STOP_STATUS_NORMAL
)
528 return state
->returnValue
;
530 result = state->returnValue;
534 //IoState_stackRetain_(state, result);
537 printf("IoBlock no result!\n");
542 } while (m
= md
->next
);
547 // getting arguments ---------------------------
549 int IoMessage_argCount(IoMessage
*self
)
551 return List_size(DATA(self
)->args
);
554 void IoMessage_assertArgCount_receiver_(IoMessage
*self
, int n
, IoObject
*receiver
)
556 if (List_size(DATA(self
)->args
) < n
)
558 IoState_error_(IOSTATE
, self
, "[%s %s] requires %i arguments\n",
559 IoObject_name(receiver
), CSTRING(DATA(self
)->name
), n
);
563 void IoMessage_locals_numberArgAt_errorForType_(IoMessage
*self
,
566 const char *typeName
)
568 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
569 IoState_error_(IOSTATE
, self
, "argument %i to method '%s' must be a %s, not a '%s'",
570 n
, CSTRING(DATA(self
)->name
), typeName
, IoObject_name(v
));
573 IoObject
*IoMessage_locals_numberArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
575 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
579 IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "Number");
585 int IoMessage_locals_intArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
587 return IoNumber_asInt(IoMessage_locals_numberArgAt_(self
, locals
, n
));
590 long IoMessage_locals_longArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
592 return IoNumber_asLong(IoMessage_locals_numberArgAt_(self
, locals
, n
));
595 size_t IoMessage_locals_sizetArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
597 long v
= IoNumber_asLong(IoMessage_locals_numberArgAt_(self
, locals
, n
));
601 IoState_error_(IOSTATE
, self
, "IoMessage_locals_sizetArgAt_ attempt to get size_t value from negative number %i", v
);
608 double IoMessage_locals_doubleArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
610 return IoNumber_asDouble(IoMessage_locals_numberArgAt_(self
, locals
, n
));
613 float IoMessage_locals_floatArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
615 return (float)IoNumber_asDouble(IoMessage_locals_numberArgAt_(self
, locals
, n
));
618 char *IoMessage_locals_cStringArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
620 return CSTRING(IoMessage_locals_symbolArgAt_(self
, locals
, n
));
623 IoObject
*IoMessage_locals_seqArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
625 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
629 IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "Sequence");
635 IoObject
*IoMessage_locals_valueAsStringArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
637 return IoObject_asString_(IoMessage_locals_valueArgAt_(self
, locals
, n
), self
);
640 IoObject
*IoMessage_locals_symbolArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
642 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
646 IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "Sequence");
649 return IoSeq_rawAsSymbol(v
);
652 IoObject
*IoMessage_locals_mutableSeqArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
654 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
656 if (!ISMUTABLESEQ(v
))
658 IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "mutable Sequence");
664 IoObject
*IoMessage_locals_blockArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
666 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
667 if (!ISBLOCK(v
)) IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "Block");
671 IoObject
*IoMessage_locals_dateArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
673 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
674 if (!ISDATE(v
)) IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "Date");
678 IoObject
*IoMessage_locals_messageArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
680 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
681 if (!ISMESSAGE(v
)) IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "Message");
685 IoObject
*IoMessage_locals_listArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
687 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
688 if (!ISLIST(v
)) IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "List");
692 IoObject
*IoMessage_locals_mapArgAt_(IoMessage
*self
, IoObject
*locals
, int n
)
694 IoObject
*v
= IoMessage_locals_valueArgAt_(self
, locals
, n
);
695 if (!ISMAP(v
)) IoMessage_locals_numberArgAt_errorForType_(self
, locals
, n
, "Map");
701 void IoMessage_print(IoMessage
*self
)
703 UArray
*ba
= IoMessage_description(self
);
705 //printf("%s\n", UArray_asCString(ba));
706 IoState_print_(IOSTATE
, UArray_asCString(ba
));
710 void IoMessage_printWithReturn(IoMessage
*self
)
712 IoMessage_print(self
);
713 IoState_print_(IOSTATE
, "\n");
716 UArray
*IoMessage_description(IoMessage
*self
)
718 UArray
*ba
= UArray_new();
719 IoMessage_appendDescriptionTo_follow_(self
, ba
, 1);
723 UArray
*IoMessage_descriptionJustSelfAndArgs(IoMessage
*self
)
725 UArray
*ba
= UArray_new();
726 IoMessage_appendDescriptionTo_follow_(self
, ba
, 0);
730 IoObject
*IoMessage_asString(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
733 docSlot("asString", "Same as code().")
736 return IoMessage_descriptionString(self
, locals
, m
);
739 void IoMessage_appendDescriptionTo_follow_(IoMessage
*self
, UArray
*ba
, int follow
)
742 IoMessageData
*data
= DATA(self
);
744 UArray_appendCString_(ba
, CSTRING(data
->name
));
747 int i
, max
= List_size(DATA(self
)->args
);
751 UArray_appendCString_(ba
, "(");
753 for (i
= 0; i
< max
; i
++)
755 IoMessage
*arg
= List_at_(DATA(self
)->args
, i
);
756 IoMessage_appendDescriptionTo_follow_(arg
, ba
, 1);
760 UArray_appendCString_(ba
, ", ");
764 UArray_appendCString_(ba
, ")");
773 if (DATA(self
)->next
&& DATA(self
)->name
!= IOSTATE
->semicolonSymbol
) UArray_appendCString_(ba
, " ");
774 if (DATA(self
)->name
== IOSTATE
->semicolonSymbol
) UArray_appendCString_(ba
, "\n");
775 } while (self
= DATA(self
)->next
);
778 // methods ---------------------------------------------------
780 IoObject
*IoMessage_clone(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
783 docSlot("clone", "Returns a Message that is a deep copy of the receiver. ")
786 return IoMessage_deepCopyOf_(self
);
789 IoObject
*IoMessage_protoName(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
792 docSlot("name", "Returns the name of the receiver. ")
795 IoObject
*s
= DATA(self
)->name
;
799 IoObject
*IoMessage_protoSetName(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
802 docSlot("setName(aString)", "Sets the name of the receiver. Returns self. ")
805 DATA(self
)->name
= IOREF(IoMessage_locals_symbolArgAt_(m
, locals
, 0));
806 //IoMessage_cacheIfPossible(self);
810 IoObject
*IoMessage_descriptionString(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
814 "Returns a String containing a decompiled code representation of the receiver.")
817 UArray
*ba
= IoMessage_description(self
); /* me must io_free the returned UArray */
818 return IoState_symbolWithUArray_copy_(IOSTATE
, ba
, 0);
822 // next -------------------------
824 IoObject
*IoMessage_next(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
828 "Returns the next message in the message chain or nil if there is no next message. ")
831 return DATA(self
)->next
? (IoObject
*)DATA(self
)->next
: IONIL(self
);
834 IoMessage
*IoMessage_rawNext(IoMessage
*self
)
836 return DATA(self
)->next
;
839 IoObject
*IoMessage_setNext(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
842 docSlot("setNextMessage(aMessageOrNil)",
843 "Sets the next message in the message chain to a deep copy of
844 aMessage or it removes the next message if aMessage is nil. ")
847 IoObject
*v
= IoMessage_locals_valueArgAt_(m
, locals
, 0);
848 IOASSERT(ISMESSAGE(v
) || ISNIL(v
), "argument must be Message or Nil");
855 IoMessage_rawSetNext(self
, v
);
859 void IoMessage_rawSetNext(IoMessage
*self
, IoMessage
*m
)
861 DATA(self
)->next
= m
? IOREF(m
) : NULL
;
863 #ifdef IOMESSAGE_HASPREV
867 DATA(m
)->previous
= self
;
872 IoObject
*IoMessage_isEOL(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
875 docSlot("isEndOfLine", "Returns true if the message marks the end of the line. A ';' message.")
878 return IOBOOL(self
, IoMessage_rawIsEOL(self
));
881 int IoMessage_rawIsEOL(IoMessage
*self
)
883 return IoMessage_name(self
) == IOSTATE
->semicolonSymbol
;
886 IoMessage
*IoMessage_rawNextIgnoreEOLs(IoMessage
*self
)
888 IoMessage
*next
= IoMessage_rawNext(self
);
890 while (next
&& IoMessage_rawIsEOL(next
))
892 next
= IoMessage_rawNext(next
);
898 IoObject
*IoMessage_nextIgnoreEOLs(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
901 docSlot("nextIgnoreEndOfLines",
902 "Returns the next message in the message chain which is not an EndOfLine or nil if there is no next message. ")
905 IoMessage
*next
= IoMessage_rawNextIgnoreEOLs(self
);
906 return next
? next
: IONIL(self
);
909 IoMessage
*IoMessage_rawLastBeforeEOL(IoMessage
*self
)
911 IoMessage
*last
= self
;
914 while (next
= IoMessage_rawNext(last
))
916 if (IoMessage_rawIsEOL(next
))
926 IoObject
*IoMessage_lastBeforeEOL(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
929 docSlot("lastBeforeEndOfLine",
930 "Returns the last message in the chain before the EndOfLine or nil.")
933 return IoMessage_rawLastBeforeEOL(self
);
936 IoMessage
*IoMessage_rawLast(IoMessage
*self
)
938 IoMessage
*last
= self
;
941 while (next
= IoMessage_rawNext(last
))
949 IoObject
*IoMessage_last(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
953 "Returns the last message in the chain.")
956 return IoMessage_rawLast(self
);
959 // previous -------------------------
961 IoObject
*IoMessage_previous(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
965 "Returns the previous message in the message chain or Nil if there is no previous message. ")
967 #ifdef IOMESSAGE_HASPREV
968 return DATA(self
)->previous
? (IoObject
*)DATA(self
)->previous
: IONIL(self
);
974 IoMessage
*IoMessage_rawPrevious(IoMessage
*self
)
976 #ifdef IOMESSAGE_HASPREV
977 return DATA(self
)->previous
;
983 IoObject
*IoMessage_setPrevious(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
986 docSlot("setPrevious(aMessageOrNil)",
987 "Sets the previous message in the message chain to a deep copy of
988 aMessage or it removes the previous message if aMessage is Nil. ")
991 IoObject
*v
= IoMessage_locals_valueArgAt_(m
, locals
, 0);
992 IOASSERT(ISMESSAGE(v
) || ISNIL(v
), "argument must be Message or Nil");
999 IoMessage_rawSetPrevious(self
, v
);
1004 void IoMessage_rawSetPrevious(IoMessage
*self
, IoMessage
*m
)
1006 #ifdef IOMESSAGE_HASPREV
1007 DATA(self
)->previous
= m
? IOREF(m
) : NULL
;
1011 DATA(m
)->next
= self
;
1016 // ------------------------------------------------------
1018 IoObject
*IoMessage_argAt(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1021 docSlot("argAt(indexNumber)",
1022 "Returns Message object for the specified argument or Nil if none exists.")
1025 int index
= IoNumber_asInt(IoMessage_locals_numberArgAt_(m
, locals
, 0));
1026 IoObject
*v
= List_at_(DATA(self
)->args
, index
);
1027 return v
? v
: IONIL(self
);
1030 IoObject
*IoMessage_arguments(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1033 docSlot("arguments",
1034 "Returns a list of the message objects that act as the
1035 receiver's arguments. Modifying this list will not alter the actual
1036 list of arguments. Use the arguments_() method to do that. ")
1039 IoList
*argsList
= IoList_new(IOSTATE
);
1040 IoList_rawAddBaseList_(argsList
, DATA(self
)->args
);
1044 IoObject
*IoMessage_setArguments(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1047 docSlot("setArguments(aListOfMessages)",
1048 "Sets the arguments of the receiver to deep copies of
1049 those contained in aListOfMessages. Returns self.")
1052 IoList
*ioList
= IoMessage_locals_listArgAt_(m
, locals
, 0);
1053 List
*newArgs
= IoList_rawList(ioList
);
1055 List_removeAll(DATA(self
)->args
);
1057 LIST_FOREACH(newArgs
, i
, argMessage
,
1059 if (!ISMESSAGE((IoMessage
*)argMessage
))
1061 IoState_error_(IOSTATE
, m
, "arguments_() takes a list containing only Message objects");
1064 List_append_(DATA(self
)->args
, IOREF((IoMessage
*)argMessage
));
1070 IoObject
*IoMessage_appendArg(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1073 docSlot("appendArg(aMessage)",
1074 """Adds aMessage to the argument list of receiver. Examples,
1076 Io> message(a) appendArg(message(b))
1079 Io> message(a(1,2)) appendArg(message(3))
1084 IoMessage
*msg
= IoMessage_locals_messageArgAt_(m
, locals
, 0);
1085 IoMessage_addArg_(self
, msg
);
1089 IoObject
*IoMessage_appendCachedArg(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1092 docSlot("appendCachedArg(aValue)",
1093 """Adds aValue to the argument list of receiver as a cachedResult.""")
1096 IoObject
*v
= IoMessage_locals_valueArgAt_(m
, locals
, 0);
1097 IoMessage_addCachedArg_(self
, v
);
1101 IoObject
*IoMessage_argCount_(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1105 """Returns the number of arguments this message has. A faster way to do, msg arguments size. Examples,
1107 Io> message(a(1,2,3)) argCount
1110 Io> message(a) argCount
1115 return IONUMBER(IoMessage_argCount(self
));
1118 IoObject
*IoMessage_fromString(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1121 docSlot("fromString(aString)",
1122 "Returns a new Message object for the compiled(but not executed)
1123 result of aString. ")
1126 IoSymbol
*string
= IoMessage_locals_symbolArgAt_(m
, locals
, 0);
1127 IoSymbol
*label
= DATA(m
)->label
;
1129 if (IoMessage_argCount(m
) > 1)
1131 label
= IoMessage_locals_symbolArgAt_(m
, locals
, 1);
1134 return IoMessage_newFromText_labelSymbol_(IOSTATE
, CSTRING(string
), label
);
1137 IoObject
*IoMessage_cachedResult(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1140 docSlot("cachedResult",
1141 "Returns the cached result of the Message or Nil if there is none.")
1144 return (DATA(self
)->cachedResult
? DATA(self
)->cachedResult
: IONIL(self
));
1147 IoObject
*IoMessage_setCachedResult(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1150 docSlot("setCachedResult(anObject)",
1151 "Sets the cached result of the message. Returns self.")
1154 DATA(self
)->cachedResult
= IOREF(IoMessage_locals_valueArgAt_(m
, locals
, 0));
1158 IoObject
*IoMessage_removeCachedResult(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1161 docSlot("removeCachedResult", "Removes the cached result of the Message.")
1164 DATA(self
)->cachedResult
= NULL
;
1168 IoObject
*IoMessage_hasCachedResult(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1171 docSlot("hasCachedResult",
1172 "Returns true if there is a cached result. Nil is a valid cached result.")
1175 return IOBOOL(self
, DATA(self
)->cachedResult
== NULL
);
1178 IoObject
*IoMessage_argsEvaluatedIn(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1181 docSlot("argsEvaluatedIn(anObject)",
1182 "Returns a List containing the argument messages evaluated in the
1183 context of anObject. ")
1186 IoObject
*context
= IoMessage_locals_valueArgAt_(m
, locals
, 0);
1187 IoList
*args
= IoList_new(IOSTATE
);
1190 for (i
= 0; i
< List_size(DATA(self
)->args
); i
++)
1192 IoObject
*arg
= IoMessage_locals_valueArgAt_(self
, context
, i
);
1193 IoList_rawAppend_(args
, arg
);
1198 IoObject
*IoMessage_evaluatedArgs(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1201 docSlot("evaluatedArgs",
1202 "Returns a List containing the argument messages evaluated in the context.")
1205 IoList
*args
= IoList_new(IOSTATE
);
1208 for (i
= 0; i
< List_size(DATA(self
)->args
); i
++)
1210 IoObject
*arg
= IoMessage_locals_valueArgAt_(self
, locals
, i
);
1211 IoList_rawAppend_(args
, arg
);
1217 // ------------------------------
1220 IoSymbol *IoMessage_name(IoMessage *self)
1222 return DATA(self)->name;
1226 IoSymbol
*IoMessage_rawLabel(IoMessage
*self
)
1228 return DATA(self
)->label
;
1231 List
*IoMessage_rawArgs(IoMessage
*self
)
1233 return DATA(self
)->args
;
1236 IoMessage
*IoMessage_rawArgAt_(IoMessage
*self
, int n
)
1238 IoMessage
*result
= List_at_(DATA(self
)->args
, n
);
1239 IoState_stackRetain_(IOSTATE
, result
);
1243 void IoMessage_addArg_(IoMessage
*self
, IoMessage
*m
)
1245 List_append_(DATA(self
)->args
, IOREF(m
));
1248 // -------------------------------
1250 UArray
*IoMessage_asMinimalStackEntryDescription(IoMessage
*self
)
1252 IoSymbol
*name
= IoMessage_name(self
);
1253 IoSymbol
*label
= IoMessage_rawLabel(self
);
1254 int lineNumber
= IoMessage_rawLineNumber(self
);
1255 return UArray_newWithFormat_("%s:%i %s", CSTRING(label
), lineNumber
, CSTRING(name
));
1258 void IoMessage_foreachArgs(IoMessage
*self
,
1260 IoSymbol
**indexSlotName
,
1261 IoSymbol
**valueSlotName
,
1262 IoMessage
**doMessage
)
1266 IoMessage_assertArgCount_receiver_(self
, 2, receiver
);
1268 if (IoMessage_argCount(self
) > 2)
1270 *indexSlotName
= IoMessage_name(IoMessage_rawArgAt_(self
, 0));
1275 *indexSlotName
= NULL
; //IONIL(self);
1279 *valueSlotName
= IoMessage_name(IoMessage_rawArgAt_(self
, 0 + offset
));
1280 *doMessage
= IoMessage_rawArgAt_(self
, 1 + offset
);
1283 IoMessage
*IoMessage_asMessageWithEvaluatedArgs(IoMessage
*self
, IoObject
*locals
, IoMessage
*m
)
1285 IoState
*state
= IOSTATE
;
1286 IoMessage
*sendMessage
;
1287 int i
, max
= IoMessage_argCount(self
);
1288 IoObject
*context
= locals
;
1290 if (IoMessage_argCount(m
) > 0)
1292 context
= IoMessage_locals_valueArgAt_(m
, locals
, 0);
1295 if (IoMessage_needsEvaluation(self
))
1297 sendMessage
= IoMessage_newWithName_(state
, IoMessage_name(self
));
1304 for (i
= 0; i
< max
; i
++)
1306 IoMessage
*arg
= IoMessage_rawArgAt_(self
, i
);
1307 IoObject
*result
= IoMessage_locals_performOn_(arg
, context
, context
);
1308 IoMessage_setCachedArg_to_(sendMessage
, i
, result
);