|
FAUST compiler
0.9.9.6b8
|
00001 /************************************************************************ 00002 ************************************************************************ 00003 FAUST compiler 00004 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale 00005 --------------------------------------------------------------------- 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 ************************************************************************ 00020 ************************************************************************/ 00021 #include <assert.h> 00022 #include <stdio.h> 00023 #include <stdlib.h> 00024 #include <limits.h> 00025 #include "recursivness.hh" 00026 #include "property.hh" 00027 00028 #include "signals.hh" 00029 #include "ppsig.hh" 00030 #include "set" 00031 00032 using namespace std; 00033 00034 00046 //-------------------------------------------------------------------------- 00047 static int annotate(Tree env, Tree sig); 00048 static int position (Tree env, Tree t, int p=1); 00049 00050 Tree RECURSIVNESS = tree(symbol("RecursivnessProp")); 00051 //-------------------------------------------------------------------------- 00052 00053 00059 void recursivnessAnnotation(Tree sig) 00060 { 00061 annotate(nil, sig); 00062 } 00063 00064 00072 int getRecursivness(Tree sig) 00073 { 00074 Tree tr; 00075 if ( ! getProperty(sig, RECURSIVNESS, tr)) { 00076 cerr << "Error in getRecursivness of " << *sig << endl; 00077 exit(1); 00078 } 00079 return tree2int(tr); 00080 } 00081 00082 //-------------------------------------- IMPLEMENTATION ------------------------------------ 00089 static int annotate(Tree env, Tree sig) 00090 { 00091 Tree tr, var, body; 00092 00093 if (getProperty(sig, RECURSIVNESS, tr)) { 00094 return tree2int(tr); // already annotated 00095 } else if (isRec(sig, var, body)) { 00096 int p = position(env, sig); 00097 if (p > 0) { 00098 return p; // we are inside \x.(...) 00099 } else { 00100 int r = annotate(cons(sig, env), body) - 1; 00101 if (r<0) r=0; 00102 setProperty(sig, RECURSIVNESS, tree(r)); 00103 return r; 00104 } 00105 } else { 00106 int rmax = 0; 00107 vector<Tree> v; getSubSignals(sig, v); 00108 for (unsigned int i=0; i<v.size(); i++) { 00109 int r = annotate(env, v[i]); 00110 if (r>rmax) rmax=r; 00111 } 00112 setProperty(sig, RECURSIVNESS, tree(rmax)); 00113 return rmax; 00114 } 00115 } 00116 00117 00118 00125 static int position (Tree env, Tree t, int p) 00126 { 00127 if (isNil(env)) return 0; // was not in the environment 00128 if (hd(env) == t) return p; 00129 else return position (tl(env), t, p+1); 00130 } 00131 00132 00133 //-----------------------------------list recursive symbols----------------------- 00134 00135 00136 00143 // the property used to memoize the results 00144 property<Tree> SymListProp; 00145 00146 Tree symlistVisit(Tree sig, set<Tree>& visited) 00147 { 00148 Tree S; 00149 if (SymListProp.get(sig, S)) { 00150 return S; 00151 } else if ( visited.count(sig) > 0 ){ 00152 return nil; 00153 } else { 00154 visited.insert(sig); 00155 Tree id, body; 00156 if (isRec(sig, id, body)) { 00157 Tree U = singleton(sig); 00158 for (int i=0; i<len(body); i++) { 00159 U = setUnion(U, symlistVisit(nth(body,i), visited)); 00160 } 00161 return U; 00162 } else { 00163 vector<Tree> subsigs; 00164 int n = getSubSignals(sig, subsigs, true); // il faut visiter aussi les tables 00165 Tree U = nil; 00166 for (int i=0; i<n; i++) { 00167 U = setUnion(U, symlistVisit(subsigs[i], visited)); 00168 } 00169 return U; 00170 } 00171 } 00172 } 00173 00174 Tree symlist(Tree sig) 00175 { 00176 Tree S; 00177 if (!SymListProp.get(sig, S)) { 00178 set<Tree> visited; 00179 S = symlistVisit(sig, visited); 00180 SymListProp.set(sig, S); 00181 } 00182 //cerr << "SYMLIST " << *S << " OF " << ppsig(sig) << endl; 00183 return S; 00184 }
1.8.0