Preform within I7 source text?

I finally got around to reading up a bit on Preform. I saw this tantalizing statement (section 3):

It is also possible to load additional Preform declarations from source text in Inform…

Does that mean that it’s theoretically possible to modify how the compiler understands the source text that it’s reading? If so, does anyone know where one can find out more about how to do that?


Preform is used by language extensions and by other extensions that replace sections of the language extension (so that the preform is read early enough by the compiler).
Some parts of the preform must be in the language ext (or replacing a section of it) but some must be in the game source (I don’t know why).

In Experimental French Features.i7x, you can find such an example: line 4508

All of this is for 6L38. @Natrium729 has worked on the translation of v10 last year and might have some things to add.

Merci beaucoup, CrocMiam!

I was able to get a small success with

Include (-
language English

<en-trie-pasturise-exceptions> ::=
	    zorking               zorken
-) in the Preform grammar.

which works when placed in the main source text, but this is of no real value because there is an I7 syntax for setting custom past participles already.

I made an attempt to add “elsewise” as an alternative for “else” or “otherwise” (in the if ... else ... construction). However, the code

Include (-
language English

<control-structure-phrase> ::=
	/f/ elsewise	|
	/h/ elsewise	|
	/i/ -- elsewise

-) in the Preform grammar.

did not work, and I’m not sure why. (I tried to follow the pattern shown in section 7 of About Preform. Quite possibly I have misunderstood the intended syntax here.)

The alternative word “elsewise” was accepted only when directly altering Syntax.preform and replacing

<control-structure-phrase> ::=
	    if ... is begin |                       
	    if ... is |                                     
	    if/unless ... |                         
	    repeat ... |                            
	    while ... |                                     
	    else/otherwise |                        
	    else/otherwise if/unless ... |
	    else/otherwise ... |            
	    -- otherwise |                          
	    -- ...      

with a modified version that changed the lines using else/otherwise.

I also tried to get “whenever” to be accepted in place of “if,” but I had no success at all in that. Looking at the production definition, I’m guessing that the reason is that the compiler routine receiving text matching the third line is hardcoded to look at the specific word used so that it can discriminate between “if” (P) and “unless” (not P).

1 Like

The contents of Control Structures provide a little more information. It certainly doesn’t seem as though my guess about differentiating “P” from “not P” via something hardcoded to the production is correct, though it’s not at all clear to me how the compiler is managing to tell the difference between if and unless in source code. (Section SR5/3/1 - Control phrases of the Standard Rules seems to do this job somehow?)

The example that you pointed to in your extension modifies the <control-structure-phrase> non-terminal, @CrocMiam. Does it work correctly? If so, can you provide any hints?

It works in French with these 4 things:

  • 6L38
  • (in French) after the title/author
  • Include Experimental French Features by Nathanael Marion
  • In the game source:
Include (-
	language French

	<control-structure-phrase> ::=
		/a/ si ... est début |
		/b/ si ... est |
		/c/ si ... |
		/c/ à moins que |
		/d/ répéter/parcourir ... |
		/e/ tant que ... |
		/f/ sinon |
		/g/ sinon si ... |
		/g/ sinon à moins que |
		/h/ -- sinon |
		/i/ -- ... |
-) in the Preform grammar.

It allows me to write

	si 1 est 2: 
		dire "oh la la";
	sinon dire "oh zut";

I can’t tell you more.

1 Like

It’s been a long time I dived into Preform, but anyway, here’s some things about it, in no particular order, and maybe repeating what CrocMiam said or what you discovered yourself:

  • Yes, you can use Preform to modify how the compiler understands the source text that it is reading.
  • I did not experiment much with Preform and Inform 10.1, besides what’s known to be “safe” to use and included in a language extension. I haven’t tried to port the experimental French features (that try to fully translate the Preform into French) to Inform 10.1.
  • Some Preform definitions have to be read early enough by the compiler to work, but I haven’t really found a pattern. From earliest to latest:
    • Some have to be in the file Syntax.preform included in the language bundle. (Although if I remember correctly, there are no definition that need to be here to work on 6L38.)
    • Some have to be in the main source text. That’s the case for the if/else phrases on 6L38.
    • Some have to be in a language extension (the ones specified by a language bundle and included by writing (in French/Spanish/etc.) after the story title. The French extension (there’s an Inform 10 branch along the main 6L38 branch), for instance, contains the bare necessary for a translation.
    • You can also “cheat” by replacing a section of the language extension from a regular extension; it mostly works. That’s what the experimental French features (in the same repo) do.

There’s a file documenting all 6L02’s Preform definitions that ended in the French extension repo even if it was not supposed to. But I haven’t found a better home for it yet. (Maybe in the IF Archive?) Some definitions have changed in Inform 10, but unfortunately, I haven’t found an equivalent document for Inform 10. As stated in the Preform introduction:

Definitions like this one are scattered all across the Inform web, in order to keep them close to the code which relates to them.

So you have to search for them across Inform’s documentation, or infer their use by looking directly in the Syntax.preform file, which contains every rule.

Also, I haven’t managed to make some rules work (or I misunderstood them). For example, in French on 6L38, there’s one to make it possible to write la lampe is a thing (with “la” instead of “the” or “a”) and it will set the correct grammatical gender for the lamp. But this particular rule doesn’t exist anymore in Inform 10 and I couldn’t find its replacement.

All that to say that Preform is not well documented yet (I find it even worse than in 6L38). I just made a lot of experimentations to see how it works.

The next version of Inform will allow you to add a Syntax.preform file in a language bundle and I suppose that will be the “official” and “safest” way to add some Preform. (I think it’s already implemented so it’s possible to try it by compiling Inform yourself.) Actually, I’m not sure if sprinkling some Preform directly in your source text instead of using a language bundle is/will be encouraged (a bit like the I6 that is encouraged to stay in kits.)

Sorry for the rambling and if I didn’t really answered your questions… I’ll help more if I can.

Just to be clear, the dire phrases (i.e. French for “say”) are not set by the Preform shown in the previous post. It’s set by another independent Preform rule not shown, and a regular phrase created in the extension. It’s not relevant to the control structure thing.


Thank you both for sharing what you can. I am working my way through The English Syntax of Inform now (which Natrium729 has pointed out to me in the past – thank you again), and it is clear enough even if it is not up-to-date.

Perhaps I just picked a bad starting point with the <control-structure-phrases> non-terminal – certain other modifications seem to work.

EDIT: … and many pages of reading later, I got it figured out! (That was a bad starting point.)

Thank you again for the guidance, CrocMiam and Natrium729.

1 Like