parent programmer
object admin

var root name 'admin

method init_admin
    if (caller() != $root)
        throw(~perm, "Caller is not $root.");
    $sys.new_admin();
.

method uninit_admin
    if (caller() != $root)
        throw(~perm, "Caller is not $root.");
    $sys.admin_going_away();
.

eval
    .initialize();
    .add_command("definer * this * eval *", 'eval_as_to_cmd);
    .add_command("as * eval *", 'eval_as_cmd);
.

method eval_as_cmd
    arg dummy1, objname, dummy2, line;
    var obj, result;

    if (sender() != this())
        throw(~perm, "Sender is not this.");
    catch ~objnf {
        obj = .match_environment(objname);
    } with handler {
        .tell("I don't see \"" + objname + "\" here.");
        return;
    }
    result = obj.eval([line]);
    if (result[1] == 'errors)
        .tell(result[2]);
    else
        .tell("--> " + $data.unparse(result[2]));
.

method eval_as_to_cmd
    arg dummy1, objname, dummy2, targetname, dummy3, line;
    var obj, target, result;

    if (sender() != this())
        throw(~perm, "Sender is not this.");
    catch ~objnf {
        obj = .match_environment(objname);
        target = .match_environment(targetname);
    } with handler {
        .tell("I don't see \"" + objname + "\" here.");
        return;
    }
    result = obj.eval([line], target);
    if (result[1] == 'errors)
        .tell(result[2]);
    else
        .tell("--> " + $data.unparse(result[2]));
.