Generic Programmer Private methods: programming_line(str) Handle line in a program program_done() Handle end of program Comamnds: eval_cmd(s) Evaluate a string s program_cmd("@program", name, "on", obj) Start programming a method parent builder object programmer var root name 'programmer var programmer inited 0 var programmer programming 0 var programmer program_buf 0 method init_programmer if (caller() != $root) throw(~perm, "Caller is not $root."); programming = 0; program_buf = 0; . method uninit_programmer if (caller() != $root) throw(~perm, "Caller is not $root."); programming = 0; program_buf = 0; . eval .initialize(); .add_shortcut(";*", 'eval_cmd, ["eval", 1]); .add_command("eval *", 'eval_cmd); .add_command("@program * on *", 'program_cmd); .add_command("@show *", 'show_cmd); .add_command("@params *", 'params_cmd); .add_command("@methods *", 'methods_cmd); .add_command("@verbs *", 'verbs_cmd); .add_command("@list * on *", 'list_cmd); . method parse_command arg str; var err; if (!.is_owned_by(sender())) throw(~perm, "Sender not an owner."); // Catch errors and display a stack trace. catch any { if (programming) .programming_line(str); else return pass(str); } with handler { for err in (traceback()) .tell(err); } . method programming_line arg str; if (sender() != this() || caller() != definer()) throw(~perm, "Sender not this."); if (str == ".") .program_done(); else if (programming != 'ignore) program_buf = program_buf + [str]; . method program_done var errors; if (sender() != this() || caller() != definer()) throw(~perm, "Sender not this."); if (programming == 'ignore) { .tell("Finished ignoring input."); } else { catch ~perm { errors = programming[1].compile(program_buf, programming[2]); if (errors) .tell(errors); else .tell("Method compiled."); } with handler { .tell("You cannot program that object."); } } programming = 0; program_buf = 0; . method eval_cmd arg dummy1, s; var result; if (sender() != this()) throw(~perm, "Sender not this."); // Evaluate the line. if (s && s[1] == ";") result = .eval([substr(s, 2)]); else result = .eval(["return " + s + ";"]); // Display the errors, or the result. if (result[1] == 'errors) .tell(result[2]); else if (!s || s[1] != ";") .tell("--> " + $data.unparse(result[2])); . method program_cmd arg dummy1, name, dummy2, obj; if (sender() != this()) throw(~perm, "Sender not this."); // Find the object to program. catch ~objnf { obj = .match_environment(obj); } with handler { .tell("I don't see \"" + error_arg() + "\" here."); return; } if (!obj.is_owned_by(this())) { .tell("You can't program that object; ignoring text."); programming = 'ignore; return; } programming = [obj, tosym(name)]; program_buf = []; .tell("Enter text for method " + name + "."); . method show_cmd arg dummy1, name; var obj; if (sender() != this()) throw(~perm, "Sender not this."); catch ~objnf, ~perm { obj = .match_environment(name); .tell(obj.show()); } with handler { switch (error()) { case ~objnf: .tell("I don't see \"" + error_arg() + "\" here."); case ~perm: .tell("Permission denied."); } } . method params_cmd arg dummy1, name; var obj, params, i; if (sender() != this()) throw(~perm, "Sender not this."); catch ~objnf, ~perm { obj = .match_environment(name); params = obj.parameters(); } with handler { switch (error()) { case ~objnf: .tell("I don't see \"" + error_arg() + "\" here."); case ~perm: .tell("Permission denied."); } return; } .tell("Parameters:"); for i in (params) .tell(" " + tostr(i)); . method methods_cmd arg dummy1, name; var obj, methods, i; if (sender() != this()) throw(~perm, "Sender not this."); catch ~objnf, ~perm { obj = .match_environment(name); methods = obj.methods(); } with handler { switch (error()) { case ~objnf: .tell("I don't see \"" + error_arg() + "\" here."); case ~perm: .tell("Permission denied."); } return; } .tell("Methods:"); for i in (methods) .tell(" " + tostr(i)); . method verbs_cmd arg dummy1, name; var obj, verbs, i, info, str; if (sender() != this()) throw(~perm, "Sender not this."); // Find the object to show. catch ~objnf, ~perm { obj = .match_environment(name); verbs = obj.verb_templates(); } with handler { switch (error()) { case ~objnf: .tell("I don't see \"" + error_arg() + "\" here."); case ~perm: .tell("Permission denied."); } return; } .tell("Verbs:"); for i in (verbs) { str = " " + pad(i, 40) + " "; info = obj.local_verb_info(i); if (info[2] == 'remote) str = str + pad(tostr(info[1]), 20) + " (remote)"; else str = str + tostr(info[1]); .tell(str); } . method list_cmd arg dummy1, method, dummy2, name; var obj, anc, header, code; if (sender() != this()) throw(~perm, "Sender not this."); // Find the object to show. method = tosym(method); catch ~objnf, ~perm { obj = .match_environment(name); anc = obj.find_method(method); code = anc.list_method(method); } with handler { switch (error()) { case ~objnf: .tell("I don't see \"" + error_arg() + "\" here."); case ~perm: .tell("Permission denied."); } return; } // List the method. header = toliteral(obj) + "." + tostr(method) + "() (defined on "; header = header + toliteral(anc) + "):"; .tell(header); .tell(code); .