parent $root_evaluator
object $base_evaluator
var $root dbref 'base_evaluator
var $root child_index 1
var $root fertile 0
var $root manager $base_evaluator
var $root owned [$base_evaluator]
var $root owners [$]
var $root writable []
var $root readable ['parameters, 'methods, 'code]
var $prep_evaluator append_str "_stmt"
var $root inited 1
var $has_messages message_info #[["errors.english.usage", [$base_evaluator, $compile_evaluator, $uncompile_evaluator, []]], ["errors.english.usage.list", [$base_evaluator, $compile_evaluator, $uncompile_evaluator, []]]]
var $has_messages messages #[[$base_evaluator, #[["errors.english.usage", <$ctext_class, ['text_stmt, [['error_stmt, [['text_stmt, [['string_type, "Usage is "], ['char_type, "lp"], ['string_type, "english <list> [<empty> [<and> [<sep>]]])"]]]]]]]>], ["errors.english.usage.list", <$ctext_class, ['text_stmt, [['error_stmt, [['string_type, "The first argument to english must be a list."]]]]]>]]]]
method name_stmt
arg vars, args;
var name, article, n;
//args[1] is a dbref, or list of dbrefs
//args[2] is the article. defaults to 'indef
if (((args[1])[1]) == 'dbref_type) {
name = args[1];
} else {
vars = ._eval_ctext(vars, args[1]);
name = vars['result];
}
if ((listlen(args) > 1) && (((args[2])[1]) != 'string_type)) {
vars = ._eval_ctext(vars, args[2]);
article = vars['result];
} else {
article = ['string_type, "indef"];
}
if ((name[1]) == 'list_type)
return .apply(vars, name[2], 'name_stmt, article);
n = name[2];
if ((vars['delay]) && (n.has_ancestor($user))) {
return dict_add(vars, 'result, ['name_stmt, [name, article]]);
} else if (n == (vars['sender])) {
return dict_add(vars, 'result, ['string_type, "you"]);
} else {
catch ~methodnf {
return dict_add(vars, 'result, ['string_type, n.name(article)]);
} with handler {
return dict_add(vars, 'result, ['string_type, tostr(n)]);
}
}
.
method get_stmt
arg vars, args;
var name;
if (((args[1])[1]) != 'string_type) {
vars = ._eval_ctext(vars, args[1]);
name = vars['result];
} else {
name = args[1];
}
if ((name[1]) != 'string_type)
return dict_add(vars, 'result, ['string_type, "Variable names must be strings."]);
if (!((name[2]) in dict_keys(vars)))
return dict_add(vars, 'result, ['string_type, (">>ERROR: no such variable " + (name[2])) + "<<"]);
return dict_add(vars, 'result, vars[name[2]]);
.
method format_stmt
arg vars, args;
return dict_add(vars, 'result, args[1]);
.
method _eval_ctext
arg vars, term;
var t, output, result;
if (vars['debug])
return ._eval_debug(vars, term);
if (!term) {
return dict_add(vars, 'result, []);
} else if ((term[1]) in ['symbol_type, 'dbref_type, 'integer_type, 'string_type]) {
return dict_add(vars, 'result, term);
} else {
catch ~methodnf {
return .(term[1])(vars, term[2]);
} with handler {
output = [];
for t in (term[2]) {
vars = ._eval_ctext(vars, t);
result = vars['result];
if (type(result) != 'symbol) {
if (type(result[1]) == 'list)
output = [@output, result[1]];
else
output = [@output, result];
}
}
return dict_add(vars, 'result, [term[1], output]);
}
}
.
method force_stmt
arg vars, args;
var t, output, old;
old = vars['force];
vars = dict_add(vars, 'force, 1);
output = [];
for t in (args) {
vars = ._eval_ctext(vars, t);
if (output)
output = [@output, vars['result]];
else
output = vars['result];
}
vars = dict_add(vars, 'force, old);
return dict_add(vars, 'result, output);
.
method text_stmt
arg vars, args;
var term, output, result, t, start, mid, last, first;
output = [];
vars = ._eval_series(vars, args);
result = vars['result];
output = [result[1]];
for term in (sublist(result, 2)) {
if (output) {
last = output.last();
if (((term[1]) == 'string_type) && ((last[1]) == 'string_type)) {
term = ['string_type, (last[2]) + (term[2])];
output = output.chop();
}
}
output = [@output, term];
}
if (listlen(output) == 1) {
first = output[1];
if ((first[1]) == 'string_type)
return dict_add(vars, 'result, first);
}
return dict_add(vars, 'result, ['text_stmt, output]);
.
method foreach_stmt
arg vars, args;
var name, l, c, output, v;
//args[1] is the name of a variable
//args[2] is the a list
//args[3] is the code that will be executed once for each element in the lsit
vars = ._eval_ctext(vars, args[1]);
name = vars['result];
if ((name[1]) != 'string_type)
return dict_add(vars, 'result, ['string_type, "The first argument to foreach should be a string"]);
else
name = name[2];
vars = ._eval_ctext(vars, args[2]);
l = vars['result];
if ((l[1]) != 'list_type)
return dict_add(vars, 'result, ['string_type, "The second arguemnt to foreach should be a list"]);
else
l = l[2];
c = args[3];
output = [];
for v in (l) {
vars = dict_add(vars, name, v);
vars = ._eval_ctext(vars, c);
output = [@output, vars['result]];
}
if (listlen(output) > 1)
output = ['list_type, output];
else if (listlen(output) == 1)
output = output[1];
else
output = 'success;
return dict_add(vars, 'result, output);
.
method eval_stmt
arg vars, args;
var a, output, line;
vars = ._eval_ctext(vars, args[1]);
vars = ._eval_ctext(vars, vars['result]);
return vars;
.
method message_stmt
arg vars, args;
var m;
vars = ._eval_ctext(vars, args[1]);
m = vars['result];
m = (vars['this]).eval_message(.normalize(m), vars);
return dict_add(vars, 'result, m.ctext());
.
method delay_stmt
arg vars, args;
var t, output, old, old_d;
old = vars['force];
old_d = vars['delay];
vars = dict_add(vars, 'force, 0);
output = [];
vars = ._eval_ctext(vars, args[1]);
vars = dict_add(vars, 'force, old);
if (vars['delay]) {
vars = dict_add(vars, 'delay, old_d);
return dict_add(vars, 'result, ['evaluator, [['dbref, this()], vars['result]]]);
} else {
vars = dict_add(vars, 'delay, old_d);
return vars;
}
.
method evaluator
arg vars, args;
vars = ((args[1])[2])._eval_ctext(vars, (args[2])[1]);
vars = dict_add(vars, 'force, 1);
vars = dict_add(vars, 'delay, 0);
vars = sender().eval_ctext(vars, vars['result]);
return vars;
.
method english_stmt
arg vars, args;
var list, empty, and, sep, length;
// turns a list in args[1] into an english list
// args 2 3 4 are optional
// see $list.to_english for meanings.
// generate the defaults
empty = ['string_type, "nothing"];
and = ['string_type, " and "];
sep = ['string_type, ", "];
length = listlen(args);
//get the list
catch ~keynf {
list = args[1];
} with handler {
return dict_add(vars, 'result, (.eval_message("errors.english.usage", vars)).ctext());
}
vars = ._eval_ctext(vars, list);
list = vars['result];
//get the optional arguments
if (length > 1) {
if (((args[2])[1]) != 'string_type) {
vars = ._eval_ctext(vars, args[2]);
empty = vars['result];
if ((empty[1]) != 'string_type)
return dict_add(vars, 'result, (.eval_message("errors.english.usage", vars)).ctext());
} else {
empty = args[2];
}
if (length > 2) {
vars = ._eval_ctext(vars, args[3]);
and = vars['result];
if ((and[1]) != 'string_type)
return dict_add(vars, 'result, (.eval_message("errors.english.usage", vars)).ctext());
if (length > 3) {
vars = ._eval_ctext(vars, args[4]);
sep = vars['result];
if ((sep[1]) != 'string_type)
return dict_add(vars, 'result, (.eval_message("errors.english.usage", vars)).ctext());
}
}
}
list = .normalize(list);
if (type(list) == 'list)
return dict_add(vars, 'result, .fix_values(._english_stmt(list, .normalize(empty), .normalize(and), .normalize(sep))));
else
return dict_add(vars, 'result, .fix_values(list));
.
method gt_stmt
arg vars, args;
var left, right;
vars = ._eval_ctext(vars, args[1]);
left = .normalize(vars['result]);
vars = ._eval_ctext(vars, args[2]);
right = .normalize(vars['result]);
if (left > right)
return dict_add(vars, 'result, ['integer_type, 1]);
else
return dict_add(vars, 'result, ['integer_type, 0]);
.
method if_stmt
arg vars, args;
var output, index, length, statements;
index = 1;
output = [];
while (listlen(args) > index) {
vars = ._eval_ctext(vars, args[index]);
if (._truth(vars['result]))
return ._eval_ctext(vars, args[index + 1]);
else
index = index + 1;
}
return ._eval_ctext(vars, args.last());
.
method list_stmt
arg vars, args;
var method, a, ars;
//call methods on $list
// args[1] is the method
// args[2].. are the arguments
vars = ._eval_ctext(vars, args[1]);
method = vars['result];
if ((method[1]) == 'string_type)
method = tosym(method[2]);
else
method = method[1];
if (type(method) != 'symbol)
return dict_add(vars, 'result, ['string_type, ">>ERROR: methods should be a symbol or string."]);
ars = [];
for a in (sublist(args, 2)) {
vars = ._eval_ctext(vars, a);
ars = [@ars, .normalize(vars['result])];
}
if (ars)
return dict_add(vars, 'result, .fix_values($list.(method)(@ars)));
else
return dict_add(vars, 'result, .fix_values($list.(method)()));
.
method char_type
arg vars, args;
if ((args[1]) != 'string_type)
return ['string_type, ">>ERROR: Character must be a constant string."];
switch (args) {
case "lp":
return ['string_type, "("];
case "amp":
return [string_type, "&"];
case "quote":
return ['string_type, "\""];
case "per":
return ['string_type, "%"];
default:
return ['string_type, (">>ERROR: Unknown character " + args) + "<<"];
}
.
method server_name_stmt
arg vars, args;
return dict_add(vars, 'result, .fix_values($motd.server_name()));
.
method eval_debug
arg vars, term;
var t, output, result, start, offset, debugger, end, off;
offset = tick();
debugger = vars['debug];
debugger.tell("Debuger: " + ($uncompile_evaluator.uncompile(term)));
off = (| vars['offset] |) || 0;
vars = dict_add(vars, 'offset, 0);
start = tick();
if (!term) {
return dict_add(vars, 'result, []);
} else if ((term[1]) in ['symbol_type, 'dbref_type, 'integer_type, 'string_type]) {
return dict_add(vars, 'result, term);
} else {
catch ~methodnf {
return .(term[1])(vars, term[2]);
} with handler {
output = [];
for t in (term[2]) {
vars = ._eval_ctext(vars, t);
result = vars['result];
if (type(result) != 'symbol)
output = [@output, result];
}
return dict_add(vars, 'result, [term[1], output]);
}
}
end = tick();
debugger.tell("Debugger: " + ($uncompile_evalautor.uncompile(result)));
debugger.tell("Debuuger: Time: " + tostr(end - start));
offset = ((((vars['offset]) + start) - offset) + end) - tick();
return dict_add(vars, 'offset, offset);
.
method _eval_debug
arg vars, term;
var start, debugger, end, method, depth, useful, breakdown, unc, waste, off;
//debugger init
off = tick();
debugger = vars['debug];
method = (| tostr(term[1]) |) || "empty";
depth = (| vars['depth] |) || 0;
vars = dict_add(vars, 'depth, depth + 1);
unc = $uncompile_evaluator.eval_ctext(term);
vars = dict_add(vars, 'useful, 0);
vars = dict_add(vars, 'waste, 0);
if (depth == 0)
vars = dict_add(vars, 'debug_data, #[]);
debugger.tell($list.join(tostr(depth) + " ", unc));
start = tick();
//evaluator
if (!term) {
vars = dict_add(vars, 'result, ['string_type, ""]);
} else if ((term[1]) in ['symbol_type, 'dbref_type, 'integer_type, 'string_type]) {
vars = dict_add(vars, 'result, term);
} else {
catch ~methodnf {
vars = .(term[1])(vars, term[2]);
} with handler {
vars = ._eval_debug_series(vars, term[2]);
vars = dict_add(vars, 'result, [term[1], vars['result]]);
}
}
//debugger clean up
end = tick();
useful = ((end - start) - (vars['waste])) - (vars['useful]);
//.debug(end-start, useful, vars['waste], vars['useful]);
vars = dict_add(vars, 'depth, depth);
vars = dict_add(vars, 'debug_data, ._update_breakdown(vars['debug_data], method, useful));
unc = $uncompile_evaluator.eval_ctext(vars['result]);
debugger.tell($list.join(((tostr(depth) + " time ") + tostr(useful)) + " ", unc));
if (depth == 0)
debugger.tell(._breakdown(vars['debug_data]));
vars = dict_add(vars, 'useful, ((end - start) + (vars['useful])) - (vars['waste]));
return dict_add(vars, 'waste, ((((vars['waste]) + start) - off) + tick()) - end);
.
method _update_breakdown
arg data, method, total;
var nums;
nums = (| data[method] |) || [0, 0];
data = dict_add(data, method, [(nums[1]) + total, (nums[2]) + 1]);
return data;
.
method _breakdown
arg data;
var breakdown, method;
breakdown = ["Breakdown:"];
for method in (dict_keys(data))
breakdown = [@breakdown, ((((" " + tostr(method)) + ": ") + tostr((data[method])[1])) + " ") + tostr((data[method])[2])];
return breakdown;
.
method _eval_debug_series
arg vars, args;
var start, output, result, total, waste, t, s, useful, u;
waste = 0;
useful = 0;
start = tick();
output = [];
for t in (args) {
s = tick();
waste = waste + (vars['waste]);
useful = useful + (vars['useful]);
vars = dict_add(vars, 'waste, 0);
vars = dict_add(vars, 'useful, 0);
waste = (waste + tick()) - s;
if (!t) {
vars = dict_add(vars, 'result, ['string_type, ""]);
} else if ((t[1]) in ['symbol_type, 'dbref_type, 'integer_type, 'string_type]) {
vars = dict_add(vars, 'result, t);
} else {
catch ~methodnf {
vars = .(t[1])(vars, t[2]);
} with handler {
vars = ._eval_debug_series(vars, t[2]);
vars = dict_add(vars, 'result, [t[1], vars['result]]);
}
}
result = vars['result];
if (type(result) != 'symbol)
output = [@output, result];
}
vars = dict_add(vars, 'useful, useful);
vars = dict_add(vars, 'result, output);
return dict_add(vars, 'waste, waste + (vars['waste]));
.
method _eval_series
arg vars, term;
var t, output, result;
if (vars['debug])
return ._eval_debug_series(vars, term);
output = [];
for t in (term) {
if ((t[1]) in ['string_type, 'integer_type, 'dbref_type, 'symbol_type]) {
output = [@output, t];
} else {
vars = ._eval_ctext(vars, t);
result = vars['result];
if (type(result) != 'symbol)
output = [@output, result];
}
}
return dict_add(vars, 'result, output);
.
method debug_stmt
arg vars, args;
//(debug <code>)
vars = dict_add(vars, 'debug, (vars['this]).manager());
vars = ._eval_debug(vars, args[1]);
vars = dict_del(vars, 'debug);
return vars;
.
method set_stmt
arg vars, args;
var name;
vars = ._eval_ctext(vars, args[1]);
name = vars['result];
if ((name[1]) != 'string)
return dict_add(vars, 'result, ['string, "variable name must be a string"]);
vars = ._eval_ctext(vars, args[2]);
vars = dict_add(vars, name[2], vars['result]);
return dict_add(vars, 'result, 'succes);
.
method define_stmt
arg vars, args;
var name;
vars = ._eval_ctext(vars, args[1]);
name = vars['result];
if ((name[1]) != 'string)
return dict_add(vars, 'result, ['string, "variable name must be a string"]);
vars = dict_add(vars, name[2], args[2]);
return dict_add(vars, 'result, 'succes);
.
method _english_stmt
arg list, empty, and, sep;
switch (listlen(list)) {
case 0:
return [empty];
case 1:
return list;
case 2:
return [list[1], and, list[2]];
case 3:
return [list[1], sep, @._english_stmt(sublist(list, 2), empty, and, sep)];
}
.