"Manually" creating an action instance and evaluating scope in T3/adv3

In T3/adv3, how do you “manually” create an action instance and use it to evaluate which objects would be within scope?

For example, if you wanted to know what objects would be within scope if the player typed >FOO PEBBLE, you can tokenize “foo pebble” and then use resolveFirstAction(), CommandRanking.sortByRanking(), and so on. For example, here’s a sample “game” with a >FOOZLE system action that does this:

#charset "us-ascii"
#include <adv3.h>
#include <en_us.h>

DefineSystemAction(Foozle)
        execSystemAction() {
                local action, actor, lst, match, rankings, toks;

                actor = gActor;
                toks = cmdTokenizer.tokenize('foo pebble');

                lst = commandPhrase.parseTokens(toks, cmdDict);
                lst = lst.subset({ x: x.resolveFirstAction(actor,
                        actor) != nil
                });
                if(lst.length() == 0) {
                        reportFailure('Got empty action list. ');
                        return;
                }
                rankings = CommandRanking.sortByRanking(lst,
                        actor, actor);
                match = rankings[1].match;

                action = match.resolveFirstAction(actor, actor);

                "Action object list contains
                        <<toString(action.dobjList_.length())>> elements:\n ";
                action.dobjList_.forEach(function(o) {
                        "\t<<o.obj_.name>>\n ";
                });
        }
;
VerbRule(Foozle) 'foozle' singleDobj: FoozleAction
        verbPhrase = 'foozle/foozling (what)'
;

DefineTAction(Foo);
VerbRule(Foo) 'foo' singleDobj: FooAction
        verbPhrase = 'foo/fooing (what)'
;

modify Thing dobjFor(Foo) { verify() { illogical('Un-foo-able. '); } };

class Fooable: Thing
        dobjFor(Foo) {
                verify() {}
                action() { defaultReport('{You/he} foo{s} <<theName>>. '); }
        }
;

startRoom: Room 'Void' "This is a featureless void. ";
+me: Person;
+pebble: Fooable 'small round pebble' 'pebble' "A small, round pebble. ";
+stone: Thing 'ordinary stone' 'stone' "An ordinary stone. ";

versionInfo: GameID;
gameMain: GameMainDef
        initialPlayerChar = me
;

This works, but say I want to do the same thing for a specific Action class? That is, instead of starting with a literal string or a token list, I have an Action and a noun phrase. Something like:

                // THIS DOES NOT WORK!!!
                local action, actor, prod, results;

                actor = gActor;

                action = FooAction.createActionInstance();

                results = new TentativeResolveResults(actor, actor);

                prod = new EmptyNounPhraseProd();
                prod.setOrigTokenList([
                        [ 'pebble', tokWord, 'pebble' ]
                ]);
                prod.responseProd = singleNoun;

                action.dobjMatch = prod;

                action.resolveNouns(actor, actor, results);

                // REMINDER:  THIS DOES NOT WORK!!!
                "Action object list contains
                        <<toString(action.dobjList_.length())>> elements:\n ";
                action.dobjList_.forEach(function(o) {
                        "\t<<o.obj_.name>>\n ";
                });

As noted in the comments this doesn’t work.

Beyond this specific question, is there a better/more complete reference on T3 parser internals than the section The Command Execution Cycle in the TADS 3 Technical Manual? Not counting just digging through the source.

The semantic rules for all the low-level grammatical stuff is pretty straightforward (as these things go), but the T3 internals (like the creation and configuration of action instances) seems a little murky.

2 Likes