[Inform 6] Generate an action by calling the parser

Is it possible in Inform 6 for, say, a before routine to generate an action by passing a list of words to the parser for interpretation.

For instance, if I want “read book” to eventually execute “ask fireman about the big red truck”, I can’t seem to use the standard syntax, because “the big red truck” is a topic token that is parsed manually using consult_from and consult_words by the fireman object.

I know I can analyze and rewrite the buffer array in BeforeParsing, but I’d like to have “read book” perform duties in addition to “ask fireman about the big red truck”, using the latter only to display additional text to the user.

Thanks!
~Jesse

So, something like:

        <<Ask noun 'big red truck'>>;

Doesn’t work?

It doesn’t work:

<Ask noun 'big red truck'>

doesn’t invoke the parser machinery, apprently, and consult_words and consult_from are not set before the Ask routine is invoked.

Hmmm… You’re using <Ask noun ‘big red truck’> and I’m using <<Ask noun ‘big red truck’>> (double carets) or is that just a typo on your part on the forum?

Can you give some source code for context?

Both and <> are valid, with <> also returning true. inform-fiction.org/manual/html/s6.html#p98

I don’t know how to solve this problem, but it might be possible to overwrite the input buffer and then just call the parser?

So, I’ve got this code in a little scratchpad game I try things out in (this is the entire inf file) and I can call <<Ask Sally ‘birthday’>> which works.

Constant Story "Kids Game";
Constant Headline "A game for kids.";

Include "parser";
Include "verblib";

[ Initialise;
	font off;
	location = Living_Room;
];

Object with found_in [; rtrue; ], has light scenery;

Object Living_Room "Living Room"
	with
	description "A room, furnished with couch, chairs, and tables",
     has enterable light;

Object -> Sally "Sally Mae"
	with
	name 'sally' 'her' 'she' 'woman' 'mae',
	short name 'Sally',
	initial "She's the type that is not a type.",
	description "Sally looks at you from atop an upturned nose.",
	life [;
		Ask:
		switch(second) {
			'eyes': "These tears are for me, not you!"; 
			'birthday': "~You forgot it! You forgot my birthday!~";
			default: "~You forgot something.~";
		} rfalse;
	],
	has female animate;

Object -> Book "Book"
	with
	name 'book',
	description "One of those new-fangled, paper tablets...",
	before [;
		Read:
			<<Ask Sally 'birthday'>>;
	],
	has static;

Object -> TV "Television"
	with
	name 'television' 'tv',
	description 
		"An electronic device, popular before the advent of
		tablets, iphones, and the like.",
	has static on;

Include "grammar";

Verb 'talk' 'chat' 'to' * noun -> Ask;

[ Readsub; ];
Extend only 'read' replace * noun -> Read;

It’s possible I’m missing something about the problem here. However,

would seem to be solvable by

<<Ask Fireman ‘big red truck’>>
instead of
<<Ask noun ‘big red truck’>>

However, I admit I’m not always the best at grokking codewise problems without the code to look over. So, I may be misunderstanding your problem.

Hope this helps. Sorry if it doesn’t. Best of luck :slight_smile:

Thanks all - this seems like a tricky one. There’s a lot of global state in the parser source and main loop that’s not too easy to wrap one’s head around when calling the parser recursively, in a sense.

<<Ask Fireman ‘truck’>> works, putting the single word into second, but <<Ask Fireman ‘big red truck’>> creates a new dictionary “word” (‘big red truck’) which would be put into second and would need to be handled as a single unit (as opposed to Sally observing whether ‘big’ or ‘small’ preceded ‘truck’, for instance).

I’ll just abstract away the ASK handling into its own routines, and call those routines directly, instead of trying to build up a new input line.

I’d just wondered if there were some Inform library technique to do this that wasn’t mentioned in the DM4 or Roger Firth’s FAQ.

~Jesse

Yeah, that sounds like something I’d need to look at the source code you’ve got to really grok what you’re trying to do, why, and exactly how the difference is important to what you’re trying to accomplish.

Ah well.

Best of luck :slight_smile:

As for the why…I don’t really need to do it, I just thought it would be elegant to, as an example, put all of a game’s conversation handling in the ASK and TELL routines, and then, as an option for IF newcomers, offer a menu-based conversation system based on phtalkoo.h that would just delegate to ASK and TELL by constructing input lines.

What gave me the idea was the style of presenting conversation choices that Adam Cadre gave in his phototalk.inf example, where the player is presented with options like this:

3: switch (line) {
           0: print ">ASK ALLEY FOR AN ORANGE^";
           1: print ">ALLEY, GIVE ME YOUR ORANGE^";
           2: print ">TELL ALLEY ABOUT THE SEYCHELLES^";
           3: print ">ALLEY, PLEASE COME DOWN FOR A SECOND^";
           4: print ">TELL ALLEY ABOUT OUR LACK OF ANIMOSITY^";
           5: print ">ASK ALLEY ABOUT POSSIBLE PARAMOURS^";
           6: print ">ASK ALLEY TO THE DANCE ON FRIDAY^";
        } 

and (though Adam didn’t implement it, so far as I know) I thought to simply run the option chosen through the parser to have that conversation line executed.

~Jesse

There’s no built-in way of doing what you want. You’d need to fill in the input buffer array with the string, use tokenization to parse that into dict words, and then set the parser global variables to refer to that. I think the relevant variables are consult_from and consult_words – sorry, I’m travelling and don’t have my I6 library code at hand.

This will be easier and less error-prone.

You might wind up creating an object for each topic (oranges, Seychelles, etc) in which case the abstraction is easy to model.

Zarf- do you still have the source for your TWIFcomp entry from 2010 - the one which replaced the player’s command with a random action? I was looking for it recently but I can only find the game file archived. The TWIFcomp page sadly died some years ago.

The TWIFComp page can (happily) still be accessed by the Wayback Machine.

Code for zarf’s “You See Chaos Here”:

[spoiler][code]“You See Chaos Here.” by Zarf

Madness is room

Chaos is in it

Before doing anything: x

To x:
(- action = ActionData–>(1+11*random(64)); if (~~noun) noun = player; -)[/code][/spoiler]

Thanks!

Good to know!

I’m going to use a system like this (untested) bit of code

Array askwords table 8;

Object Fireman
  with handle_ask  [numwords;
            numwords = askwords-->0;
            ! word1 = words-->1
            ! etc.
        ],
       life [ i;
           Ask: if (consult_words > 8)
                   consult_words = 8;
                askwords-->0 = consult_words;
                wn = consult_from;
                for (i = 1 : i <= consult_words : i++)
                    askwords-->i = NextWord();
                self.handle_ask();
        ],
       ...


Object Book
  with before [;
         Read: FillArray(askwords, 'big', 'red', 'truck'); 
               Fireman.handle_ask();
       ],
       ...

[ FillArray ar w1 w2 w3 w4 w5 w6
            n;
    if (w1) { n++; ar-->n = w1; }
    if (w2) { n++; ar-->n = w2; }
    if (w3) { n++; ar-->n = w3; }
    if (w4) { n++; ar-->n = w4; }
    if (w5) { n++; ar-->n = w5; }
    if (w6) { n++; ar-->n = w6; }
    ar-->0 = n;
];

~Jesse

Whoops, I forgot that in strict mode you can’t change a table’s size directly, so instead of

Array askwords table 8;

one should use

Array askwords --> 9;

~Jesse