IO_METHOD(IoNumber, repeat) { /*doc Number repeat(optionalIndex, expression) Evaluates message a number of times that corresponds to the receivers integer value. This is significantly faster than a for() or while() loop. */ IoMessage_assertArgCount_receiver_(m, 1, self); { IoState *state = IOSTATE; IoSymbol *indexSlotName; IoMessage *doMessage; double i, max = CNUMBER(self); IoObject *result = IONIL(self); if(IoMessage_argCount(m) > 1) { indexSlotName = IoMessage_name(IoMessage_rawArgAt_(m, 0)); doMessage = IoMessage_rawArgAt_(m, 1); } else { indexSlotName = 0; doMessage = IoMessage_rawArgAt_(m, 0); } IoState_pushRetainPool(state); for (i = 0; i < max; i ++) { /* if (result != locals && result != self) { IoState_immediatelyFreeIfUnreferenced_(state, result); } */ IoState_clearTopPool(state); if (indexSlotName) { IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i)); } result = IoMessage_locals_performOn_(doMessage, locals, locals); if (IoState_handleStatus(IOSTATE)) { break; } } IoState_popRetainPoolExceptFor_(IOSTATE, result); return result; } }
IO_METHOD(IoFile, foreachLine) { /*doc File foreachLine(optionalLineNumber, line, message) For each line, set index to the line number of the line and line and execute aMessage. Example usage: <pre> aFile foreachLine(i, v, writeln("Line ", i, ": ", v)) aFile foreach(v, writeln("Line: ", v)) </pre> */ IoObject *result; IoSymbol *indexSlotName, *lineSlotName; IoMessage *doMessage; IoObject *newLine; int i = 0; IoState *state; IoFile_assertOpen(self, locals, m); IoMessage_foreachArgs(m, self, &indexSlotName, &lineSlotName, &doMessage); result = IONIL(self); state = IOSTATE; IoState_pushRetainPool(state); for (;;) { IoState_clearTopPool(state); newLine = IoFile_readLine(self, locals, m); if (ISNIL(newLine)) { break; } if (indexSlotName) { IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i)); } IoObject_setSlot_to_(locals, lineSlotName, newLine); result = IoMessage_locals_performOn_(doMessage, locals, locals); if (IoState_handleStatus(IOSTATE)) { break; } i ++; } IoState_popRetainPool(state); return result; }
IO_METHOD(IoFile, readLines) { /*doc File readLines Returns list containing all lines in the file. */ IoState *state = IOSTATE; if (!DATA(self)->stream) { IoFile_openForReading(self, locals, m); } IoFile_assertOpen(self, locals, m); { IoList *lines = IoList_new(state); IoObject *newLine; IoState_pushRetainPool(state); for (;;) { IoState_clearTopPool(state); newLine = IoFile_readLine(self, locals, m); if (ISNIL(newLine)) { break; } IoList_rawAppend_(lines, newLine); } IoState_popRetainPool(state); return lines; } }