Adding new topics to a table

I want the player to be able to add entries to a table during play, and then be able to look up these entries later. The problem is, I can’t figure out how to add to a “topics” column in a table, and I can’t figure out how to look up entries in the table except using a “topics” column.

Here’s some example code to illustrate what I’m trying to do:

Table of Stuff
Topic	Name
"Book"	"Book"
with 5 blank rows

Storing is an action applying to one topic.
Understand "Store [text]" as storing.

Carry out storing:
	let T be the topic understood;
	choose a blank row in Table of Stuff;
	now name entry is T;
	now topic entry is T;
	say "You stored the text '[name entry]".


Researching is an action applying to one topic.
Understand "Research [text]" as researching.

Carry out researching:
	let T be the topic understood;
	if T is a topic listed in Table of Stuff:
		choose a row with a name of "[T]" in the Table of Stuff;
		say "The text '[name entry] is included in the database.".

This gives me an error “you seem to be asking me to put a snippet into a topic, which can’t safely be done.” Any suggestions?

Try

Table of Stuff
Text	Name
"Book"	"Book"
with 5 blank rows

Storing is an action applying to one topic.
Understand "Store [text]" as storing.

Carry out storing:
	let T be the topic understood;
	choose a blank row in Table of Stuff;
	now name entry is T;
	now text entry is T;
	say "You stored the text '[name entry]".


Researching is an action applying to one topic.
Understand "Research [text]" as researching.

Carry out researching:
	let T be the topic understood;
	if "[T]" is a text listed in Table of Stuff:
		choose a row with a name of "[T]" in the Table of Stuff;
		say "The text '[name entry] is included in the database.".

Store texts instead of topics and it all works out. Other people will understand better all the subtleties of snippets, texts, and topics. I find it terribly confusing.

3 Likes

Thank you, now it compiles. Unfortunately I get another error now when I try to use the “research” action. It says “Glulxe fatal error: Memory out of range (251D0104)”.

This is the updated code:

The library is a room.


Table of Stuff
Text	Name
"Book"	"Book"
with 5 blank rows

Storing is an action applying to one topic.
Understand "Store [text]" as storing.

Carry out storing:
	let T be the topic understood;
	choose a blank row in Table of Stuff;
	now name entry is T;
	now text entry is T;
	say "You stored the text '[name entry]'".


Researching is an action applying to one topic.
Understand "Research [text]" as researching.

Carry out researching:
	let T be the topic understood;
	if T is a text listed in Table of Stuff:
		choose a row with a text of "[T]" in the Table of Stuff;
		say "The text '[name entry] is included in the database.";
	else:
		say "The text 'T' is not found.".

It’s easy to be confused because the documentation and language are a little loose about which is which, and there is sometimes casting of one form to another, and there are similarly-worded phrases that have similar functions (e.g. matches vs. matches the text).

A topic gets compiled as a routine. It’s not possible to create a new topic at run-time.

A “topic” in an action definition functionally means a text (which is initially handled as a snippet internally).

The error that you’re seeing is because a snippet is not being cast as a text automatically for the condition T is a text listed in Table of Stuff. I’m not sure whether that should qualify as a bug or not. Which version of Inform are you using?

Try changing the code a little:

Carry out researching:
	let T be the "[topic understood]"; [this line changed]
	...

[Bug details for 6M62: The interpreter fault happens when the call to BlkValueCompare() in ExistsTableRowCorr() passes the topic understood snippet as the former’s entry parameter. When BlkValueCompare() tries to get its weak kind via BlkValueWeakKind(), the line return o-->BLK_HEADER_KOV is trying to access a value out of range.]

3 Likes

Thank you, that is really good to know.

Now everything works as expected.

Oh and to answer your question, I’m using Inform 7 v10.1.2.

I’m glad that worked for you, but I just want to point out that the solution from @rileypb works on the same principle; it looks like you didn’t copy one of the changed lines from his solution:

Carry out researching:
	let T be the topic understood;
	if "[T]" is a text listed in Table of Stuff: [ <-- note new quotes and square brackets in this line]
	...

In all fairness he should get the credit.

@Zed, @drpeterbatesuk, @Draconis (or other interested parties): Is the issue that the OP encountered a bug? The compiler knows that the column being checked holds a text – I would think it should either automatically cast the snippet or issue a Problem message pointing out the mismatch, as it does for:

...
let N be a number;
if N is a text listed in Table of Stuff:
...
2 Likes

Yes, I agree that this is a bug.

Snippets are not routinely cast to texts in order to make comparisons.

For example, the following does not work as intended (although it also generates neither a compiler error or runtime error: the comparison is simply always false):

After reading a command:
	let T be the player's command;
	if T is "Hello":
		say "Hello.";
		reject the player's command.

This happens because at I6 level the compiler generates a straight comparison of a snippet value with an array address:

[ call_U2016 tmp_0;
    if (debug_rules) {
        DB_Rule(call_U2016, 800, 0);
    }
    (tmp_0 = players_command);
    if ((tmp_0 == bc_U299)) {
        (say__p = 1);
        ParaContent();
        print "Hello.";
        print "^";
        RulebookFails();
        rtrue;
    }
    rfalse;
];

...

Array bc_U299 --> [ CONSTANT_PACKED_TEXT_STORAGE; text_U98; ];

This is something the compiler should also reject, as it would if T were assigned to a number not a snippet.

2 Likes