00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include "boxes.hh"
00045 #include "ppbox.hh"
00046 #include "prim2.hh"
00047 #include "xtended.hh"
00048
00049
00050 Tree BOXTYPEPROP = tree(symbol("boxTypeProp"));
00051 static bool infereBoxType (Tree box, int* inum, int* onum);
00052
00053
00054
00063 bool getBoxType (Tree box, int* inum, int* onum)
00064 {
00065 Tree t;
00066 if (getProperty(box, BOXTYPEPROP, t)) {
00067
00068 if (isNil(t)) {
00069 return false;
00070 } else {
00071 *inum = hd(t)->node().getInt();
00072 *onum = tl(t)->node().getInt();
00073 return true;
00074 }
00075
00076 } else {
00077
00078 if (infereBoxType(box, inum, onum)) {
00079 setProperty(box, BOXTYPEPROP, cons(tree(*inum), tree(*onum)));
00080 return true;
00081 } else {
00082 setProperty(box, BOXTYPEPROP, nil);
00083 return false;
00084 }
00085 }
00086 }
00087
00088
00089
00097 static bool infereBoxType (Tree t, int* inum, int* onum)
00098 {
00099 Tree a, b, ff, l, s;
00100
00101
00102 xtended* p = (xtended*) getUserData(t);
00103
00104 if (p) { *inum = p->arity(); *onum = 1; }
00105 else if (isBoxInt(t)) { *inum = 0; *onum = 1; }
00106 else if (isBoxReal(t)) { *inum = 0; *onum = 1; }
00107 else if (isBoxWire(t)) { *inum = 1; *onum = 1; }
00108 else if (isBoxCut(t)) { *inum = 1; *onum = 0; }
00109
00110 else if (isBoxSlot(t)) { *inum = 0; *onum = 1; }
00111 else if (isBoxSymbolic(t,s,b)) { if (!getBoxType(b, inum, onum)) return false; *inum += 1; }
00112
00113 else if (isBoxPrim0(t)) { *inum = 0; *onum = 1; }
00114 else if (isBoxPrim1(t)) { *inum = 1; *onum = 1; }
00115 else if (isBoxPrim2(t)) { *inum = 2; *onum = 1; }
00116 else if (isBoxPrim3(t)) { *inum = 3; *onum = 1; }
00117 else if (isBoxPrim4(t)) { *inum = 4; *onum = 1; }
00118 else if (isBoxPrim5(t)) { *inum = 5; *onum = 1; }
00119
00120 else if (isBoxFFun(t,ff)) { *inum = ffarity(ff); *onum = 1; }
00121 else if (isBoxFConst(t)) { *inum = 0; *onum = 1; }
00122 else if (isBoxFVar(t)) { *inum = 0; *onum = 1; }
00123
00124 else if (isBoxButton(t)) { *inum = 0; *onum = 1; }
00125 else if (isBoxCheckbox(t)) { *inum = 0; *onum = 1; }
00126 else if (isBoxVSlider(t)) { *inum = 0; *onum = 1; }
00127 else if (isBoxHSlider(t)) { *inum = 0; *onum = 1; }
00128 else if (isBoxNumEntry(t)) { *inum = 0; *onum = 1; }
00129 else if (isBoxVGroup(t,l,a)){ if (!getBoxType(a, inum, onum)) return false; }
00130 else if (isBoxHGroup(t,l,a)){ if (!getBoxType(a, inum, onum)) return false; }
00131 else if (isBoxTGroup(t,l,a)){ if (!getBoxType(a, inum, onum)) return false; }
00132
00133 else if (isBoxVBargraph(t)) { *inum = 1; *onum = 1; }
00134 else if (isBoxHBargraph(t)) { *inum = 1; *onum = 1; }
00135
00136 else if (isBoxSeq(t, a, b)) {
00137
00138 int u,v,x,y;
00139 if (!getBoxType(a, &u, &v)) return false;
00140 if (!getBoxType(b, &x, &y)) return false;
00141
00142 if (v >= x) {
00143 *inum = u; *onum = y+v-x;
00144 } else {
00145 *inum = u+x-v; *onum = y;
00146 }
00147
00148 } else if (isBoxPar(t, a, b)) {
00149
00150 int u,v,x,y;
00151 if (!getBoxType(a, &u, &v)) return false;
00152 if (!getBoxType(b, &x, &y)) return false;
00153
00154 *inum = u+x; *onum = v+y;
00155
00156 } else if (isBoxSplit(t, a, b)) {
00157
00158 int u,v,x,y;
00159 if (!getBoxType(a, &u, &v)) return false;
00160 if (!getBoxType(b, &x, &y)) return false;
00161
00162 if (v == 0) {
00163 cerr << "Connection error in : " << boxpp(t) << endl
00164 << "The first expression : " << boxpp(a) << " has no outputs" << endl;
00165 exit(1);
00166 }
00167
00168 if (x == 0) {
00169 cerr << "Connection error in : " << boxpp(t) << endl
00170 << "The second expression : " << boxpp(b) << " has no inputs" << endl;
00171 exit(1);
00172 }
00173
00174 if (x % v != 0) {
00175 cerr << "Connection error in : " << boxpp(t) << endl
00176 << "The number of outputs " << v
00177 << " of the first expression should be a divisor of the number of inputs " << x
00178 << " of the second expression" << endl;
00179 exit(1);
00180 }
00181
00182 *inum = u; *onum = y;
00183
00184 } else if (isBoxMerge(t, a, b)) {
00185
00186 int u,v,x,y;
00187 if (!getBoxType(a, &u, &v)) return false;
00188 if (!getBoxType(b, &x, &y)) return false;
00189
00190 if (v == 0) {
00191 cerr << "Connection error in : " << boxpp(t) << endl
00192 << "The first expression : " << boxpp(a) << " has no outputs" << endl;
00193 exit(1);
00194 }
00195
00196 if (x == 0) {
00197 cerr << "Connection error in : " << boxpp(t) << endl
00198 << "The second expression : " << boxpp(b) << " has no inputs" << endl;
00199 exit(1);
00200 }
00201
00202 if (v % x != 0) {
00203 cerr << "Connection error in : " << boxpp(t) << endl
00204 << "The number of outputs " << v
00205 << " of the first expression should be a multiple of the number of inputs " << x
00206 << " of the second expression" << endl;
00207 exit(1);
00208 }
00209
00210 *inum = u; *onum = y;
00211
00212 } else if (isBoxRec(t, a, b)) {
00213
00214 int u,v,x,y;
00215 if (!getBoxType(a, &u, &v)) return false;
00216 if (!getBoxType(b, &x, &y)) return false;
00217 if ( (x > v) | (y > u) ) {
00218 cerr << "Connection error in : " << boxpp(t) << endl;
00219 if (x > v) cerr << "The number of outputs " << v
00220 << " of the first expression should be greater or equal \n to the number of inputs " << x
00221 << " of the second exepression" << endl;
00222 if (y > u) cerr << "The number of inputs " << u
00223 << " of the first expression should be greater or equal \n to the number of outputs " << y
00224 << " of the second exepression" << endl;
00225 exit(1);
00226 }
00227 *inum = max(0,u-y); *onum = v;
00228
00229 } else {
00230 return false;
00231 }
00232 return true;
00233 }
00234
00235
00236