FAUST compiler  0.9.9.6b8
environment.cpp
Go to the documentation of this file.
1 #include "environment.hh"
2 #include "errormsg.hh"
3 #include "boxes.hh"
4 #include "ppbox.hh"
5 #include "names.hh"
6 
7 
8 //-----------------------new environment management----------------------------
9 //
10 // The environement is made of layers. Each layer contains a set of definitions
11 // stored as properties of the layer. Each definition can refers to other
12 // definitions of the same layer or of subsequent layers. Recursive
13 // definitions are not allowed. Multiple defintions of the same symbol
14 // in a layer is allowed but generate a warning when the definition is
15 // different
16 //-----------------------------------------------------------------------------
17 
18 
19 
26 static Tree pushNewLayer(Tree lenv)
27 {
28  return tree(unique("ENV_LAYER"), lenv);
29 }
30 
31 
32 
41 Sym BARRIER = symbol ("BARRIER");
42 
44 {
45  return tree(BARRIER, lenv);
46 }
47 
48 
56 bool isEnvBarrier(Tree lenv)
57 {
58  return isNil(lenv) || (lenv->node() == Node(BARRIER));
59 }
60 
61 
69 static void addLayerDef(Tree id, Tree def, Tree lenv)
70 {
71  // check for multiple definitions of a symbol in the same layer
72  Tree olddef;
73  if (getProperty(lenv, id, olddef)) {
74  if (def == olddef) {
75  evalwarning(getDefFileProp(id), getDefLineProp(id), "equivalent re-definitions of", id);
76  } else {
77  fprintf(stderr, "%s:%d: ERROR: redefinition of symbols are not allowed : ", getDefFileProp(id), getDefLineProp(id));
78  print(id,stderr);
79  fprintf(stderr, " is already defined in file \"%s\" line %d \n", getDefFileProp(id), getDefLineProp(id));
80  gErrorCount++;
81  }
82  }
83  setProperty(lenv, id, def);
84 }
85 
86 
94 Tree pushValueDef(Tree id, Tree def, Tree lenv)
95 {
96  Tree lenv2 = pushNewLayer(lenv);
97  addLayerDef(id, def, lenv2);
98  return lenv2;
99 }
100 
101 
109 Tree pushMultiClosureDefs(Tree ldefs, Tree visited, Tree lenv)
110 {
111  Tree lenv2 = pushNewLayer(lenv);
112  while (!isNil(ldefs)) {
113  Tree def = hd(ldefs);
114  Tree id = hd(def);
115  Tree rhs= tl(def);
116  Tree cl = closure(tl(def),nil,visited,lenv2);
117  stringstream s; s << boxpp(id);
118  if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
119  addLayerDef( id, cl, lenv2 );
120  ldefs = tl(ldefs);
121  }
122  return lenv2;
123 }
124 
125 
135 bool searchIdDef(Tree id, Tree& def, Tree lenv)
136 {
137  // search the environment until a definition is found
138  // or a barrier (or nil) is reached
139 
140  while (!isEnvBarrier(lenv) && !getProperty(lenv, id, def)) {
141  lenv = lenv->branch(0);
142  }
143  return !isEnvBarrier(lenv);
144 }
145 
149 static void updateClosures(vector<Tree>& clos, Tree oldEnv, Tree newEnv)
150 {
151  for (unsigned int i=0; i < clos.size(); i++) {
152  Tree exp, genv, visited, lenv;
153  if (isClosure(clos[i], exp, genv, visited, lenv)) {
154  if (lenv == oldEnv) {
155  clos[i] = closure(exp, genv, visited, newEnv);
156  }
157  }
158  }
159 }
160 
169 Tree copyEnvReplaceDefs(Tree anEnv, Tree ldefs, Tree visited, Tree curEnv)
170 {
171  vector<Tree> ids, clos;
172  Tree copyEnv;
173 
174  anEnv->exportProperties(ids, clos); // get the definitions of the environment
175  copyEnv = pushNewLayer(anEnv->branch(0)); // create new environment with same stack
176  updateClosures(clos, anEnv, copyEnv); // update the closures replacing oldEnv with newEnv
177 
178  for (unsigned int i=0; i < clos.size(); i++) { // transfers the updated definitions to the new environment
179  setProperty(copyEnv, ids[i], clos[i]);
180  }
181 
182  while (!isNil(ldefs)) { // replace the old definitions with the new ones
183  Tree def = hd(ldefs);
184  Tree id = hd(def);
185  Tree rhs= tl(def);
186  Tree cl = closure(rhs,nil,visited,curEnv);
187  stringstream s; s << boxpp(id);
188  if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
189  setProperty(copyEnv, id, cl);
190  ldefs = tl(ldefs);
191  }
192  return copyEnv;
193 }
194 
195 
Symbol * unique(const char *str)
Returns a new unique symbol of name strxxx.
Definition: symbol.hh:97
Class Node = (type x (int + double + Sym + void*))
Definition: node.hh:75
static void updateClosures(vector< Tree > &clos, Tree oldEnv, Tree newEnv)
Replace closure that point to oldEnv with closure on newEnv.
Tree pushValueDef(Tree id, Tree def, Tree lenv)
Push a new layer and add a single definition.
Definition: environment.cpp:94
Tree copyEnvReplaceDefs(Tree anEnv, Tree ldefs, Tree visited, Tree curEnv)
Create a new environment by copying an existing one and replacing some definitions.
bool isEnvBarrier(Tree lenv)
Test if the environment is a barrier (or nil) so that searchIdDef will know where to stop when search...
Definition: environment.cpp:56
static void addLayerDef(Tree id, Tree def, Tree lenv)
Add a definition (as a property) to the current top level layer.
Definition: environment.cpp:69
bool searchIdDef(Tree id, Tree &def, Tree lenv)
Search the environment (until first barrier) for the definition of a symbol ID and return it...
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
Tree hd(Tree l)
Definition: list.hh:133
const Node & node() const
return the content of the tree
Definition: tree.hh:143
void setDefNameProperty(Tree t, Tree id)
Definition: names.cpp:54
void evalwarning(const char *filename, int linenum, const char *msg, Tree exp)
Definition: errormsg.cpp:53
Tree pushEnvBarrier(Tree lenv)
Definition: environment.cpp:43
bool isNil(Tree l)
Definition: list.hh:137
static Tree pushNewLayer(Tree lenv)
Push a new (unique) empty layer (where multiple definitions can be stored) on top of an existing envi...
Definition: environment.cpp:26
Tree pushMultiClosureDefs(Tree ldefs, Tree visited, Tree lenv)
Push a new layer with multiple definitions creating the appropriate closures.
bool isBoxCase(Tree s)
Definition: boxes.cpp:617
int getDefLineProp(Tree sym)
Definition: errormsg.cpp:82
bool isClosure(Tree t, Tree &abstr, Tree &genv, Tree &vis, Tree &lenv)
Definition: boxes.cpp:239
int gErrorCount
Definition: errormsg.cpp:31
Sym BARRIER
Push a new environment barrier on top of an existing environment so that searchIdDef (used by the pat...
Definition: environment.cpp:41
Tree closure(Tree abstr, Tree genv, Tree vis, Tree lenv)
Definition: boxes.cpp:234
Tree tree(const Node &n)
Definition: tree.hh:186
Symbols are unique objects with a name stored in a hash table.
Definition: symbol.hh:53
Definition: ppbox.hh:58
void setProperty(Tree t, Tree key, Tree val)
Definition: list.cpp:418
Tree nil
Definition: list.cpp:116
Symbol * symbol(const char *str)
Returns (and creates if new) the symbol of name str.
Definition: symbol.hh:95
Interface for names management.
void exportProperties(vector< Tree > &keys, vector< Tree > &values)
export the properties of a CTree as two vectors, one for the keys and one for the associated values ...
Definition: tree.cpp:388
Tree tl(Tree l)
Definition: list.hh:134
Tree branch(int i) const
return the ith branch (subtree) of a tree
Definition: tree.hh:145
const char * getDefFileProp(Tree sym)
Definition: errormsg.cpp:72
bool getProperty(Tree t, Tree key, Tree &val)
Definition: list.cpp:423
void print(Tree t, FILE *out)
Definition: list.cpp:154