new object $reads_lines: $utilities; var $root inited = 1; var $reads_lines line_buffer = 0; var $reads_lines end_strings = 0; var $reads_lines parser = 0; var $reads_lines task = 0; public method .tell() { arg @ignored; }; public method .parse_line() { arg line; // If a parser is defined, don't try to command-match, just pass it through to the parser if (parser) { return .(parser)(line); } else { return (> pass(line) <); } }; public method .read_lines() { arg @args; var prompt, ret; if (parser) { throw(~busy, "Already involved with something else."); } prompt = (| args[1] |) || "Receiving input. Enter \".\" to finish or \"@abort\" to abort."; end_strings = [((| args[2] |) || "."), ((| args[3] |) || "@abort")]; line_buffer = []; parser = '_read_line; task = task_id(); if (prompt) { .tell(prompt); } // Now, suspend the task. ._read_line will resume it when it's done catch any { (> suspend() <); } with { parser = 0; rethrow(error()); } parser = 0; if (line_buffer == 0) { .tell("** Aborted **; Text thrown away."); } return line_buffer; }; private method ._read_line() { arg line; var pos; if ((pos = (line in end_strings))) { if (pos > 1) { line_buffer = 0; } $scheduler.resume(task); } else { line_buffer += [line]; } };