Now that 6.35 is out, I am thinking about what should go into the next release.
The big thing I’d love – about 15 years overdue – is to revamp the memory system from “allocate everything at the start” to “reallocate as you go.” This would (eventually) completely get rid of the dreaded
The memory setting FOO (which is N at present) has been exceeded. Try running Inform again…
I’d tackle this incrementally – one memory setting at a time. There are about 30 such settings, plus a few more hard limits which can only be updated by rebuilding the compiler.
Today I experimentally knocked out the MAX_CLASSES setting. (This patch is in a work branch, not yet merged.) That took a couple of hours of rearranging code. It’s not a trivial cut-and-paste task, but I could probably run through the most important settings over the course of a few months, dipping into one whenever I have a free evening.
(Question for the I6 users here: which are the most important memory settings? Which ones do you run into first when extending your game?)
I have an itch to improve the -a assembly output. (I started implementing this too.) This doesn’t affect code generation at all; it’s a matter of making the assembly trace output more readable.
Currently if you compile a line like
print (name) obj.owner;
…the -a output looks like this (also using -G -~S):
This is really not very enlightening. In fact it’s actively misleading, because the generated game file doesn’t contain the constants 10, 5, or 6 for this routine! Those are temporary values that get backpatched later in compilation.
The numeric values are still temporary, but at least you know what they refer to. It’s much easier to compare this assembly to the original source.
This assembly output happens inline as code is parsed. So there are limits on how much info we can generate at this stage. We don’t know final addresses yet. Forward-declared symbols have no type information. But we can at least say what symbol name every assembly operand represents.
(Question for the crowd: This isn’t going to break anybody’s project, is it? I don’t think that anybody is trying to parse inform -a output. But if you are, let me know.)
I don’t want to take this file as a TODO list. (Some items have been independently reinvented already.) But if you see any ideas that you want to make an argument for, go for it.
I just noticed yesterday that it outputs dead code in a situation this. It converts the branch to an unconditional jump, but still outputs the code inside.
if (0) {
...
}
(Actually technically the branches were more complex, possibly it’s smart enough already to know not to output a branch with a simple false constant like that?)
possibly it’s smart enough already to know not to output a branch with a simple false constant like that?
It’s not even that smart. But I suspect that authors would avoid writing such simple constants anyhow. (If you want code to be conditional on a compile-time constant, you’d use #ifdef rather than if.)
What more complex conditions are you running into, in real-life cases?
[ Noun_Filter_63
v ! value parsed
n ! saved value of noun
;
v = Kind_GPR_79();
if (v == GPR_NUMBER) {
n = noun; noun = parsed_number;
if (~~(((true) && (true)))) v = GPR_FAIL;
noun = n;
}
return v;
];
It’s not a big issue, I had to adjust my secret project to account for orphaned blocks, but it wasn’t hard at all.
Ooh, yeah, that’ll certainly make for a lot of dead code. I had forgotten about those.
The good news is that the compiler is smart enough to condense the expression down to “if false”. So fixing the simple case will get quite a lot of mileage on I7 code.
One difficulty is with dynamic branches/jumps and even inter-function jumps: the compiler can’t simply remove such blocks without potentially breaking code.
But dynamic branches and inter-function jumps must be super uncommon, does anything other than Glulxercise actually use them? We could say that files which use such features need to turn on a setting, and if the setting isn’t used then optimisations like dead code removal could be made.
If you like this idea I could look at adapting my algorithm for I6. (One difficulty would be flexible arrays, I’m not sure how you’d do them in C. Though if I’d need to do backpatching that would be a bigger difficulty!)
Dynamic branches (as in the computed_jump tests in Glulxercise) must be written in assembly at present. (Right?)
Inter-function jumps, same thing. That is, I think you could only do this if you laid out your target function with hand-crafted assembly.
We could say that files which use such features need to turn on a setting, and if the setting isn’t used then optimisations like dead code removal could be made.
That would work.
Another possibility is to define a convention: any jump label is assumed to be “live” even if the compiler doesn’t see a jump to it. So you could avoid dead code removal by writing:
I don’t think I’ve ever hit any Inform 6 limits, until recently when I had to increase MAX_FLOATING_OBJECTS from 32 to 40, although that may have been a PunyInform limit.
I think you’re suggesting a new graphics API for games to use? That would require new interpreters. For this thread, I’m only looking at possible improvements to the I6 compiler and language.