Original Parser

version 1 by Ron Newcomb

  • Home page
  • Beginning
  • Previous
  • Next



  • Chapter - Multiple Object List

    [The |MultiAdd| routine adds object |o| to the multiple-object-list. This is
    only allowed to hold |MATCH_LIST_WORDS| minus one objects at most, at which
    point it ignores any new entries (and sets a global flag so that a warning
    may later be printed if need be).

    The |MultiSub| routine deletes object |o| from the multiple-object-list.
    It returns 0 if the object was there in the first place, and 9 (because
    this is the appropriate error number in |Parser()|) if it wasn't.
    (However, nowhere in the code uses that return value.)

    The |MultiFilter| routine goes through the multiple-object-list and throws
    out anything without the given attribute |attr| set.

    |ReviseMulti| goes through the multiple-object list and removes certain items.
    Some grammar tokens like [other things] and [things inside] refer to the other
    noun's grammar token, such as [container]. So ReviseMulti enables this
    cross-talk between token by filtering out objects that relate to the other
    noun in the indicated way. ]

    To add (obj - an object) to the multiple-object list, allowing duplicates (this is MultiAdd):
        let the size be the number of elements in the multiple-object list;
        if the size is the maximum number of things understood at once - 1:
            now the multiple-object list overflowed is true;
            stop the action;
        if not allowing duplicates:
            if the obj is listed in the multiple-object list, stop the action;
        increment size;
        change the size element of the multiple-object list to the obj;
        change the multiple-object list to have size elements.

    [ MultiAdd o i j;
    i = multiple_object-->0;
    if (i == MATCH_LIST_WORDS-1)
    { toomany_flag = 1;
    rtrue;
    }
    for (j=1 : j<=i : j++)
    if (o == multiple_object-->j) rtrue;
    i++;
    multiple_object-->i = o;
    multiple_object-->0 = i;
    ]

    [ Lacks cache optimizations. Can easily be generalized for all 1-based arrays. ]
    To remove (obj - an object) from the multiple-object list (this is MultiSub): [MultiSubtract, not MultiSubroutine]
        let the final position be the number of elements in the multiple-object list;
        if the obj is listed in the multiple-object list:
            shift the multiple-object list left between the chosen and the final position using some scratch space;
            decrement the final position;
            change the multiple-object list to have (final position) elements.
            [return 0;]
        [return the not sure what it refers to error.]

    [ MultiSub o i j k;
    i = multiple_object-->0;
    for (j=1 : j<=i : j++)
    if (o == multiple_object-->j) {
    for (k=j : k<=i : k++) multiple_object-->k = multiple_object-->(k+1);
    multiple_object-->0 = --i;
    return 0;
    }
    return VAGUE_PE;
    ]

    [ Unused? Can easily be generalized for all 1-based arrays if MultiSub is as well. ]
    To remove all except (attr - an either/or property) objects/things from the multiple-object list (this is MultiFilter):
        repeat through the multiple-object list:
            if the chosen element does not provide the property attr directly:
                remove the chosen element from the multiple-object list;
                now the chosen [row] is at the 0th position. [ which restarts the loop ]

    [ MultiFilter attr i j o;
        .MFiltl;
    i = multiple_object-->0;
    for (j=1 : j<=i : j++) {
    o = multiple_object-->j;
    if (o hasnt attr) { MultiSub(o); jump Mfiltl; }
    }
    ]


    [ The 'other things' grammar token filters out the second noun. ]
    [ The 'things inside' grammar token filters out what's outside the second noun. ]
    [ The 'things' grammar token, during TAKE ALL..., filters out anything outside the actor's scope. ]
    To filter the multiple-object list by the grammar token & (other noun - an object) (this is ReviseMulti):
        if trace 4, say " Revising multiple object list of size [number of elements in the multiple-object list] with 2nd [other noun][line break]";
        let kept be 0;
        if the kind of multi is 'other things':
            remove the other noun from the multiple-object list;
    [ repeat through the multiple-object list:
                if [as long as] the chosen element is not the second noun:
                    increment kept;
                    change the kept element of the multiple-object list to the chosen element;
                [otherwise the chosen element is removed from the list. ]
            change the multiple-object list to have kept elements;]
        otherwise if the kind of multi is 'things inside':
            repeat through the multiple-object list:
                if [as long as] the chosen element is directly in the other noun:
                    increment kept;
                    change the kept element of the multiple-object list to the chosen element;
            change the multiple-object list to have kept elements;
        otherwise if the kind of multi is 'things' and the action to be is the taking action:
            if trace 4, say " Token 2 plural case: number with actor [the person asked][line break]";
            if the TAKE ALL exception is 2:
                repeat through the multiple-object list:
                    if [as long as] the scope ceiling of the chosen element is the scope ceiling of the person asked:
                        increment kept;
                        change the kept element of the multiple-object list to the chosen element;
                    [otherwise the chosen element is removed from the list. ]
                change the multiple-object list to have kept elements;
        if trace 4, say " Done: new size [number of elements in the multiple-object list][line break]".
    [ if the number of elements in the multiple-object list is 0, decide on the nothing to do error;
        decide on no errors here.]

    [ ReviseMulti second_p i low;
    #Ifdef DEBUG;
    if (parser_trace >= 4)
    print " Revising multiple object list of size ", multiple_object-->0,
    " with 2nd ", (name) second_p, "^";
    #Endif; ! DEBUG

    if (multi_context == MULTIEXCEPT_TOKEN or MULTIINSIDE_TOKEN) {
    for (i=1,low=0 : i<=multiple_object-->0 : i++) {
    if ( (multi_context==MULTIEXCEPT_TOKEN && multiple_object-->i ~= second_p) ||
    (multi_context==MULTIINSIDE_TOKEN && multiple_object-->i in second_p)) {
    low++;
    multiple_object-->low = multiple_object-->i;
    }
    }
    multiple_object-->0 = low;
    }

    if (multi_context == MULTI_TOKEN && action_to_be == ##Take) {
    #Ifdef DEBUG;
    if (parser_trace >= 4) print " Token 2 plural case: number with actor ", low, "^";
    #Endif; ! DEBUG
    if (take_all_rule == 2) {
    for (i=1,low=0 : i<=multiple_object-->0 : i++) {
    if (ScopeCeiling(multiple_object-->i) == ScopeCeiling(actor)) {
    low++;
    multiple_object-->low = multiple_object-->i;
    }
    }
    multiple_object-->0 = low;
    }
    }

    i = multiple_object-->0;
    #Ifdef DEBUG;
    if (parser_trace >= 4) print " Done: new size ", i, "^";
    #Endif; ! DEBUG
    if (i == 0) return NOTHING_PE;
    return 0;
    ]