******* TO DO: IMPROVE THIS PAGE OF DOCUMENTATION. *******
An easy facility for efficiently translating a number in a set of numbers to a different number (also works with text).
You can do that using "switch" (example follows):
var destVar, uint;
switch sourceVar;
case 123;
set destVar, 1;
case 666;
set destVar, 2;
case 46;
set destVar, 7;
case 99;
set destVar, 8;
case 300 .. 399;
set destVar, 10;
case 2;
case 5;
case 7;
set destVar, 20;
default:
set destVar, 0;
eswitch;
Switch is a great feature, but it is not exactly designed for the particular purpose of translating a number to another number.
A specialized efficient facility for doing that:
translate sourceVar, destVar;
aso 123, 1;
aso 666, 2;
aso 46, 7;
aso 99, 8;
aso 300 .. 399, 10;
aso 2 5 7, 20;
default 0;
etranslate;
The "aso" command defines an association. The value in the first parameter is associated with the value in the second parameter. It must be possible for the compiler to determine both values at compile-time (as opposed to runtime).
As a shortcut, "translate blah;" means same as "translate blah, blah;" (translate in-place).
"aso 123, 1;" means if the source number is 123, then translate it to 1.
"aso 300 .. 399, 10;" means if the source number is in the range 300 to 399 inclusive, then translate it to 10.
"aso 2 5 7, 20;" means if the source number is 2, 5, or 7, then translate it to 20. Or maybe the syntax should be "aso (2,5,7), 20;". This could also be written as 3 separate commands (as follows). The final program code is exactly the same in either case.
aso 2, 20; aso 5, 20; aso 7, 20;
"default 0;" means if none of the translations matched, then translate the number to 0. If "default" is omitted, then the destination variable is unchanged.
If "default" has 3 parameters, they mean respectively:(1) Default value if source is less than all of the translations,
(2) default value if source is within the min/max of the translation range but not matching any,
(3) default value if source is greater than all the translations.
The translation works with both numbers and text (num to num, text to text, num to text, and text to num). And ofcourse it works with named constants as well as numbers or text specified directly.
The above example performs the translation immediately on-the-spot, as does "switch". It is also be possible to define a named translation, and then use that named translation in multiple places:
{Make named translation definition}
translation FoodNameToID;
aso "Burrito", 1;
aso "Nacho", 2;
aso "Taco", 3;
aso "Pizza", 8;
default 0;
etranslation;
{Perform translation using named definition}
ntranslate FoodNameToID, sourceVar, destVar;
The translation can be performed in reverse using the same named definition. Simply use the "ntranslaterev" command instead of "ntranslate". If "ntranslate" translates "Taco" to 3, then "ntranslaterev" translates 3 to "Taco".
Translations are NOT performed using a simple slow linear search. Instead a fast look-up table, binary search, or hashing method is used. Or if there are only a few associations, it might be converted to "if" / "elif" commands. The compiler analyzes the list of associations to help it decide which method to use based on which will most likely yield the best speed while not consuming an excessive amount of memory.
When performing a translation, if there are multiple matches, the first one appearing in the list of associations is used. For example, if the list of associations contains:
aso 7, 20; aso 2, 20; aso 5, 20;
And the translation is being performed in reverse, then there are 3 matches for "20". The first one will be used. Thus "20" is translated to "7" in this example (the other 2 associations for "20" are not included in the reverse look-up table).