10.2/11.0 Working development version of Dynamic Objects / Dynamic Tables (by Tara McGrew)

I think it would be possible, with a lot of hacky code. The phrase in question is

To decide which number is number of (S - description of values)
	(documented at ph_numberof):
	(- {-primitive-definition:number-of} -

We can replace this phrase. If you do a bit of sneaky bytecode introspection, then you can work out if it’s a constant or a function call. If it’s a constant then we can check if the kind is a subkind of object, and if that’s true then calculate the new number of objects in the kind. Otherwise return the original result.

Bytecode introspection

Through the @catch instruction you can get the address of a statement, and thereby find out what its opcode is. Here’s an example I’ve been working on for an inline hyperlinks extension which gets the address of the text between the text substitutions without printing it.

To say link -- beginning say_replacement_command_link -- running on:
	(-
		{-counter-up:InlineLink_Catch}
		{-counter-up:InlineLink_CatchC}
		{-counter-up:InlineLink_After}
		! Get the address of the next statement via @catch
		jump {-label:InlineLink_Catch};
		.{-label:InlineLink_CatchC};
		@pull {-my:1};
		@pull {-my:1};
		TAGGED_HYPERLINK_TY_Inline_Text({-my:1});
		! Clean up the rest of the call stub
		@pull {-my:1};
		@pull {-my:1};
		jump {-label:InlineLink_After};
		.{-label:InlineLink_Catch};
		@catch {-my:1} {-label:InlineLink_CatchC};
	-).

To say as -- ending say_replacement_command_link -- running on:
	(- .{-label:InlineLink_After}; -).

Include (-
[ TAGGED_HYPERLINK_TY_Inline_Text addr;
	print "TAGGED_HYPERLINK_TY_Inline_Text ", addr, ": ", (addr->0), " ", (addr->1), " ", (addr->2), "^";
	! Expect a @callf to ParaContent
	if (addr->0 == 129 && addr->1 == 96 && addr->2 == 3) {
		if ((addr + 3)-->0 == ParaContent) {
			! Now @streamstr
			if (addr->7 == 114 && addr->8 == 3) {
				print  (addr + 9)-->0, (string) (addr + 9)-->0, "^";
				TAGGED_HYPERLINK_TY_New(inline_replacement_hyperlink, (addr + 9)-->0, NUMBER_TY, 1);
				rfalse;
			}
		}
	}
	print "err";
];
-).
3 Likes