awk Script Which Generates a C++ Class Library to Propagate Engineering Units and Dimensions Dynamically Trough a C++ Program
# ################################################################### # function init() initialized the Generation of the C++ Classes # Required to Propagate units and dimensions Through a Calculation # as the calculation runs. # ################################################################### function init() { NUMNUM=25 newName[ 1]="UnsignedChar"; oldName[ 1]="unsigned char" newName[ 2]="Char"; oldName[ 2]="char" newName[ 3]="UnsignedShort"; oldName[ 3]="unsigned short" newName[ 4]="Short"; oldName[ 4]="short" newName[ 5]="UnsignedInt"; oldName[ 5]="unsigned int" newName[ 6]="Int"; oldName[ 6]="int" newName[ 7]="UnsignedLong"; oldName[ 7]="unsigned long" newName[ 8]="Long"; oldName[ 8]="long" newName[ 9]="UnsignedLongLong"; oldName[ 9]="unsigned long" newName[10]="LongLong"; oldName[10]="long long" newName[11]="Float"; oldName[11]="float" newName[12]="Double"; oldName[12]="double" newName[13]="LongDouble"; oldName[13]="long double" ind[0]="" ind[1]=" " ind[2]=ind[1] ind[1] ind[3]=ind[2] ind[1] ind[4]=ind[3] ind[1] ind[5]=ind[4] ind[1] # ----------------------------------- aOpers[ 1]="+" # -----> Arithmetic Operators aOpers[ 2]="-" aOpers[ 3]="*" aOpers[ 4]="/" aOpers[ 5]="+=" # -----> 5,6,7 and 8 require units/dimensions checking aOpers[ 6]="-=" aOpers[ 7]="*=" aOpers[ 8]="/=" aopers=8 # ----------------------------------- pOpers[ 1]="++" # -----> Prefix/Postfix Operators pOpers[ 2]="--" popers=2 # ----------------------------------- iOpers[ 1]="%" # -----> Operators that require integer operands iOpers[ 2]="&" iOpers[ 3]="^" iOpers[ 4]="|" iOpers[ 5]="<<" iOpers[ 6]=">>" iOpers[ 7]= "%=" iOpers[ 8]= "&=" iOpers[ 9]= "|=" iOpers[10]= "^=" iOpers[11]="<<=" iOpers[12]=">>=" iopers=12 # ----------------------------------- skip[ 9]=1 skip[10]=1 skip[13]=1 # ----------------------------------- skip1[11]=1 skip1[12]=1 skip1[13]=1 } # ################################################################### # function gen_aOpers(i,j ,k,n) generates the +, - *, /, +=, -= *=, /= # functions for units and dimensions tracking. # ################################################################### function gen_aOpers(i,j ,k,n,cast1,cast2) { if(j in skip) return n=i>j?i:j if(i==j) { # -----> Generate Member arithmetic functions for(k=1; k<=aopers; k++) { printf("%s%s operator %-3s (%s& r); // 2a\n" ,ind[2],newName[i],aOpers[k],newName[i]) > fouth printf("// **********************************************************************************************************\n") > foutc printf("%s%s %s::operator %-3s (%s& r) { // 1a\n" ,ind[0],newName[i],newName[i],aOpers[k],newName[i]) > foutc printf("%s%s num;\n",ind[1],newName[n]) > foutc printf("%snum.val = (val %s r.val);\n",ind[1],aOpers[k]) > foutc printf("%snum.u = (u %-3s r.u);\n",ind[1],aOpers[k]) > foutc printf("%sreturn num;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc } } else { for(k=1; k<=aopers; k++) { # -----> Generate friend arithmetic Functions printf("%sfriend %s operator %-3s (%s& , %s&); // 4a\n" ,ind[2],newName[n],aOpers[k],newName[i],newName[j]) > fouth printf("// **********************************************************************************************************\n") > foutc printf("%s%s operator %-3s (%s& l , %s& r) { // 3a\n" ,ind[0],newName[n],aOpers[k],newName[i],newName[j]) > foutc printf("%s%s num;\n",ind[1],newName[n]) > foutc cast1=cast2="" if(match(aOpers[k],"[=]")<=0) { printf("%snum.val = (l.val %s r.val);\n",ind[1],aOpers[k]) > foutc } else { cast1=sprintf("(%s)",oldName[n]) cast2=sprintf("(%s)",oldName[i]) printf("%snum.val = %s(l.val %s %sr.val);\n",ind[1],cast1,aOpers[k],cast2) > foutc } printf("%snum.u = (l.u %-3s r.u);\n",ind[1],aOpers[k]) > foutc printf("%sreturn num;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc } } for(k=1; k<=aopers; k++) { # -----> Generate friend arithmetic Functions # -------------------------------------------------------------------------------------------------------- printf("%sfriend %s operator %-3s (%s& , %s&); // 5a\n" ,ind[2],newName[n],aOpers[k],newName[i],oldName[j]) > fouth printf("// **********************************************************************************************************\n") > foutc printf("%s%s operator %-3s (%s& l , %s& r) { // 6a\n" ,ind[0],newName[n],aOpers[k],newName[i],oldName[j]) > foutc printf("%s%s num;\n",ind[1],newName[n]) > foutc cast1=cast2="" if(match(aOpers[k],"[=]")<=0) { if(ij) cast2=sprintf("(%s)",oldName[n]) printf("%snum.val = (%sl.val %s %sr);\n",ind[1],cast1,aOpers[k],cast2) > foutc } else { cast1=sprintf("(%s)",oldName[n]) cast2=sprintf("(%s)",oldName[i]) printf("%snum.val = %s(l.val %s %sr);\n",ind[1],cast1,aOpers[k],cast2) > foutc } printf("%snum.u = l.u;\n",ind[1]) > foutc printf("%sreturn num;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc # -------------------------------------------------------------------------------------------------------- printf("%sfriend %s operator %-3s (%s& , %s&); // 7a\n" ,ind[2],newName[n],aOpers[k],oldName[i],newName[j]) > fouth printf("// **********************************************************************************************************\n") > foutc printf("%s%s operator %-3s (%s& l , %s& r) { // 8a\n" ,ind[0],newName[n],aOpers[k],oldName[i],newName[j]) > foutc printf("%s%s num;\n",ind[1],newName[n]) > foutc cast1=cast2="" if(match(aOpers[k],"[=]")<=0) { if(i j) cast2=sprintf("(%s)",oldName[n]) printf("%snum.val = (%sl %s %sr.val);\n",ind[1],cast1,aOpers[k],cast2) > foutc } else { cast1=sprintf("(%s)",oldName[n]) cast2=sprintf("(%s)",oldName[i]) printf("%snum.val = %s(l %s %sr.val);\n",ind[1],cast1,aOpers[k],cast2) > foutc } printf("%snum.u = r.u;\n",ind[1]) > foutc printf("%sreturn num;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc } } # ################################################################### # function gen_iOpers(i,j) generates the %, &, ^, | , <<, >>, # %=, &=, ^=, |=, <<=, >>= functions for units and dimensions # tracking. # ################################################################### function gen_iOpers(i,j ,k,n) { if(j in skip || j in skip1) return if(i in skip || i in skip1) return n=i>j?i:j if(i==j) { # -----> Generate Member bitwise functions for(k=1; k<=iopers; k++) { printf("// **********************************************************************************************************\n") > foutc printf("%s%s operator %-3s (%s& r); // 2i\n" ,ind[2],newName[n],iOpers[k],newName[i]) > fouth printf("%s%s %s::operator %-3s (%s& r) { // 1i\n" ,ind[0],newName[n],newName[i],iOpers[k],newName[i]) > foutc printf("%s%s num;\n",ind[1],newName[n]) > foutc printf("%snum.val = (val %s r.val);\n",ind[1],iOpers[k]) > foutc printf("%snum.u = (u %-3s r.u);\n",ind[1],iOpers[k]) > foutc printf("%sreturn num;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc } } else { for(k=1; k<=iopers; k++) { # -----> Generte friend bitwise Functions printf("%sfriend %s operator %-3s (%s& , %s&); // 4i\n" ,ind[2],newName[n],iOpers[k],newName[i],newName[j]) > fouth printf("// **********************************************************************************************************\n") > foutc printf("%s%s operator %-3s (%s& l , %s& r) { // 3i\n" ,ind[0],newName[n],iOpers[k],newName[i],newName[j]) > foutc printf("%s%s num;\n",ind[1],newName[n]) > foutc printf("%snum.val = (l.val %s r.val);\n",ind[1],iOpers[k]) > foutc printf("%snum.u = (l.u %-3s r.u);\n",ind[1],iOpers[k]) > foutc printf("%sreturn num;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc } } for(k=1; k<=iopers; k++) { # -----> Generte friend bitwise Functions # -------------------------------------------------------------------------------------------------------- printf("%sfriend %s operator %-3s (%s& , %s&); // 5i\n" ,ind[2],newName[n],iOpers[k],newName[i],oldName[j]) > fouth printf("// **********************************************************************************************************\n") > foutc printf("%s%s operator %-3s (%s& l , %s& r) { // 6i\n" ,ind[0],newName[n],iOpers[k],newName[i],oldName[j]) > foutc printf("%s%s num;\n",ind[1],newName[n]) > foutc printf("%snum.val = (l.val %s r);\n",ind[1],iOpers[k]) > foutc printf("%snum.u = l.u;\n",ind[1],iOpers[k]) > foutc printf("%sreturn num;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc # -------------------------------------------------------------------------------------------------------- printf("%sfriend %s operator %-3s (%s& , %s&); // 7i\n" ,ind[2],newName[n],iOpers[k],oldName[i],newName[j]) > fouth printf("// **********************************************************************************************************\n") > foutc printf("%s%s operator %-3s (%s& l , %s& r) { // 8i\n" ,ind[0],newName[n],iOpers[k],oldName[i],newName[j]) > foutc printf("%s%s num;\n",ind[1],newName[n]) > foutc printf("%snum.val = (l %s r.val);\n",ind[1],iOpers[k]) > foutc printf("%snum.u = r.u;\n",ind[1],iOpers[k]) > foutc printf("%sreturn num;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc } } # ################################################################### # function gen_pOpers(i,j) generates the i++, and ++i pre and post # increment functions for units and dimensions tracking. # ################################################################### function gen_pOpers(i ,k,arg) { arg[1]="void" arg[2]="int" # -----> Generate Member pre and post increment functions for(j=1; j<=2; j++) { if(j==1) c="Prefix operator" if(j==2) c="Postfix operator" for(k=1; k<=popers; k++) { printf("// **********************************************************************************************************\n") > foutc printf("%s%s %s::operator %s(%s) { // 1p, %s\n",ind[0],newName[i],newName[i],pOpers[k],arg[j],c) > foutc printf("%s%s operator %s(%s); // 2p, %s\n",ind[2],newName[i],pOpers[k],arg[j],c) > fouth if(j==1) printf("%s %sval;\n",ind[1],pOpers[k]) > foutc if(match(newName[i],"Unsigned")==1 && k==2) printf("%sassert(val>=1);\n",ind[1]) > foutc if(j==2) printf("%s val%s;\n",ind[1],pOpers[k]) > foutc printf("%sreturn *this;\n",ind[1]) > foutc printf("%s}\n\n",ind[0]) > foutc } } } # ################################################################### # function gen_constructors(i) generates the constructors and # destructors for each class # ################################################################### function gen_constructors(i ,k,arg) { printf("// *********************************************************************************************************\n") > foutc printf("%s// First class %s constructor\n",ind[0],newName[i]) > foutc printf("// *********************************************************************************************************\n") > foutc printf("%s%s::%s() {\n",ind[0],newName[i],newName[i]) > foutc printf("%sval=0;\n",ind[1]) > foutc printf("%sstate=UNDEF;\n",ind[1]) > foutc printf("%su.init();\n",ind[1]) > foutc printf("%s}\n",ind[0]) > foutc printf("// *********************************************************************************************************\n") > foutc printf("%s// Second class %s constructor\n",ind[0],newName[i]) > foutc printf("// *********************************************************************************************************\n") > foutc printf("%s%s::%s(char* str) {\n",ind[0],newName[i],newName[i]) > foutc printf("%sval=0;\n",ind[1]) > foutc printf("%sstate=UNDEF;\n",ind[1]) > foutc printf("%su.init(str);\n",ind[1]) > foutc printf("%s}\n",ind[0]) > foutc printf("// *********************************************************************************************************\n") > foutc printf("%s// First class %s destructor\n",ind[0],newName[i]) > foutc printf("// *********************************************************************************************************\n") > foutc printf("%s%s::~%s() {\n",ind[0],newName[i],newName[i]) > foutc printf("%sval=0;\n",ind[1]) > foutc printf("%sstate=UNDEF;\n",ind[1]) > foutc printf("%su.init();\n",ind[1]) > foutc printf("%s}\n",ind[0]) > foutc } # ################################################################### # Main 'gen.awk' Routine # ################################################################### BEGIN { foutc="test.cpp" fouth="test.h" init() printf("#include \n") > foutc printf("#include \"units.h\"\n") > foutc printf("#include \"test.h\"\n") > foutc # ----- Generate the class declarations for(i=1;i<=13; i++) { if(i in skip) continue printf("class %s;\n",newName[i]) > fouth } for(i=1;i<=13; i++) { if(i in skip) continue printf("%s// %s ----------------------------------------------------------------\n",ind[0],i) > foutc printf("%s%s temp_%s[%d];\n",ind[0],newName[i],newName[i],NUMNUM) > foutc printf("%sint %s_index=0;\n",ind[0],newName[i]) > foutc } for(i=1; i<=13; i++) { if(i in skip) continue printf("class %s {\n",newName[i]) > fouth printf("%spublic:\n",ind[1]) > fouth printf("%sstatic char bf[200];\n",ind[2]) > fouth printf("%s%s val;\n",ind[2],oldName[i]) > fouth printf("%sUnits u;\n",ind[2]) > fouth printf("%s/* Units and dimensions associated with this numeric object */\n",ind[2]) > fouth printf("%sUNITS_t state; /* State=DUMMY/SET */\n",ind[2]) > fouth printf("%s// First class %s constructor\n",ind[2],newName[i]) > fouth printf("%s%s();\n",ind[2],newName[i]) > fouth printf("%s// Second class %s constructor\n",ind[2],newName[i]) > fouth printf("%s%s(char*);\n",ind[2],newName[i]) > fouth printf("%s// First class %s destructor\n",ind[2],newName[i]) > fouth printf("%s~%s();\n",ind[2],newName[i]) > fouth gen_constructors(i) for(j=1;j<=13; j++) { gen_aOpers(i,j) } for(j=1;j<=13; j++) gen_iOpers(i,j) gen_pOpers(i) printf("}; // -----> end of class %s\n\n",newName[i]) > fouth } close(fouth) close(foutc) }