|
FAUST compiler
0.9.9.6b8
|
00001 #include "environment.hh" 00002 #include "errormsg.hh" 00003 #include "boxes.hh" 00004 #include "ppbox.hh" 00005 #include "names.hh" 00006 00007 00008 //-----------------------new environment management---------------------------- 00009 // 00010 // The environement is made of layers. Each layer contains a set of definitions 00011 // stored as properties of the layer. Each definition can refers to other 00012 // definitions of the same layer or of subsequent layers. Recursive 00013 // definitions are not allowed. Multiple defintions of the same symbol 00014 // in a layer is allowed but generate a warning when the definition is 00015 // different 00016 //----------------------------------------------------------------------------- 00017 00018 00019 00026 static Tree pushNewLayer(Tree lenv) 00027 { 00028 return tree(unique("ENV_LAYER"), lenv); 00029 } 00030 00031 00032 00041 Sym BARRIER = symbol ("BARRIER"); 00042 00043 Tree pushEnvBarrier(Tree lenv) 00044 { 00045 return tree(BARRIER, lenv); 00046 } 00047 00048 00056 bool isEnvBarrier(Tree lenv) 00057 { 00058 return isNil(lenv) || (lenv->node() == Node(BARRIER)); 00059 } 00060 00061 00069 static void addLayerDef(Tree id, Tree def, Tree lenv) 00070 { 00071 // check for multiple definitions of a symbol in the same layer 00072 Tree olddef; 00073 if (getProperty(lenv, id, olddef)) { 00074 if (def == olddef) { 00075 evalwarning(getDefFileProp(id), getDefLineProp(id), "equivalent re-definitions of", id); 00076 } else { 00077 fprintf(stderr, "%s:%d: ERROR: redefinition of symbols are not allowed : ", getDefFileProp(id), getDefLineProp(id)); 00078 print(id,stderr); 00079 fprintf(stderr, " is already defined in file \"%s\" line %d \n", getDefFileProp(id), getDefLineProp(id)); 00080 gErrorCount++; 00081 } 00082 } 00083 setProperty(lenv, id, def); 00084 } 00085 00086 00094 Tree pushValueDef(Tree id, Tree def, Tree lenv) 00095 { 00096 Tree lenv2 = pushNewLayer(lenv); 00097 addLayerDef(id, def, lenv2); 00098 return lenv2; 00099 } 00100 00101 00109 Tree pushMultiClosureDefs(Tree ldefs, Tree visited, Tree lenv) 00110 { 00111 Tree lenv2 = pushNewLayer(lenv); 00112 while (!isNil(ldefs)) { 00113 Tree def = hd(ldefs); 00114 Tree id = hd(def); 00115 Tree rhs= tl(def); 00116 Tree cl = closure(tl(def),nil,visited,lenv2); 00117 stringstream s; s << boxpp(id); 00118 if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str()); 00119 addLayerDef( id, cl, lenv2 ); 00120 ldefs = tl(ldefs); 00121 } 00122 return lenv2; 00123 } 00124 00125 00135 bool searchIdDef(Tree id, Tree& def, Tree lenv) 00136 { 00137 // search the environment until a definition is found 00138 // or a barrier (or nil) is reached 00139 00140 while (!isEnvBarrier(lenv) && !getProperty(lenv, id, def)) { 00141 lenv = lenv->branch(0); 00142 } 00143 return !isEnvBarrier(lenv); 00144 } 00145 00149 static void updateClosures(vector<Tree>& clos, Tree oldEnv, Tree newEnv) 00150 { 00151 for (unsigned int i=0; i < clos.size(); i++) { 00152 Tree exp, genv, visited, lenv; 00153 if (isClosure(clos[i], exp, genv, visited, lenv)) { 00154 if (lenv == oldEnv) { 00155 clos[i] = closure(exp, genv, visited, newEnv); 00156 } 00157 } 00158 } 00159 } 00160 00169 Tree copyEnvReplaceDefs(Tree anEnv, Tree ldefs, Tree visited, Tree curEnv) 00170 { 00171 vector<Tree> ids, clos; 00172 Tree copyEnv; 00173 00174 anEnv->exportProperties(ids, clos); // get the definitions of the environment 00175 copyEnv = pushNewLayer(anEnv->branch(0)); // create new environment with same stack 00176 updateClosures(clos, anEnv, copyEnv); // update the closures replacing oldEnv with newEnv 00177 00178 for (unsigned int i=0; i < clos.size(); i++) { // transfers the updated definitions to the new environment 00179 setProperty(copyEnv, ids[i], clos[i]); 00180 } 00181 00182 while (!isNil(ldefs)) { // replace the old definitions with the new ones 00183 Tree def = hd(ldefs); 00184 Tree id = hd(def); 00185 Tree rhs= tl(def); 00186 Tree cl = closure(rhs,nil,visited,curEnv); 00187 stringstream s; s << boxpp(id); 00188 if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str()); 00189 setProperty(copyEnv, id, cl); 00190 ldefs = tl(ldefs); 00191 } 00192 return copyEnv; 00193 } 00194 00195
1.8.0