We can’t drop any of those, but obviously the bracket form is somewhat ambiguous with the idea of throwing [; function code... ] in there. Joel’s proposal handles this by requiring the bracket form of arrays, as in the example above. But this is potentially confusing. Also I haven’t tested how the optional semicolons work.
Maybe we can disambiguate by looking for a semicolon after the first bracket? I’m not sure what’s possible here.
As you write, it makes sense. It is already a known syntax for writing inline routines in properties and me (with quite limited knowledge…) can’t see that the addition could break some old code.
For some context for some readers: you can already have references to functions in arrays and call them, you have to create them and name them yourself:
As someone who’s dabbled in I6, I like this idea. It would also make it easier to implement advanced menus or conversation menus using ext_menu.h or ext_talk_menu.h, since they use arrays in place of objects.
That’s what I hit, @blindHunter — trying to make a conversation system built with arrays.
Unfortunately, these can’t be a drop-in replacement for existing object-prop-arrays (you do have to access items differently (arr-->I vs obj.&prop-->I) and you’ll probably want to make it a ‘table’, so you have the length.
I believe we talked about it a few years ago, as it would be beneficial to the talk menu extension (part of the PunyInform library, but can also be used with the standard library if you’re targeting Z-code).
I would think the trickiest bit might be getting scope correct. Assuming we want scope to be correct? That’s the main reason to enclose arbitrary things in brackets, I think?
Never a problem in I6, funnily enough! The only sort of identifier that doesn’t have global scope is the function argument. If you want local variables for loops and such, you just declare that the function/routine takes more arguments than it actually does, and the extra ones are yours to use as you like.
Since arguments have to be declared at the top of a routine, their scope is always exactly that routine. Nice and simple! Just don’t ask how the compiler figures out whether something is an identifier instead of a keyword in the first place…
(As an experienced I6 author, you’re probably used to it by now, but it’s a neat quirk of the language that very few others have.)
I think so, yeah; making sure they’re balanced (so it doesn’t cause problems with if-statements and the like) but then ignoring them entirely. Presumably some part of I7 makes it easier to generate useless braces than to just…not.
This sounds right to me, @Draconis . There’s no advantage to the nested block, given the lack of scope stuff. Other than someone who just really, really wants to indicate the next 10 lines are related and group them up, they’d have no use. I also suspect, like you, the real reason would be to simplify i7-code-generation.
Unless: @zarf , would a block let you break out of the block (as do/while/for do). That would be sort-of-useful. But probably not what Graham meant.
Only slightly related: I’ve been building a language server for Inform6 to do stuff like IDE-like hover/structure/refactoring/identifier-matching and, as part of that, updated the Technical Manual’s BNF to modern Inform6. I’ve made an ANTLR4 grammar for it. Oh my is it a hairy language to build a grammar for simply, especially given the conditional-compilation stuff.
But I hope that once it’s complete and accurate (*), it might help anyone else that wants to make i6-parse-aware tools.
(*) currently, it parses all of the stdlib/puny/a few other large-ish inf files, so it’s probably at least somewhat close to right,