matching utilities (#52)(an instance of Generic Utilities Package made by Hacker)VERB SOURCE CODE: match:
":match(string, object-list)";
"Return object in 'object-list' aliased to 'string'.";
"Matches on a wide variety of syntax, including:";
" \"5th axe\" -- The fifth object matching \"axe\" in the object list.";
" \"where's sai\" -- The only object contained in 'where' matching \"sai\" (possible
$ambiguous_match).";
" \"where's second staff\" -- The second object contained in 'where' matching \"staff\".";
" \"my third dagger\" -- The third object in your inventory matching \"dagger\".";
"Ordinal matches are determined according to the match's position in 'object-list'
or, if a possessive (such as \"where\" above) is given, then the ordinal is the nth
match in that object's inventory.";
"In the matching room (#3879@LambdaMOO), the 'object-list' consists of first the
player's contents, then the room's, and finally all exits leading from the room.";
string = args[1];
olist = args[2];
if (!string)
return $nothing;
elseif (string == "me")
return player;
elseif (string == "here")
return player.location;
elseif (valid(object = $string_utils:literal_object(string)))
return object;
elseif (valid(object = $string_utils:match(string, olist, "aliases")))
return object;
elseif (parsed = this:parse_ordinal_reference(string))
return this:match_nth(parsed[2], olist, parsed[1]);
elseif (parsed = this:parse_possessive_reference(string))
whostr = parsed[1];
objstr = parsed[2];
if (valid(whose = this:match(whostr, olist)))
return this:match(objstr, whose.contents);
else
return whose;
endif
else
return object;
endif
.
match_nth:
":match_nth(string, objlist, n)";
"Find the nth object in 'objlist' that matches 'string'.";
what = args[1];
where = args[2];
n = args[3];
for v in (where)
z = 0;
for q in (v.aliases)
z = z || (index(q, what) == 1);
endfor
if (z && (!(n = n - 1)))
return v;
endif
endfor
return $failed_match;
.
match_verb: "$match_utils:match_verb(verbname, object) => Looks for a command-line style verb named match_list:
":match_list(string, object_list) -> List of all matches.";
what = args[1];
where = args[2];
r = {};
for v in (where)
if (!(v in r))
z = 0;
for q in (v.aliases)
z = z || (index(q, what) == 1);
endfor
if (z)
r = listappend(r, v);
endif
endif
endfor
return r;
.
parse_ordinal_reference parse_ordref:
":parse_ordref(string)";
"Parses strings referring to an 'nth' object.";
"=> {NUM n, STR object} Where 'n' is the number the ordinal represents, and 'object'
is the rest of the string.";
"=> 0 If the given string is not an ordinal reference.";
" Example:";
":parse_ordref(\"second broadsword\") => {2, \"broadsword\"}";
":parse_ordref(\"second\") => 0";
" Note that there must be more to the string than the ordinal alone.";
if (m = match(args[1], ("^" + this.ordinal_regexp) + " +%([^ ].+%)$"))
o = substitute("%1", m);
n = (o in this.ordn) || (o in this.ordw);
return n && {n, substitute("%2", m)};
else
return 0;
endif
.
parse_possessive_reference:
":parse_possessive_reference(string)";
"Parses strings in a possessive format.";
"=> {STR whose, STR object} Where 'whose' is the possessor of 'object'.";
"If the string consists only of a possessive string (ie: \"my\", or \"yduJ's\"),
then 'object' will be an empty string.";
"=> 0 If the given string is not a possessive reference.";
" Example:";
":parse_possessive_reference(\"joe's cat\") => {\"joe\", \"cat\"}";
":parse_possessive_reference(\"sis' fish\") => {\"sis\", \"fish\"}";
" Strings are returned as a value suitable for a :match routine, thus 'my' becoming
'me'.";
":parse_possessive_reference(\"my dog\") => {\"me\", \"dog\"}";
string = args[1];
if (m = match(string, "^my$%|^my +%(.+%)?"))
return {"me", substitute("%1", m)};
elseif (m = match(string, "^%([^ ]+s?%)%'s? *%(.+%)?"))
return {substitute("%1", m), substitute("%2", m)};
else
return 0;
endif
.
PROPERTY DATA:       ordn       ordw       ordinal_regexp |