The function exprepl which we mentioned in the section 2.4.2.1 is to expand replicators. It needs to make use of function COPY, but COPY transforms strings into strings only. It cannot be applied to tree. So, we define a new function called n_exprepl. We use this function recursively to expand bodyreplicators. For example, suppose we have the pattern for bodyreplicator:
now, we define a function n_exprepl for bodyreplicator:
fun n_exprepl(ivr,ini,fi,inc,spqbr,j,tbl)
= let val m = (fi-ini) div inc + 1
val i = ini+(j-1)*inc
in ranvalue := as_value(ivr,(!ranvalue),i,[]);
if j<=m then (bbrep spqbr tbl)
^ n_exprepl(ivr,ini,fi,inc,spqbr,j+1,tbl)
else ""
end
where ivr denotes the indexvariable, ini denotes the initial range integer value , fi denotes the final range integer value, inc is an integer which denotes the increase step, spqbr is a subtree of bodyreplicator, j is a counter from 1 to m, tbl denotes an array table which stores the information about arrays, bbrep is a function which deals with bodyreplicators and outputs a string, function as_value appends the range variable and its value to ranvalue, ranvalue is a list which stores the current value of the range variable i. When function bbrep finds the range variable i, it will replace i with the actual value. In order to put the replicator in normal form, we have
m = (fi-ini) div inc + 1
and i = ini+(j-1)*inc calculates the current value of the range variable. For example:
At first, the function n_exprepl has the following parameters:
n_exprepl("i",1,4,1,spqbr,1,tbl)
and m = (4-1) div 1 + 1 = 4.
After calling the function recursively, we have the following result:
Suppose we have a pattern for the concatenator,
now, we define a function n_exprepl1:
fun n_exprepl1(ivr,ini,fi,inc,mseq,j,tbl,sep1)
= let val m = (fi-ini) div inc + 1
val i = ini+(j-1)*inc
in ranvalue := as_value(ivr,(!ranvalue),i,[]);
if j<=m then (ex_mseq mseq tbl) ^ sep1
^ n_exprepl1(ivr,ini,fi,inc,mseq,j+1,tbl,sep1)
else ""
end
where parameters ivr,ini,fi,inc,j and tbl have the same meanings as the function n_exprepl for expanding bodyreplicators, sep1 is the same as sep which shows in concatenator pattern, tt mseq is a subtree of macro sequence. For example:
At first, the function n_exprepl1 has the following parameters:
n_exprepl1("i",1,4,1,mseq,1,tbl,";")
and m = (4-1) div 1 + 1 = 4.
After calling the function recursively, we have the following result:
Imbricator expansion is more complicated than bodyreplicator and concatenator expansion. We will use different functions to apply to different patterns. Suppose we have the pattern for imbricator:
First of all, we define a function n_exprepl2 to expand p:
fun n_exprepl2(ivr,ini,fi,inc,mseq,j,tbl,sep1,left)
= let val m = (fi-ini) div inc + 1
val i = ini+(j-1)*inc
in ranvalue := as_value(ivr,(!ranvalue),i,[]);
if j<=m then left ^ (ex_mseq mseq tbl) ^ sep1
^ n_exprepl2(ivr,ini,fi,inc,mseq,j+1,tbl,sep1,left)
else ""
end
where all the meanings of parameters are the same as the function n_exprepl1 for expanding concatenators except parameter left. left stores a left bracket. For instance, if we have (p@t@q) then the value of left is ``('', if we have p@t@q then the value of left is `` '' (null). Similar to the function n_exprepl4 to expand q:
fun n_exprepl4(ivr,ini,fi,inc,mseq,j,tbl,sep1,right)
= let val m = (fi-ini) div inc + 1
val i = ini+(j-1)*inc
in ranvalue := as_value(ivr,(!ranvalue),i,[]);
if j<=m then sep1 ^ (ex_mseq mseq tbl) ^ right
^ n_exprepl4(ivr,ini,fi,inc,mseq,j+1,tbl,sep1,right)
else ""
end
where right stores a right bracket. For instance, if we have (p@t@q) then the value of right is ``)'', if we have (p@t@q)* then the value of right is ``)*'', if we have p@t@q then the value of right is ``'' (null).
For the pattern
, we define a function
n_exprepl5:
fun n_exprepl5(ivr,ini,fi,inc,j,left)
= let val m = (fi-ini) div inc + 1
val i = ini+(j-1)*inc
in ranvalue := as_value(ivr,(!ranvalue),i,[]);
if j<=m then
left ^ n_exprepl5(ivr,ini,fi,inc,j+1,left)
else ""
end
Similar to the function n_exprepl5, we define a function n_exprepl6
for the pattern
:
fun n_exprepl6(ivr,ini,fi,inc,j,right)
= let val m = (fi-ini) div inc + 1
val i = ini+(j-1)*inc
in ranvalue := as_value(ivr,(!ranvalue),i,[]);
if j<=m then
n_exprepl6(ivr,ini,fi,inc,j+1,right) ^ right
else ""
end