[I7] converting a text to a number

Is there any way to convert a text to its numerical equivalent? Like:

let P be "54"; let half-P be the numerical value of P divided by 2;

Test Chamber is a room.

To decide which number is the numerical value of (T - text):
	let index be the number of characters in T;
	let sum be 0;
	let multiplier be 1;
	while index > 0:
		now sum is sum + (multiplier * the single character numerical value of character number index in T);
		now multiplier is multiplier * 10;
		now index is index - 1;
	decide on sum.

To decide which number is the single character numerical value of (T - text):
	[does I7 have a switch statement?]
	[both "0" and nondigit characters contribute a value of 0 to the sum]
	let D be 0;
	if T is "1":
		now D is 1;
	otherwise if T is "2":
		now D is 2;
	otherwise if T is "3":
		now D is 3;
	otherwise if T is "4":
		now D is 4;
	otherwise if T is "5":
		now D is 5;
	otherwise if T is "6":
		now D is 6;
	otherwise if T is "7":
		now D is 7;
	otherwise if T is "8":
		now D is 8;
	otherwise if T is "9":
		now D is 9;
	decide on D.
		
When play begins:
	Let P be "54";
	say "the numerical value of P is [the numerical value of P].";
	let half-P be the numerical value of P divided by 2;
	say "half-P is [half-P]."

The second phrase is so long because “character number n in T” provides a text of length 1 rather than a character. Otherwise, we could do something like:

To decide which number is the numerical value of (C - character):
	(- ({C} - '0') -).

Also, this lacks validation that the whole string is comprised of nothing but digits. Something as simple as adding a trailing space to the number will break the algorithm. That could be fixed by only considering the prefix of the string that’s entirely digits and setting the initial value of index accordingly rather than setting it blindly to the length of the string.

if T is: -- "1": now D is 1; -- "2": now D is 2; -- "3": now D is 3; -- "4": now D is 4; -- "5": now D is 5; -- "6": now D is 6; -- "7": now D is 7; -- "8": now D is 8; -- "9": now D is 9;
See the documentation: §11.8. Otherwise

@A J: Thanks. Doesn’t seem to work in this instance (with 6L38) because T (a text) isn’t a word value, but good to know.

So, in an effort not to be lazy, I’ve implemented the fix for trailing junk that I mentioned in my previous post. Edit: also leading whitespace and negative numbers. Here’s the new code:

Test Chamber is a room.

To decide which number is the numerical value of (T - text):
	[allow leading whitespace or minus signs]
	let start be 1;
	let negation multiplier be 1;
	repeat with i running from start to the number of characters in T:
		let char be character number i in T;
		if char is not " " and char is not "-":
			break;
		[allow leading minus sign to negate sum. can do this more than once.]
		if char is "-":
			now negation multiplier is negation multiplier * -1;
		now start is start + 1;
	[only consider prefix of T containing digits]
	let index be the number of characters in T;
	repeat with i running from start to the number of characters in T:
		if character number i in T is not a digit:
			now index is i - 1;
			break;
	[proceed from back to front accumulating a sum, first considering 1s place, then 10s place, and so on]
	let sum be 0;
	let multiplier be 1;
	while index >= start:
		now sum is sum + (multiplier * the single character numerical value of character number index in T);
		now multiplier is multiplier * 10;
		now index is index - 1;
	decide on sum * negation multiplier;

To decide whether (T - text) is not a digit:
	if T is "0" or T is "1" or T is "2" or T is "3" or T is "4" or T is "5" or T is "6" or T is "7" or T is "8" or T is "9", decide no;
	decide yes.

To decide which number is the single character numerical value of (T - text):
	[both "0" and nondigit characters return a value of 0]
	let D be 0;
	if T is "1":
		now D is 1;
	otherwise if T is "2":
		now D is 2;
	otherwise if T is "3":
		now D is 3;
	otherwise if T is "4":
		now D is 4;
	otherwise if T is "5":
		now D is 5;
	otherwise if T is "6":
		now D is 6;
	otherwise if T is "7":
		now D is 7;
	otherwise if T is "8":
		now D is 8;
	otherwise if T is "9":
		now D is 9;
	decide on D.
		
When play begins:
	Let P be "54";
	say "the numerical value of P is [the numerical value of P].";
	let half-P be the numerical value of P divided by 2;
	say "half-P is [half-P].";

Why not let Inform’s parser do the work for you? This is a bit hacky but works.

To decide what number is the numerical equivalent of (T - text):
	let Z be the player's command;
	let N be -1;
	change the text of the player's command to T;
	if the player's command matches "[number]":
		let N be the number understood;
	change the text of the player's command to Z;
	decide on N.

Basically you swap out the player’s command temporarily, have it parse your number, then put the command back again. (Note however that this will clobber “the number understood” and related variables, so save them before use. A better version of this phrase might push them to the stack before parsing the number.)

Ah, that’s clever. Thanks!

And there’s some code to save the number understood here. (The code for “topic understood” will work as is, since all the “the foo understood” phrases refer to the same I6 thing, as I understand it.) So I guess you can do this (but I haven’t tested it):

[code]Parsed-number is a number that varies. The parsed-number variable translates into I6 as “parsed_number”.

Temporary-parsed-number is a number that varies.

To cache the topic understood: now temporary-parsed-number is parsed-number.

To restore the topic understood: now parsed-number is temporary-parsed-number.

To decide what number is the numerical equivalent of (T - text):
cache the topic understood;
let Z be the player’s command;
let N be -1;
change the text of the player’s command to T;
if the player’s command matches “[number]”:
let N be the number understood;
change the text of the player’s command to Z;
restore the topic understood;
decide on N.[/code]