new object $user: $reads_lines, $has_commands; var $root inited = 1; var $has_commands shortcuts = #[["\"", 'say_cmd], [":", 'emote_cmd], [";", 'eval_cmd]]; var $has_commands commands = #[["say", 'say_cmd], ["emote", 'emote_cmd], ["@program", 'program_cmd], ["feh", 'feh_cmd], ["@eval", 'eval_cmd], ["@edit", 'edit_cmd]]; var $user name = "the Generic User Object"; var $user connection = 0; var $user eval_offset = 0; public method .new_connection() { arg @args; sender().write("Welcome to ColdTurkey 0.0!"); return (> pass(@args) <); }; public method .init() { arg conn, username; connection = conn; name = username; }; public method .name() { return name; }; protected method .say_cmd() { arg cmdstr, cmd, what; var line; line = .name() + " says, \"" + what + "\""; $user.children().mmap('tell, line); }; protected method .emote_cmd() { arg cmdstr, cmd, what; var line; if (what[1] == ":") { line = .name() + substr(what, 2); } else { line = .name() + " " + what; } $user.children().mmap('tell, line); }; public method .tell() { arg what; var i; switch (type(what)) { case 'string: connection.write(what); case 'list: for i in (what) { .tell(i); } case 'symbol: connection.write(tostr(what)); } }; protected method .feh_cmd() { arg cmdstr, com, @whatever; .debug(.read_lines()); }; // // These are programmer commands // private method ._obj_meth() { arg methref; switch (methref[1]) { case "$": methref = methref.subrange(2); case ".": methref = .objname().subrange(2) + methref; // Maybe put in something about objnums here. } return methref.explode(".").mmap('to_symbol) + [methref]; }; protected method .edit_cmd() { arg cmdstr, com, methref; var obj, meth, code; [obj, meth, methref] = ._obj_meth(methref); // verify what we have is correct catch ~namenf, ~methodnf { obj = lookup(obj); } with { return traceback()[1][2]; } // List the method out as an MCP edit command, woohoo code = (| obj.list_method(meth) |) || []; return ["#$# edit name: $" + methref + "() upload: @program $" + methref] + code + ["."]; }; protected method .program_cmd() { arg cmdstr, com, methref; var obj, meth, code, errs; [obj, meth, methref] = ._obj_meth(methref); // verify what we have is correct catch ~namenf { obj = lookup(obj); } with { return traceback()[1][2]; } // Read in the text if ((code = .read_lines("Programing $" + methref + "(). Enter \".\" to finish, \"@abort\" to abort.")) == 0) { return; } // Now try to add the method catch any { if ((errs = obj.add_method(code, meth))) { return errs; } if (0) { (> ref[3].set_method_flags(meth, fl) <); (> ref[3].set_method_access(meth, acc) <); if ((line = (> $code_lib.verify_code(code, meth, warn) <))) { .tell(line); } } return "Method " + methref + "() compiled"; } with { return traceback()[1][2]; } }; public method .parse_line() { arg line; var ret; set_user(); catch any { ret = pass(line); } with { .tell($parse_lib.traceback(traceback())); } return ret; }; protected method .eval_cmd() { arg cmdstr, com, str; var result, adjust, vars, v, evalp, times, line, reg, obj, definer, ref, debug; // Taken from tCD vars = "me"; v = "me=" + this() + ";"; // check for debug flags if ((reg = str.regexp("^(trace|debug|profile) *;*(.*)$"))) { debug = tosym(reg[1]); str = reg[2]; } else { debug = 0; } // who are we evaluating as? if ((reg = regexp(str, "^ *as +([^; ]+)"))) { ref = $parse_lib.ref(reg[1]); obj = ref[2]; definer = ref[3]; str = strsed(str, "^ *as +([^; ]+)[ ;]+", ""); if (!obj.is(definer)) return obj + " isn't a child of " + definer; } else { obj = (definer = this()); } // are we just adjusting our offset? if (!str) { result = (> .evaluate("var " + vars + ";" + v + "return (> 1 <);", obj, definer, 'no_offset) <); result = replace(result[1], 1, result[1][1] - 1); if (eval_offset) line = strfmt("adjusted by %s ticks and %s.%6{0}r seconds.", eval_offset[1] - result[1], eval_offset[2] - result[2], abs(eval_offset[3] - result[3])); else line = strfmt("set to %s ticks and %s.%6{0}r seconds.", @result); eval_offset = result; return "Eval offset " + line; } // format it if (match_begin(str, "var") && (reg = regexp(str, "var ([^;]+)"))) { str = strsed(str, "var ([^;]+);", ""); str = "var " + vars + ", " + reg.join(",") + ";" + v + str; } else if ("return" in str) { str = "var " + vars + ";" + v + str; } else { str = strsed(str, " *;* *$", ""); str = "var " + vars + ";" + v + "return (> " + str + " <);"; } if (debug) { result = (> .evaluate(str, obj, definer, debug) <); if (! (| [times, result, debug] = result |)) { debug = 0; } } else { [times, result] = (> .evaluate(str, obj, definer) <); } // Display the errors, or the result. if (result[1] == 'errors) { .tell(result[2]); } else if (result[1] == 'traceback) { .tell($parse_lib.traceback(result[2])); line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]); if (times[2]) line += " (" + times[1] / times[2] + " ticks per second)"; return line + " ]"; } else { if (type(result[2]) == 'objnum) .tell("=> " + ((| result[2].namef('xref) |) || result[2])); else .tell("=> " + toliteral(result[2])); if (debug) .tell(debug); line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]); if (times[2]) line += " (" + times[1] / times[2] + " ticks per second)"; return line + " ]"; } // $#Edited: 11 Apr 97 03:12 $brad // $#Edited: 09 Jul 97 14:39 $user_bruce // $#Edited: 10 Dec 97 14:09 $brandon }; private method .evaluate() { arg str, obj, definer, @mode; var start, end, time, ticks, mtime, times1, times2, method, errs, trace, result, is_error; // Taken from tCD mode = mode ? mode[1] : 0; method = tosym("tmp_eval_" + time()); if ((errs = (> definer.add_method([str], method) <))) { if (mode) { return [[0, 0, 0], ['errors, errs, 0, 0], []]; } else { return [[0, 0, 0], ['errors, errs, 0, 0]]; } } catch any { if (mode in ['trace, 'profile]) { debug_callers(1); } else if (mode == 'debug) { debug_callers(2); } times1 = [tick(), time(), mtime()]; result = (> obj.(method)() <); times2 = [mtime(), time(), tick()]; trace = call_trace(); debug_callers(0); } with { times2 = [mtime(), time(), tick()]; result = traceback(); is_error = 1; debug_callers(0); } (| definer.del_method(method) |); // figure up the actual times time = times2[2] - times1[2]; ticks = times2[3] - times1[1]; if (times2[1] > times1[3]) { mtime = times2[1] - times1[3]; } else if (time) { mtime = time * 1000000 + (1000000 - times1[3]) + times2[1]; } else { mtime = 1000000 - times2[1] + times1[3]; } // offset it? if (eval_offset && mode != 'no_offset) { ticks -= eval_offset[1]; time -= eval_offset[2]; mtime -= eval_offset[3]; } if (trace) { return [[ticks, time, abs(mtime)], ['result, result], $code_lib.generate_debug_listing(trace, mode)]; } else { return [[ticks, time, abs(mtime)], [is_error ? 'traceback : 'result, result]]; } // $#Edited: 11 Apr 97 03:17 $brad // $#Edited: 03 Aug 97 14:34 $brad // $#Edited: 15 Aug 97 10:15 $brandon };