# ###################################################################
# function init() initialized the generation of the c++ classes
# required to track units and dimensions throughout as the
# calculation progresses
# ###################################################################
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(ij) 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)
}