Method code for $foundation.match_environment()

[Turn on line numbering]
arg str, @preference;
var obj, env, found, efound, sfound, match, target;

if (!str)
    throw(~objnf, "No object specified.", str);
str = str.strip_article();

// Handle special cases.
if (str in ["me", "my", "myself"]) {
    return this();
} else if (str[1] == "$" || str[1] == "#") {
    return (> $object_lib.to_dbref(str) <);
} else if (str[1] == "~") {
    str = str.subrange(2);
    if (str[1] != "~")
        return $user_db.match_begin(str);
} else if (str in ["it", "him", "her"]) {
    return (| .match_context(str) |) || throw(~context, "I don't see " + str + " here, do you?");
}

// Start matching
found = [];
env = .environment();

// special case ordinal references
if ((match = $parse_lib.ordinal_reference(str)))
    return (> env.match_nth(@match) <);

// standard matching
catch ~ambig, ~objnf {
    return (> env.match_object(str) <);
} with {
    // possessive matching
    if ((match = $parse_lib.possessive_reference(str))) {
        catch ~objnf, ~ambig, ~range {
            if (match[1] == "me") {
                obj = this();
            } else {
                target = match[1];
                obj = (> env.match_object(match[1], 'possessive) <);
            }
            env = (| obj.contents() |) || [];
            target = match[2];
            if ((found = $parse_lib.ordinal_reference(match[2]))) {
                return (> env.match_nth(@found) <);
            } else {
                // this becomes a problem, especially with exits, too broad...
                return (> env.match_object(match[2], 'possessive) <);
            }
        } with {
            if (type(obj) == 'objnum && obj.match_for_environment(match[2], 'possessive))
                throw(~self, "\"" + target + "\" matches self?" + obj, [obj, @match]);
            else if (error() == ~objnf)
                throw(~objnf, obj.name() + " does not have " + match[2].add_indefinite() + ".");
            else if (error() == ~ambig)
                throw(~ambig, "\"" + target + "\" (" + str + ") can match " + traceback()[1][3].mmap('namef, 'ref).to_english("", " or ") + ".");
            else
                throw(~objnf, obj.name() + "'s what?");
        }
    } else {
        if (error() == ~objnf)
            throw(~objnf, "You do not see " + str.add_indefinite() + " anywhere.");

        // handle ambiguous matches, start with exact match
        efound = filter obj in (traceback()[1][3]) where (obj.name() == str);
        if (listlen(efound) == 1)
            return efound[1];

        // if not exact match, check for preferencial ancestors
        if (listlen(preference)) {
            [preference] = preference;
            found = filter obj in (traceback()[1][3]) where (obj.is(preference));
            if (listlen(found) == 1)
                return found[1];
        }
        if (efound) {
            sfound = efound.mmap('namef, 'ref).to_english("", " or ");
        } else {
            efound = traceback()[1][3];
            sfound = efound.mmap('namef, 'ref).to_english("", " or ");
        }
        throw(~ambig, "\"" + str + "\" can match " + sfound + ".", efound);
    }
    rethrow(error());
}

// $#Edited: 19 Apr 04 22:32 $brandon

["// Created 26-Mar-1995 as a part of ColdCore, see: @help Credit"]

the Cold Dark