Inserting new values into a KoV already defined?

Okay, here’s my problem:

Say there’s an extension that says Color is a kind of value. The colors are red, green, and blue.

Now say I want my code to add options, by saying The colors are red, orange, yellow, green, blue, and violet.

If I do this, and then go to look at the kind in the Index, they’ll be listed as red, green, blue, orange, yellow, and violet, and repeating running through them will also have them in that order.

Is there any way to insert options into an existing kind of value, or to completely redefine it? Or am I doomed to copy the extension into the local project and modify it directly?

You can just add the ones that you want after the original definition:

Some colors are orange, yellow and violet.

Watch the capitalization if you use the form:

orange, yellow and violet are colors.

EDIT: I see that I misread the details of your question. Sorry about that; expanded answer below.

You can only add new values at the end.

If you want a custom order, you could define a global list of colors in your code and repeat through that.

Internally, the specific values for a kind of value are all just constant integer values. So, theoretically, it should be possible to do something like:

Include
(-
#Undef (+ red +);
#Undef (+ orange +);
#Undef (+ yellow +);
#Undef (+ green +);
#Undef (+ blue +);
#Undef (+ purple +);
Constant (+ red +) = 1;
Constant (+ orange +) = 2;
Constant (+ yellow +) = 3;
Constant (+ green +) = 4;
Constant (+ blue +) = 5;
Constant (+ purple +) = 6;
-) after "Object Tree" in "Output.i6t".

such that the ordering of the colors is modified. However, this doesn’t seem to work in practice, specifically because of the routine that is compiled to print the names of colors (the exact name of which varies depending on your source code), which in this case is something like:

[ E67 
    value ! Implied call parameter
    ;
    switch(value) {
        I132_red: print "red";
        I133_green: print "green";
        I134_blue: print "blue";
        I135_orange: print "orange";
        I136_yellow: print "yellow";
        I137_purple: print "purple";
        default: print "<illegal color>";
    }
];

This routine appears in generated code before the actual declaration of color constants. Perhaps surprisingly, its behavior is exactly the same with the above in place. The reason appears to be that the compiler (and here I mean the Inform 6 compiler) may not be taking into account the redefinition of declared constants via the #Undef directive when composing the underlying opcodes for the routine – instead it appears that the compiler is just looking ahead to the first definition of a constant that it does not recognize as previously declared, then using that definition.

Although I wouldn’t necessarily recommend it, this can be worked around at the I6 level.

Include
(-
Constant (+ red +) = 1;
Constant (+ orange +) = 2;
Constant (+ yellow +) = 3;
Constant (+ green +) = 4;
Constant (+ blue +) = 5;
Constant (+ purple +) = 6;
-) before "Printing Routines" in "Output.i6t". [declares order that you want ahead of normal I7 compiler definitions]

Include
(-
#Undef (+ red +);
#Undef (+ orange +);
#Undef (+ yellow +);
#Undef (+ green +);
#Undef (+ blue +);
#Undef (+ purple +);
-) before "Object Tree" in "Output.i6t". [undefines your order so that normal I7 compiler definitions are allowed]

Include
(-
#Undef (+ red +);
#Undef (+ orange +);
#Undef (+ yellow +);
#Undef (+ green +);
#Undef (+ blue +);
#Undef (+ purple +);
Constant (+ red +) = 1;
Constant (+ orange +) = 2;
Constant (+ yellow +) = 3;
Constant (+ green +) = 4;
Constant (+ blue +) = 5;
Constant (+ purple +) = 6;
-) after "Object Tree" in "Output.i6t". [undefines normal I7 compiler definitions and reinstates your preferred order]

It may be simpler to just modify the extension, especially given that the default value will still be hardcoded as the first one listed by the original declaration (though that’s not an issue in this particular case). Or go with zarf’s suggestion.

Thanks so much all! This was a huge help. I’ll probably end up forking the extension anyway, so I guess I’ll end up going that route.

Oh my god, I just realized this morning that there’s a much, much easier solution: predefine the kind and its values before including the extension. Bam, problem solved.

4 Likes