Merge branch 'newtree'
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / compiler / normalize / privatise.cpp
1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22
23
24 #include "sigtype.hh"
25 #include "compatibility.hh"
26 #include <stdio.h>
27
28 #include "sigprint.hh"
29 #include "sigtyperules.hh"
30 #include "privatise.hh"
31
32
33 /*****************************************************************************
34 privatise : compile a list of signals
35 *****************************************************************************/
36
37 static Tree makePrivatisationKey(const Tree& t);
38 static Tree makePrivatisationLabel(const Tree& exp);
39
40 static Tree privatisation (const Tree& k, const Tree& t);
41 static Tree computePrivatisation (const Tree& k, const Tree& t);
42 static Tree labelize(const Tree& label, const Tree& exp);
43
44
45 Tree privatise(const Tree& t)
46 {
47
48 return privatisation(makePrivatisationKey(t), t);
49 }
50
51
52 // -- implementation -----------------
53
54 static Tree makePrivatisationKey(const Tree& t)
55 {
56 char name[256];
57 snprintf(name, 256, "PRIVATISE %p : ", (CTree*)t);
58 return tree(unique(name));
59 }
60
61 static Tree makePrivatisationLabel(const Tree& t)
62 {
63 char name[256];
64 snprintf(name, 256, "OWNER IS %p : ", (CTree*)t);
65 return tree(unique(name));
66 }
67
68
69 // -- implementation -----------------
70
71 static Tree privatisation (const Tree& k, const Tree& t)
72 {
73 Tree v;
74
75 if (t->arity() == 0) {
76 return t;
77
78 } else if (getProperty(t, k, v)) {
79 /* Terme deja visité. La propriété nous indique
80 la version privatisée ou nil si elle est identique
81 au terme initial.
82 */
83 return isNil(v) ? t : v;
84
85 } else {
86 /* Calcul du terme privatisé et mis à jour
87 de la propriété. Nil indique que le terme
88 privatisé est identique à celui de depart
89 (pour eviter les boucles avec les compteurs
90 de references)
91 */
92 v = computePrivatisation(k,t);
93 if (v != t) {
94 setProperty(t, k, v );
95 } else {
96 setProperty(t, k, nil);
97 }
98 return v;
99 }
100 }
101
102 static Tree computePrivatisation(const Tree& k, const Tree& exp)
103 {
104 Tree tbl, size, idx, wrt, content, id, var, body;
105
106 if ( isSigWRTbl(exp, id, tbl, idx, wrt) ) {
107 /* Ce qui ne peut pas être partagé, ce sont les
108 tables dans lesquelles on ecrit. Pour cela
109 on leur donne un label unique
110 */
111 return sigWRTbl(
112 id,
113 labelize( makePrivatisationLabel(exp), privatisation(k, tbl) ),
114 privatisation(k, idx),
115 privatisation(k, wrt) );
116
117 } else if ( isSigTable(exp, id, size, content) ) {
118 /* Rien à privatiser dans une table (car size est
119 censée etre une expression entiere)
120 */
121 return exp;
122
123 } else if ( isSigGen(exp, content) ) {
124 /* On ne visite pas les contenus des tables
125 */
126 printf("erreur 1 dans computePrivatisation\n");
127 exit(1);
128
129 } else if ( isRec(exp, var, body) ) {
130 /* On ne visite pas les contenus des tables
131 */
132 setProperty(exp, k, nil);
133 return rec(var, privatisation(k,body));
134
135 } else {
136 /* On parcours les autres arbres en privatisant les branches
137 */
138 int n = exp->arity();
139
140 switch (n) {
141
142 case 1 :
143 return tree(
144 exp->node(),
145 privatisation(k, exp->branch(0)) );
146 case 2 :
147 return tree(
148 exp->node(),
149 privatisation(k, exp->branch(0)),
150 privatisation(k, exp->branch(1)) );
151 case 3 :
152 return tree (
153 exp->node(),
154 privatisation(k, exp->branch(0)),
155 privatisation(k, exp->branch(1)),
156 privatisation(k, exp->branch(2)) );
157 case 4 :
158 return tree (
159 exp->node(),
160 privatisation(k, exp->branch(0)),
161 privatisation(k, exp->branch(1)),
162 privatisation(k, exp->branch(2)),
163 privatisation(k, exp->branch(3)) );
164 }
165 printf("erreur 2 dans computePrivatisation\n");
166 exit(1);
167 }
168 printf("situation anormale dans computePrivatisation\n");
169 return exp;
170 }
171
172 static Tree labelize(const Tree& newid, const Tree& exp)
173 {
174 Tree tbl, size, idx, wrt, content, oldid;
175
176 if ( isSigWRTbl(exp, oldid, tbl, idx, wrt) ) {
177 /* Ce qui ne peut pas être partagé, ce sont les
178 tables dans lesquelles on ecrit. Pour cela
179 on leur donne un label unique
180 */
181 return sigWRTbl(newid, tbl, idx, wrt);
182
183 } else if ( isSigTable(exp, oldid, size, content) ) {
184 /* Rien à privatiser dans une table (car size est
185 censée etre une expression entiere)
186 */
187 return sigTable(newid, size, content);
188
189 } else {
190
191 printf("erreur labelize\n");
192 exit(1);
193 }
194
195 return exp;
196 }
197