00001 #include "environment.hh"
00002 #include "errormsg.hh"
00003 #include "boxes.hh"
00004 #include "ppbox.hh"
00005 #include "names.hh"
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 static Tree pushNewLayer(Tree lenv)
00027 {
00028 return tree(unique("ENV_LAYER"), lenv);
00029 }
00030
00031
00039 static void addLayerDef(Tree id, Tree def, Tree lenv)
00040 {
00041
00042 Tree olddef;
00043 if (getProperty(lenv, id, olddef)) {
00044 if (def == olddef) {
00045 evalwarning(getDefFileProp(id), getDefLineProp(id), "equivalent re-definitions of", id);
00046 } else {
00047 fprintf(stderr, "%s:%d: ERROR: redefinition of symbols are not allowed : ", getDefFileProp(id), getDefLineProp(id));
00048 print(id,stderr);
00049 fprintf(stderr, " is already defined in file \"%s\" line %d \n", getDefFileProp(id), getDefLineProp(id));
00050 gErrorCount++;
00051 }
00052 }
00053 setProperty(lenv, id, def);
00054 }
00055
00056
00064 Tree pushValueDef(Tree id, Tree def, Tree lenv)
00065 {
00066 Tree lenv2 = pushNewLayer(lenv);
00067 addLayerDef(id, def, lenv2);
00068 return lenv2;
00069 }
00070
00071
00079 Tree pushMultiClosureDefs(Tree ldefs, Tree visited, Tree lenv)
00080 {
00081 Tree lenv2 = pushNewLayer(lenv);
00082 while (!isNil(ldefs)) {
00083 Tree def = hd(ldefs);
00084 Tree id = hd(def);
00085 Tree rhs= tl(def);
00086 Tree cl = closure(tl(def),nil,visited,lenv2);
00087 stringstream s; s << boxpp(id);
00088 if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
00089 addLayerDef( id, cl, lenv2 );
00090 ldefs = tl(ldefs);
00091 }
00092 return lenv2;
00093 }
00094
00095
00104 bool searchIdDef(Tree id, Tree& def, Tree lenv)
00105 {
00106
00107
00108 while (!isNil(lenv) && !getProperty(lenv, id, def)) {
00109 lenv = lenv->branch(0);
00110 }
00111 return !isNil(lenv);
00112 }
00113
00117 static void updateClosures(vector<Tree>& clos, Tree oldEnv, Tree newEnv)
00118 {
00119 for (unsigned int i=0; i < clos.size(); i++) {
00120 Tree exp, genv, visited, lenv;
00121 if (isClosure(clos[i], exp, genv, visited, lenv)) {
00122 if (lenv == oldEnv) {
00123 clos[i] = closure(exp, genv, visited, newEnv);
00124 }
00125 }
00126 }
00127 }
00128
00137 Tree copyEnvReplaceDefs(Tree anEnv, Tree ldefs, Tree visited, Tree curEnv)
00138 {
00139 vector<Tree> ids, clos;
00140 Tree copyEnv;
00141
00142 anEnv->exportProperties(ids, clos);
00143 copyEnv = pushNewLayer(anEnv->branch(0));
00144 updateClosures(clos, anEnv, copyEnv);
00145
00146 for (unsigned int i=0; i < clos.size(); i++) {
00147 setProperty(copyEnv, ids[i], clos[i]);
00148 }
00149
00150 while (!isNil(ldefs)) {
00151 Tree def = hd(ldefs);
00152 Tree id = hd(def);
00153 Tree rhs= tl(def);
00154 Tree cl = closure(rhs,nil,visited,curEnv);
00155 stringstream s; s << boxpp(id);
00156 if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
00157 setProperty(copyEnv, id, cl);
00158 ldefs = tl(ldefs);
00159 }
00160 return copyEnv;
00161 }
00162
00163