I’m having a problem back-porting a tweaked extension with I6 inclusions in it.
First, i’ve got this, lifted and extended from Gender Options by Nathanael Nerode:
A thing can be neuter. A thing is usually neuter.
A thing can be male. A thing is usually not male.
A thing can be female. A thing is usually not female.
A thing can be nomale. A thing is usually not nomale.
The nomale property translates into I6 as "nomale".
<snip>
A nonbinary is a kind of person.
The specification of nonbinary is "Represents a person who identifies as a gender other than male or female."
A nonbinary is usually nomale.
A nonbinary is usually not male.
A nonbinary is usually not female.
A nonbinary is usually not neuter.
I get a translation error:
Expected name of an already-declared attribute but found nomale
which links to auto.inf, e.g.:
Class K12_nonbinary
class K8_person
with plural BC_43
has ~neuter
has ~male
has ~female
has nomale
with description BC_44
with initial BC_45
with list_together BC_46
with short_name BC_47
with article BC_48
Scanning auto.inf, I can’t see any difference between the declaration of the constant nomale and those of male, female, and neuter. So I’m a bit stumped.
Obviously most of the detail is omitted, so I’m just looking for a direction to look in. Thanks!
6M62 declares all the attributes up front in Definitions.i6t:
Attribute male; ! not directly used by I7, but available for languages with genders
Attribute female; ! = I7 "female" vs "male"
Attribute neuter; ! = I7 "neuter"
In more detail, I6 has three types of ‘property’- Attributes (declared with Attribute), common properties (declared with Property) and individual properties (declared within class or object definitions with with).
I7 just has properties, but under the hood they will be translated into one of these three I6 types.
New properties you declare in I7 will be translated as individual properties declared within class/object definitions, which don’t require a separate declaration line in I6, unless they are either-or properties- in which case they will usually translate as Attributes, requiring a separate declaration line Attribute ...; which if you want a particular I6 name translation you must provide yourself as an I6 inclusion.
small print there are only a limited number of Attributes available in I6 and if these are exhausted (unlikely except in very large projects or ones using many extensions) either-or properties will be translated to I6 as individual properties instead- something which would need to be dealt with on a case-by-case basis as since Ver 10 in particular, there’s no easy way to tell programmatically whether an either-or I7 property is/will be an Attribute or an individual property… see more detailed discussion here and here
Notably, though, individual properties are not supported by Inter, so if you want to use “translates as” you have to explicitly make it an Attribute or a Property. This can cause problems on the Z-machine where there’s a hard limit on the number of Properties as well as the number of Attributes.
Yes, but you can’t define them in Inter, which means you can’t reference them in Inter code (i.e. I6 as opposed to I7). This means any properties you want to reference in Inter code need to eat into the limited supply of Attributes and Properties.
“Inter” is the new name for I6 used by I7, from version 10 onward. That is, the code that’s in Include (- -) and I6T (“kit”) files.
In version 10, you cannot use “translates as” for an individual property. Only for Attributes and Properties. This means you can define individual properties in I7, but cannot (usually) reference them in Inter code. Any property accessed by Inter code has to be an Attribute or a Property.
Inter is an new intermediate ‘bytecode-type’ language separate to I6 and I7 to which I6 “kit” files are precompiled and to which I6 inclusions (- -) and I7 source are both compiled, before merging into a single Inter program (Inform calls this the Inter Tree) which is then further compiled to I6 (appearing as the auto.inf file), or C, or (potentially) other languages. The final stage of compilation is the I6 output being compiled to a glulx or Z-machine story file, or in the case of C to a stand-alone executable file. see here.
It is true that in Ver 10 you can now say ‘translates to Inter’ rather than ‘translates to I6’ but the effect is the same- the specified name is carried through via the intermediate Inter code to the final I6 output code.
From the point of view of this discussion, The hue property translates to Inter as "hue" still works as it always did, to produce a corresponding individual property called ‘hue’ in the I6 output of I7 compilation (albeit now through the intermediary of Inter code)
This is the issue I’m referring to: defining an individual property using with in Inter inclusions (or I6 inclusions if you prefer) causes a compilation failure, so it has to be defined with Property beforehand, making it common.
Happily, that particular method of defining new individual properties directly within I6 inclusions- Include (-...-) when defining a ...- now works: in particular Zed’s index code from that thread now compiles without issue and puts said individual properties into the definition of the door class.
It’s a deprecated usage according to the documentation, but currently still functions- albeit buggily in that some attempts to use I7 expansions (+ …+) within properties so defined fail to compile correctly.
I’ve filed bug reports along those lines several months back which are awaiting attention.
What you still can’t do, as far as I am aware, is define an individual property in that particular way and at the same time set up an I7 alias for it using the (I7-property) property translates into Inter as "(I6-property)" presumably because at the point of I7 compilation the new I6 properties are yet to be ‘glued in’. You have to create the property in I7 first, then the I6 alias from it using the (I7-property) property translates... Which limits somewhat the varieties of I6 property that can be aliased. Is that what you mean?
EDIT you can work around this last restriction if you really need to with I7 code ‘To decide…’ or ‘Definition:’ that references the known I6 property names, e.g.
To decide which number is the mobile flag of (d - a door): (- {d}.mobile -).
EDIT2 Hmm. Actually that doesn’t seem to work- although the plain code above happily compiles, as soon as you include an I7 source reference to ‘the mobile flag of…’ compilation fails because the mobile property doesn’t yet exist at that stage of I7 compilation- presumably because it’s glued in later as an I6 ‘splat’. I’m guessing that if you really needed this, it might be possible to do something in a kit so that it’s incorporated earlier in the compilation process??
I guess, to be fair, that the likelihood of using up all 22 available common properties (after the Standard Rules have taken their share) through needing to define them with this particular syntax in a project small enough to compile from I7 Ver 10 to Z-machine is pretty slim…
This is true! But giving users the freedom to make certain properties common (to save precious RAM on the Z-machine) seems valuable for optimization, and making it fit on the Z-machine in the first place.