--- /dev/null
+/************************************************************************
+ ************************************************************************
+ FAUST compiler
+ Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+
+
+#include "sigtype.hh"
+#include "compatibility.hh"
+#include <stdio.h>
+
+#include "sigprint.hh"
+#include "sigtyperules.hh"
+#include "privatise.hh"
+
+
+/*****************************************************************************
+ privatise : compile a list of signals
+*****************************************************************************/
+
+static Tree makePrivatisationKey(const Tree& t);
+static Tree makePrivatisationLabel(const Tree& exp);
+
+static Tree privatisation (const Tree& k, const Tree& t);
+static Tree computePrivatisation (const Tree& k, const Tree& t);
+static Tree labelize(const Tree& label, const Tree& exp);
+
+
+Tree privatise(const Tree& t)
+{
+
+ return privatisation(makePrivatisationKey(t), t);
+}
+
+
+// -- implementation -----------------
+
+static Tree makePrivatisationKey(const Tree& t)
+{
+ char name[256];
+ snprintf(name, 256, "PRIVATISE %p : ", (CTree*)t);
+ return tree(unique(name));
+}
+
+static Tree makePrivatisationLabel(const Tree& t)
+{
+ char name[256];
+ snprintf(name, 256, "OWNER IS %p : ", (CTree*)t);
+ return tree(unique(name));
+}
+
+
+// -- implementation -----------------
+
+static Tree privatisation (const Tree& k, const Tree& t)
+{
+ Tree v;
+
+ if (t->arity() == 0) {
+ return t;
+
+ } else if (getProperty(t, k, v)) {
+ /* Terme deja visité. La propriété nous indique
+ la version privatisée ou nil si elle est identique
+ au terme initial.
+ */
+ return isNil(v) ? t : v;
+
+ } else {
+ /* Calcul du terme privatisé et mis à jour
+ de la propriété. Nil indique que le terme
+ privatisé est identique à celui de depart
+ (pour eviter les boucles avec les compteurs
+ de references)
+ */
+ v = computePrivatisation(k,t);
+ if (v != t) {
+ setProperty(t, k, v );
+ } else {
+ setProperty(t, k, nil);
+ }
+ return v;
+ }
+}
+
+static Tree computePrivatisation(const Tree& k, const Tree& exp)
+{
+ Tree tbl, size, idx, wrt, content, id, var, body;
+
+ if ( isSigWRTbl(exp, id, tbl, idx, wrt) ) {
+ /* Ce qui ne peut pas être partagé, ce sont les
+ tables dans lesquelles on ecrit. Pour cela
+ on leur donne un label unique
+ */
+ return sigWRTbl(
+ id,
+ labelize( makePrivatisationLabel(exp), privatisation(k, tbl) ),
+ privatisation(k, idx),
+ privatisation(k, wrt) );
+
+ } else if ( isSigTable(exp, id, size, content) ) {
+ /* Rien à privatiser dans une table (car size est
+ censée etre une expression entiere)
+ */
+ return exp;
+
+ } else if ( isSigGen(exp, content) ) {
+ /* On ne visite pas les contenus des tables
+ */
+ printf("erreur 1 dans computePrivatisation\n");
+ exit(1);
+
+ } else if ( isRec(exp, var, body) ) {
+ /* On ne visite pas les contenus des tables
+ */
+ setProperty(exp, k, nil);
+ return rec(var, privatisation(k,body));
+
+ } else {
+ /* On parcours les autres arbres en privatisant les branches
+ */
+ int n = exp->arity();
+
+ switch (n) {
+
+ case 1 :
+ return tree(
+ exp->node(),
+ privatisation(k, exp->branch(0)) );
+ case 2 :
+ return tree(
+ exp->node(),
+ privatisation(k, exp->branch(0)),
+ privatisation(k, exp->branch(1)) );
+ case 3 :
+ return tree (
+ exp->node(),
+ privatisation(k, exp->branch(0)),
+ privatisation(k, exp->branch(1)),
+ privatisation(k, exp->branch(2)) );
+ case 4 :
+ return tree (
+ exp->node(),
+ privatisation(k, exp->branch(0)),
+ privatisation(k, exp->branch(1)),
+ privatisation(k, exp->branch(2)),
+ privatisation(k, exp->branch(3)) );
+ }
+ printf("erreur 2 dans computePrivatisation\n");
+ exit(1);
+ }
+ printf("situation anormale dans computePrivatisation\n");
+ return exp;
+}
+
+static Tree labelize(const Tree& newid, const Tree& exp)
+{
+ Tree tbl, size, idx, wrt, content, oldid;
+
+ if ( isSigWRTbl(exp, oldid, tbl, idx, wrt) ) {
+ /* Ce qui ne peut pas être partagé, ce sont les
+ tables dans lesquelles on ecrit. Pour cela
+ on leur donne un label unique
+ */
+ return sigWRTbl(newid, tbl, idx, wrt);
+
+ } else if ( isSigTable(exp, oldid, size, content) ) {
+ /* Rien à privatiser dans une table (car size est
+ censée etre une expression entiere)
+ */
+ return sigTable(newid, size, content);
+
+ } else {
+
+ printf("erreur labelize\n");
+ exit(1);
+ }
+
+ return exp;
+}
+