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 programmer inited 0
var programmer programming 0
var programmer program_buf 0
method init
arg ancestors;
(> pass(ancestors) <);
if (definer() in ancestors) {
programming = 0;
program_buf = 0;
}
.
eval
.initialize();
.set_name("Hacker");
.add_command(";*", 'pattern, 'eval_cmd);
.add_command("@program * on *", 'template, 'program_cmd);
.add_command("@show *", 'template, 'show_cmd);
.add_command("@params *", 'template, 'params_cmd);
.add_command("@methods *", 'template, 'methods_cmd);
.add_command("@verbs *", 'template, 'verbs_cmd);
.add_command("@list * on *", 'template, '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 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("--> " + toliteral(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(name) + "() (defined on ";
header = header + toliteral(anc) + "):";
.tell(header);
.tell(code);
.