lock utilities (#54)(an instance of Generic Utilities Package made by The_Mayor)VERB SOURCE CODE: init_scanner: this.input_string = args[1]; this.input_length = length(args[1]); this.input_index = 1; this.index_incremented = 0; . scan_token:
string = this.input_string;
len = this.input_length;
i = this.input_index;
while ((i <= len) && (string[i] == " "))
i = i + 1;
endwhile
if (i > len)
this.index_incremented = 0;
return "";
elseif ((ch = string[i]) in {"(", ")", "!", "?"})
this.input_index = i + 1;
this.index_incremented = 1;
return ch;
elseif (ch in {"&", "|"})
this.input_index = i = i + 1;
this.index_incremented = 1;
if ((i <= len) && (string[i] == ch))
this.input_index = i + 1;
this.index_incremented = 2;
endif
return ch + ch;
else
start = i;
while ((i <= len) && (!((ch = string[i]) in {"(", ")", "!", "?", "&", "|"})))
i = i + 1;
endwhile
this.input_index = i;
i = i - 1;
while (string[i] == " ")
i = i - 1;
endwhile
this.index_incremented = i - start;
return this:canonicalize_spaces(string[start..i]);
endif
.
canonicalize_spaces:
name = args[1];
while (index(name, " "))
name = strsub(name, " ", " ");
endwhile
return name;
.
parse_keyexp: "parse_keyexp(STRING keyexpression, OBJ player) => returns a list containing the coded key, or a string containing an error message if the attempt failed."; ""; "Grammar for key expressions:"; ""; " E ::= A "; " | E || A "; " | E && A "; " A ::= ( E ) "; " | ! A "; " | object "; " | ? object "; this:init_scanner(args[1]); this.player = args[2]; return this:parse_E(); . parse_E:
exp = this:parse_A();
if (typeof(exp) != STR)
while ((token = this:scan_token()) in {"&&", "||"})
rhs = this:parse_A();
if (typeof(rhs) == STR)
return rhs;
endif
exp = {token, exp, rhs};
endwhile
endif
this.input_index = this.input_index - this.index_incremented;
return exp;
.
parse_A:
token = this:scan_token();
if (token == "(")
exp = this:parse_E();
if ((typeof(exp) != STR) && ((tok = this:scan_token()) != ")"))
return "Missing ')'";
else
return exp;
endif
elseif (token == "!")
exp = this:parse_A();
if (typeof(exp) == STR)
return exp;
else
return {"!", exp};
endif
elseif (token == "?")
next = this:scan_token();
if (next in {"(", ")", "!", "&&", "||", "?"})
return ("Missing object-name before '" + token) + "'";
elseif (next == "")
return "Missing object-name at end of key expression";
else
what = this:match_object(next);
if (typeof(what) == OBJ)
return {"?", this:match_object(next)};
else
return what;
endif
endif
elseif (token in {"&&", "||"})
return ("Missing expression before '" + token) + "'";
elseif (token == "")
return "Missing expression at end of key expression";
else
return this:match_object(token);
endif
.
eval_key:
"eval_key(LIST|OBJ coded key, OBJ testobject) => returns true if testobject will
solve the provided key.";
key = args[1];
who = args[2];
type = typeof(key);
if (!(type in {LIST, OBJ}))
return 1;
elseif (typeof(key) == OBJ)
return (who == key) || $object_utils:contains(who, key);
endif
op = key[1];
if (op == "!")
return !this:eval_key(key[2], who);
elseif (op == "?")
return key[2]:is_unlocked_for(who);
elseif (op == "&&")
return this:eval_key(key[2], who) && this:eval_key(key[3], who);
elseif (op == "||")
return this:eval_key(key[2], who) || this:eval_key(key[3], who);
else
return 1 / 0;
endif
.
match_object:
"used by $lock_utils to unparse a key expression so one can use `here' and `me' as
well as doing the regular object matching.";
token = args[1];
if (token == "me")
return this.player;
elseif (token == "here")
if (valid(this.player.location))
return this.player.location;
else
return ("'here' has no meaning where " + this.player.name) + " is";
endif
else
what = this.player.location:match_object(token);
if (what == $failed_match)
return ("Can't find an object named '" + token) + "'";
elseif (what == $ambiguous_match)
return ("Multiple objects named '" + token) + "'";
else
return what;
endif
endif
.
unparse_key:
":unparse_key(LIST|OBJ coded key) => returns a string describing the key in english/moo-code
terms.";
"Example:";
"$lock_utils:unparse_key({\"||\", $hacker, $housekeeper}) => \"#18105[Hacker] ||
#36830[housekeeper]\"";
key = args[1];
type = typeof(key);
if (!(type in {LIST, OBJ}))
return "(None.)";
elseif (type == OBJ)
if (valid(key))
return tostr(key, "[", key.name, "]");
else
return tostr(key);
endif
else
op = key[1];
arg1 = this:unparse_key(key[2]);
if (op == "?")
return "?" + arg1;
elseif (op == "!")
if (typeof(key[2]) == LIST)
return ("!(" + arg1) + ")";
else
return "!" + arg1;
endif
elseif (op in {"&&", "||"})
other = (op == "&&") ? "||" | "&&";
lhs = arg1;
rhs = this:unparse_key(key[3]);
if ((typeof(key[2]) == OBJ) || (key[2][1] != other))
exp = lhs;
else
exp = ("(" + lhs) + ")";
endif
exp = ((exp + " ") + op) + " ";
if ((typeof(key[3]) == OBJ) || (key[3][1] != other))
exp = exp + rhs;
else
exp = ((exp + "(") + rhs) + ")";
endif
return exp;
else
return 1 / 0;
endif
endif
.
eval_key_new:
set_task_perms($no_one);
key = args[1];
who = args[2];
type = typeof(key);
if (!(type in {LIST, OBJ}))
return 1;
elseif (typeof(key) == OBJ)
return (who == key) || $object_utils:contains(who, key);
endif
op = key[1];
if (op == "!")
return !this:eval_key(key[2], who);
elseif (op == "?")
return key[2]:is_unlocked_for(who);
elseif (op == "&&")
return this:eval_key(key[2], who) && this:eval_key(key[3], who);
elseif (op == "||")
return this:eval_key(key[2], who) || this:eval_key(key[3], who);
elseif (op == ".")
if ($object_utils:has_property(who, key[2]) && who.(key[2]))
return 1;
else
for thing in ($object_utils:all_contents(who))
if ($object_utils:has_property(thing, key[2]) && thing.(key[2]))
return 1;
endif
endfor
endif
return 0;
elseif (op == ":")
if ($object_utils:has_verb(who, key[2]) && who:(key[2])())
return 1;
else
for thing in ($object_utils:all_contents(who))
if ($object_utils:has_verb(thing, key[2]) && thing:(key[2])())
return 1;
endif
endfor
endif
return 0;
else
return 1 / 0;
endif
.
parse_A_new:
token = this:scan_token();
if (token == "(")
exp = this:parse_E();
if ((typeof(exp) != STR) && (this:scan_token() != ")"))
return "Missing ')'";
else
return exp;
endif
elseif (token == "!")
exp = this:parse_A();
if (typeof(exp) == STR)
return exp;
else
return {"!", exp};
endif
elseif (token == "?")
next = this:scan_token();
if (next in {":", ".", "(", ")", "!", "&&", "||", "?"})
return ("Missing object-name before '" + token) + "'";
elseif (next == "")
return "Missing object-name at end of key expression";
else
what = this:match_object(next);
if (typeof(what) == OBJ)
return {"?", this:match_object(next)};
else
return what;
endif
endif
elseif (token in {":", "."})
next = this:scan_token();
if (next in {":", ".", "(", ")", "!", "&&", "||", "?"})
return ("Missing verb-or-property-name before '" + token) + "'";
elseif (next == "")
return "Missing verb-or-property-name at end of key expression";
elseif (typeof(next) != STR)
return "Non-string verb-or-property-name at end of key expression";
else
return {token, next};
endif
elseif (token in {"&&", "||"})
return ("Missing expression before '" + token) + "'";
elseif (token == "")
return "Missing expression at end of key expression";
else
return this:match_object(token);
endif
.
PROPERTY DATA:       player       input_index       input_length       input_string       index_incremented |