Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IE-0014: Inter names for rulebooks #14

Merged
merged 1 commit into from
Oct 24, 2022
Merged

IE-0014: Inter names for rulebooks #14

merged 1 commit into from
Oct 24, 2022

Conversation

curiousdannii
Copy link
Collaborator

@curiousdannii curiousdannii commented Oct 24, 2022

  • Proposal: IE-0014
  • Authors: Graham Nelson
  • Language feature name: --
  • Status: Draft
  • Related proposals: IE-0013
  • Implementation: Implemented but unreleased

Summary

A purely additive change to the translates into Inter as... sentence syntax,
allowing explicit Inter identifier names to be assigned to be rulebooks and
activities created in source text. In particular, this allows kits to access
rulebooks and activities created in extensions.

@curiousdannii curiousdannii merged commit 152ae84 into main Oct 24, 2022
@curiousdannii curiousdannii deleted the ie-0014 branch October 24, 2022 02:57
@curiousdannii curiousdannii added the formal-proposal A formal proposal that has been accepted for consideration by the core Inform team label Oct 24, 2022
@uecasm
Copy link

uecasm commented Dec 20, 2022

Possible alternative (since I just encountered some examples while hacking at Flexible Windows):

In 9.3, given a kind of object and a property declared for that kind of object in the I7 source text, you could mix the two in a relatively nice way:

To call glk_set_window for (win - a g-window):
	(- glk_set_window( {win}.(+ ref number +) ); -).

Include (-
[ CallGlkSetWindow win;
    glk_set_window( win.(+ ref number +) );
];

[ SetWinRef win ref;
    win.(+ ref number +) = ref;
];
-).

(Things were less nice for "either-or properties", since they'd already been hidden behind a function.)

In v10, these things no longer work -- the (+ ref number +) apparently expands to an undefined value P_ref_number and properties aren't simple I6 properties any more but need an indirection via an additional function call.

(On that note, I was expecting GProperty(OBJECT_TY, win, (+ ref number +)) to work, and it doesn't.)

But why? Why not detect these property read/write patterns and compile them to the needed internal function call without cluttering the source text with such details? Why require explicitly specifying an I6 identifier to "translate" or be "accessed" instead of just letting it pick something automatic from the I7 name? Why can't we have the 9.3 syntax back? Especially now that the I6 code is also compiled to Inter, it seems like it ought to be easy to detect a property read/write and translate it to a function call if that's needed.

Alternatively, perhaps moving things even further to the I7 syntax -- the above could be rewritten as something like:

To call glk_set_window for (win - a g-window):
	(- glk_set_window( (+ ref number of win +) ); -).

Include (-
[ CallGlkSetWindow win;
    glk_set_window( (+ ref number of {win} +) );
];

[ SetWinRef win ref;
    (+ now ref number of {win} is {ref} +);
];
-).

(Though the caveat with this last option is that the I6 has lost some of the value kind metadata, but perhaps there could be some kind of annotation for that.)

@curiousdannii
Copy link
Collaborator Author

curiousdannii commented Jul 15, 2023

I'm getting an error when trying to make a rule which is defined in I7 accessible to Inter.

You wrote 'The preserve suspended text input rule is accessible to Inter
as "PRESERVE_SUSPENDED_TEXT_INPUT_R"' (Basic Inform, line 1573): but this
is a language construct which cannot be given an Inter name except by
defining it from Inter, so although you can say 'X is defined by Inter as
Y' to make this available to source text, you cannot say 'X translates into
Inter as Y' or 'X is accessible to Inter as Y'.

Also it seems like there's no "accessible to Inter" option for phrases, is that correct?

@ganelson
Copy link
Owner

I think there are two different requests here. One is to make rule definitions accessible. That may be possible. The other, to do with phrases, probably isn't. (For named phrases, it might be.) The trouble is that phrases have all manner of implementations under the hood: some are inlined, some are polymorphic and are represented by multiple functions at runtime depending on the kinds of value they are applied to. So there's no such thing, exactly, as "the value at runtime of a phrase".

@curiousdannii
Copy link
Collaborator Author

Oh, I hadn't thought of polymorphism. That does complicate matters. But hopefully not too much, hopefully there's a subset of phrases which can be made accessible.

Sometimes it's just much better to author code in I7, but we need to call that code from I6. If we absolutely needed to do that at present I guess we could make a rulebook with a single rule in it, but that's a little bloated, and restricts you to one parameter. (We could get around that restriction if necessary by setting global variables. Which should work fine enough, unless the code wants to be recursive...) If named phrases with no generic parameters could be made accessible I think those would be acceptable restrictions.

As an example, Flexible Windows in 6M62 has this I6 function, which then invokes a bunch of quite involved I7 code, which would be much less elegant if it had to be converted to I6 code.

[ glk_window_open parent method size type rock result;
	result = ( (+ handling an unscheduled construction +)-->1 )( parent, method, size, type, rock );
	if ( result == 0 )
	{
		return FW_glk_window_open( parent, method, size, type, rock );
	}
	return result;
];
To decide which number is the result from handling an unscheduled construction from (parent - a number) with method (method - a number) and size (size - a number) and type (type - a number) and rock (rock - a number) (this is handling an unscheduled construction):
	let parent win be the window with ref parent;
	let win be the window with rock rock;
	if parent win is the invalid window or win is the invalid window:
		decide on 0;
	now win is spawned by parent win;
	now the position of win is the position from method;
	now the scale method of win is the scale method from method;
	now the measurement of win is the size;
	now the type of win is the type from type;
	open win;
	decide on the ref number of win;

To open up/-- (win - a g-window), as the acting main window:
	if win is g-unpresent and (win is the main window or the main window is ancestral to win):
		now win is g-required;
		now every g-window ancestral to win is g-required;
		calibrate windows;
		if as the acting main window:
			set win as the acting main window

To calibrate windows:
	[ Close windows that shouldn't be open and then open windows that shouldn't be closed ]
	while there is a not currently being processed g-unrequired g-present childless g-window (called win):
		[ Only run each window once, even if we end up back in this loop (by open/close being called in a before rule), to prevent infinite loops ]
		now win is currently being processed;
		safely carry out the deconstructing activity with win;
		now win is not currently being processed;
	while there is a not currently being processed g-required g-unpresent next-step g-window (called win):
		now win is currently being processed;
		safely carry out the constructing activity with win;
		now win is not currently being processed;

The handling an unscheduled construction phrase could be converted to I6 easily enough (especially now with kit defined enums), but the open up and calibrate phrases use one of those most beautiful I7 features, descriptions. They would be real hard to convert to I6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
formal-proposal A formal proposal that has been accepted for consideration by the core Inform team
Projects
None yet
3 participants