Skip to content

Commit

Permalink
Add some type safety to the hyperlink framework
Browse files Browse the repository at this point in the history
  • Loading branch information
curiousdannii committed Jul 27, 2024
1 parent be162bd commit 0264145
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 25 deletions.
25 changes: 13 additions & 12 deletions inform7/Internal/Extensions/Graham Nelson/Basic Inform.i7x
Original file line number Diff line number Diff line change
Expand Up @@ -1821,40 +1821,41 @@ Chapter - Hyperlinks

A hyperlink tag is a kind of value.

The hyperlink value is a number variable.
The hyperlink value variable is defined by Inter as "hyperlink_value".

The hyperlink handling rules is a hyperlink tag based rulebook.
The hyperlink handling rules is accessible to Inter as "HYPERLINK_HANDLING_RB".

The handle hyperlinks rule is listed in the glk event handling rules.
The handle hyperlinks rule is defined by Inter as "HANDLE_HYPERLINK_R".

To say link (T - hyperlink tag):
(- MakeTaggedHyperlink({T}); -).

To say link (T - hyperlink tag) of (V - value of kind K):
(- MakeTaggedHyperlink({T}, {-by-reference:V}, {-strong-kind:K}); -).

To say end link:
(- if (Cached_Glk_Gestalts-->gestalt_Hyperlinks) { glk_set_hyperlink(0); } -).

To decide what K is hyperlink value as a/an (name of kind of value K):
(- (hyperlink_value) -).


Rule hyperlink is a hyperlink tag.

To say link (R - rule):
(- MakeTaggedHyperlink((+ rule hyperlink +), {R}); -).
(- MakeTaggedHyperlink((+ rule hyperlink +), {-by-reference:R}, RULE_TY); -).

Hyperlink handling rule for a rule hyperlink (this is the rule hyperlink rule):
run rule at address hyperlink value;
follow hyperlink value as a rule;

Keypress hyperlink is a hyperlink tag.

To say link (C - unicode character):
(- MakeTaggedHyperlink((+ keypress hyperlink +), {C}); -).
(- MakeTaggedHyperlink((+ keypress hyperlink +), {-by-reference:C}, UNICODE_CHARACTER_TY); -).

Hyperlink handling rule for a keypress hyperlink (this is the keypress hyperlink rule):
set the glk event type to character event;
now glk event value 1 is hyperlink value;

Section - unindexed

To run rule at address (R - number):
(- ({R})(); -).
now glk event value 1 is hyperlink value as a number;

Chapter - Suspending and resuming input

Expand Down
28 changes: 27 additions & 1 deletion inform7/Internal/Inter/Architecture32Kit/Sections/Glk.i6t
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,10 @@ A simple framework for handling hyperlinks in an interoperable manner.
We combine a hyperlink tag with a payload in one 32-bit value. The tag is stored
in the lowest bits, and the payload above it.

|CALCULATE_HYPERLINK_TAG_WIDTH_R| is a |before starting the virtual machine| rule,
which gets the number of options in the hyperlink tag enum and sets the tag/payload
masks and widths accordingly.

=
Global hyperlink_payload_mask;
Global hyperlink_tag_mask;
Expand All @@ -453,8 +457,30 @@ Global hyperlink_value;
rfalse;
];

[ MakeTaggedHyperlink tag val;
@ |MakeTaggedHyperlink| combines the tag and value into one 32 bit hyperlink ID,
checking that the value is not a pointer to ephemeral data (on the stack).

|HANDLE_HYPERLINK_R| then extracts tag and value from an ID, expanding the value
back to 32 bits.

=

[ MakeTaggedHyperlink tag val kind;
if (Cached_Glk_Gestalts-->gestalt_Hyperlinks) {
#Ifdef DEBUG;
if (val >= blockv_stack && val < (blockv_stack + BLOCKV_STACK_SIZE * WORDSIZE)) {
if (kind) {
if (KindConformsTo_POINTER_VALUE_TY(kind)) {
! Break up the message so that Inform doesn't think it's an Inter invocation
print "Error: cannot make hyperlink from ephemeral value; try creating with {", "-by-reference:V}^";
return;
}
}
else {
print "Warning: hyperlink value might be ephemeral; try creating with explicit kind^";
}
}
#Endif; ! DEBUG
if (val > 0) {
@shiftl val hyperlink_tag_width val;
}
Expand Down
25 changes: 13 additions & 12 deletions inform7/extensions/basic_inform/Sections/Glulx and Glk.w
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,24 @@ Chapter - Hyperlinks

A hyperlink tag is a kind of value.

The hyperlink value is a number variable.
The hyperlink value variable is defined by Inter as "hyperlink_value".

The hyperlink handling rules is a hyperlink tag based rulebook.
The hyperlink handling rules is accessible to Inter as "HYPERLINK_HANDLING_RB".

The handle hyperlinks rule is listed in the glk event handling rules.
The handle hyperlinks rule is defined by Inter as "HANDLE_HYPERLINK_R".

To say link (T - hyperlink tag):
(- MakeTaggedHyperlink({T}); -).

To say link (T - hyperlink tag) of (V - value of kind K):
(- MakeTaggedHyperlink({T}, {-by-reference:V}, {-strong-kind:K}); -).

To say end link:
(- if (Cached_Glk_Gestalts-->gestalt_Hyperlinks) { glk_set_hyperlink(0); } -).

To decide what K is hyperlink value as a/an (name of kind of value K):
(- (hyperlink_value) -).

@ And some built-in hyperlink tags:

- A rule hyperlink runs a rule when clicked; that in turn allows you to run any other code you like.
Expand All @@ -180,24 +186,19 @@ To say end link:
Rule hyperlink is a hyperlink tag.

To say link (R - rule):
(- MakeTaggedHyperlink((+ rule hyperlink +), {R}); -).
(- MakeTaggedHyperlink((+ rule hyperlink +), {-by-reference:R}, RULE_TY); -).

Hyperlink handling rule for a rule hyperlink (this is the rule hyperlink rule):
run rule at address hyperlink value;
follow hyperlink value as a rule;

Keypress hyperlink is a hyperlink tag.

To say link (C - unicode character):
(- MakeTaggedHyperlink((+ keypress hyperlink +), {C}); -).
(- MakeTaggedHyperlink((+ keypress hyperlink +), {-by-reference:C}, UNICODE_CHARACTER_TY); -).

Hyperlink handling rule for a keypress hyperlink (this is the keypress hyperlink rule):
set the glk event type to character event;
now glk event value 1 is hyperlink value;

Section - unindexed

To run rule at address (R - number):
(- ({R})(); -).
now glk event value 1 is hyperlink value as a number;

@h Suspending input.
These properties and phrases allow the author to suspend and resume input requests.
Expand Down

0 comments on commit 0264145

Please sign in to comment.