### church2num.sed ### convert the input church numeral to an arabic integer ### 0 = (\f.(\x.x)) ### 1 = (\f.(\x.(f x))) ### 2 = (\f.(\x.(f (f x)))) ### ... ### n = (\f.(\x.(f^n x))) ### sanity check input # this check is complicated; assume ok :start ### have two segments ### | ### start at zero ### add one to and subtract one from ### until = zero s/\(.*\)/0|\1/ # clear t status t loop :loop #/.*/p # check for termination s/^\([[:digit:]]\+\)|(\\f.(\\x.x))/\1/ t end # subtract one from s/^\([^|]\+\)|\(.*\)(f x)\(.*\)/\1|\2x\3/ # add one to # use rules like (1:0) = 10, and (4+1) = 5 # add one s/^\([^|]\+\)|\(.*\)/(1+\1)|\2/ :add # reduce addition # if (1+n) | n>9, deal with multiple digits # (1+14) => (1:(1+4)) => 15 s/(1+\([[:digit:]]\+\)\([[:digit:]]\))/(\1:(1+\2))/ s/(1+0)/1/ s/(1+1)/2/ s/(1+2)/3/ s/(1+3)/4/ s/(1+4)/5/ s/(1+5)/6/ s/(1+6)/7/ s/(1+7)/8/ s/(1+8)/9/ s/(1+9)/10/ ### shift carry ### ie. (2:10) => ((1+2):0) s/(\([[:digit:]]\+\):10)/((1+\1):0)/ ### reduce simple : ### (23:4) => 234 s/(\([[:digit:]]\+\):\([[:digit:]]\))/\1\2/ t add b loop :end