Original Parser

version 1 by Ron Newcomb

  • Home page
  • Beginning
  • Previous
  • Next



  • Chapter - DoScopeActionAndRecurse

    [Level 3.
    In all cases, the |domain| itself is visited. There are then three possible
    forms of recursion:
    (a) To unconcealed objects which are inside, on top of, carried or worn by
    the |domain|: this is called ``searching'' in traditional I6 language and
    is suppressed if |domain| is the special value |nosearch|. hidden
    (b) To unconcealed component parts of the |domain|.
    (c) To any other objects listed in the |add_to_scope| property array, or
    supplied by the |add_to_scope| property routine, if it has one. (I7 does
    not usually use |add_to_scope|, but it remains a useful hook in the parser,
    so it retains its old I6 library interpretation.)]


    To recursively do scope action on (domain - an object):
        recursively do scope action on the domain excluding nothing under 'something'.

    To recursively do scope action on (domain - an object) excluding (nosearch - an object) under (context - a grammar token) (this is DoScopeActionAndRecurse):
        [ Rule 0 - In all cases, the |domain| itself is visited. ]
        do scope action on the domain;
        [ Rule (a) - Assuming the calling function hasn't specifically requested a domain not be searched, we'll consider everything that rooms, people, and see-through things have. ]
        if the domain is not the nosearch and (the domain is a room or the domain is a person or the domain is see-through):
            repeat with the possession running through the possessed nodes of the domain:
                if the domain is the person asked or the domain does not conceal the possession:
                    recursively do scope action on the possession excluding nosearch under the context;
        [ Rule (b) - Also consider anything (unconcealed) that the domain incorporates. ]
        if the domain can have parts:
            repeat with the piece running through the incorporated nodes of the domain:
                if the domain is the person asked or the domain does not conceal the piece:
                    recursively do scope action on the piece excluding nosearch under the context;
        [ Rule (c) - Now consider objects in the add_to_scope property. If used, that property points to either an array or a routine. I7 doesn't use add_to_scope so it's usually nothing. ]
        let ad be the hidden scope extender array of the domain;
        if ad is not currently blank:
            if ad is currently a rule:
                now the add to scope flag is 2 plus the context as a number;
                consider the scope extender of the domain directly;
                now the add to scope flag is zero;
            otherwise:
                repeat through the scope extender of the domain:
                    if the object element is not currently blank:
                        recursively do scope action on the object element excluding nothing under the context.

    [ DoScopeActionAndRecurse domain nosearch context i ad n obj next_obj;

        DoScopeAction(domain);

    ! (a)
    if ((domain ~= nosearch) &&
    ((domain ofclass K1_room or K8_person) || (IsSeeThrough(domain) == 1))) {
            obj = child(domain);
            while (obj) {
                next_obj = sibling(obj);
                if ((domain == actor) || (TestConcealment(domain, obj) == false))
                    DoScopeActionAndRecurse(obj, nosearch, context);
                obj = next_obj;
            }
        }

        ! (b)
        if (domain provides component_child) {
            obj = domain.component_child;
            while (obj) {
                next_obj = obj.component_sibling;
                if ((domain == actor) || (TestConcealment(domain, obj) == false))
                    DoScopeActionAndRecurse(obj, 0, context);
                obj = next_obj;
            }
        }

    ! (c)
    ad = domain.&add_to_scope;
    if (ad ~= 0) {
    ! Test if the property value is not an object.
    #Ifdef TARGET_ZCODE;
    i = (UnsignedCompare(ad-->0, top_object) > 0);
    #Ifnot; ! TARGET_GLULX
    i = (((ad-->0)->0) ~= $70);
    #Endif; ! TARGET_

    if (i) {
    ats_flag = 2+context;
    RunRoutines(domain, add_to_scope);
    ats_flag = 0;
    }
    else {
    n = domain.#add_to_scope;
    for (i=0 : (WORDSIZE*i)<n : i++)
    if (ad-->i)
    DoScopeActionAndRecurse(ad-->i, 0, context);
    }
    }
    ]