resolveIt.sas
/* Richard A. DeVenezia
* www.devenezia.com
*
* Originally posted to SAS-L Feb 7, 2004
*/
%macro resolveIndirectAddressing (tokenValue, resolutionTemplate, trace=0);
%local
level
levelTemplate
token
initialTokenValue
intermediatetokenValue
lengthResolutionTemplate
p0
p1
guard
maxGuard
done
;
%let maxGuard = 10;
%if &trace %then
%let initialTokenValue=&tokenValue;
%let resolutionTemplate = &resolutionTemplate->;
%let lengthResolutionTemplate = %length (&resolutionTemplate);
%let guard = 1;
%let level = 0;
%let p0 = 0;
%let p1 = 0;
%let done = 0;
%do %while (not &done) ;
%let level = %eval (&level+1);
%let p0 = %eval (&p0+&p1+1);
%if &p0 > &lengthResolutionTemplate
%then %let p1 = 0;
%else %let p1 = %index (%substr(&resolutionTemplate,&p0),->);
%if &p1 = 0 %then
%let done = 1;
%else %do;
%if &trace %then
%let intermediateTokenValue = &tokenValue;
%* the crux of resolving the indirect addressing;
%let levelTemplate = %substr(&resolutionTemplate,&p0,%eval(&p1-1));
%let templateResolved = %sysfunc (tranwrd (&levelTemplate,:,&tokenValue));
%let tokenValue = &&&templateResolved;
%if &trace %then
%put intermediateTokenValue=&intermediatetokenValue levelTemplate=&levelTemplate templateResolved=&templateResolved newTokenValue=&tokenValue;
%end;
%let guard = %eval(&guard + 1);
%if &guard > &maxGuard %then %do;
%put ERROR: resolveIt exceeded the guard limit of &maxGuard;
%let done = 1;
%end;
%end;
%if &trace %then %do;
%let level = %eval(&level-1);
%put NOTE: initial token value: &initialTokenValue;
%put NOTE: resolutionTemplate: &resolutionTemplate;
%put NOTE: &level levels resolved.;
%put NOTE: final resolution: &tokenValue;
%end;
&tokenValue
%mend; Sample code
%let i=1; %let a1=2; %let b2=3; %let c3=4; %let d4=5; %let e5=6; %let f6=7; %put %resolveIndirectAddressing (&i, a:->b:->c:->d:->e:->f:); %let i=1; %let a1z=2; %let b2y=3; %let c3x=4; %let d4w=5; %put %resolveIndirectAddressing (&i, a:z->b:y->c:x->d:w, trace=1);
intermediateTokenValue=1 levelTemplate=a:z templateResolved=a1z newTokenValue=2 intermediateTokenValue=2 levelTemplate=b:y templateResolved=b2y newTokenValue=3 intermediateTokenValue=3 levelTemplate=c:x templateResolved=c3x newTokenValue=4 intermediateTokenValue=4 levelTemplate=d:w templateResolved=d4w newTokenValue=5 NOTE: initial token value: 1 NOTE: resolutionTemplate: a:z->b:y->c:x->d:w-> NOTE: 4 levels resolved. NOTE: final resolution: 5 5