FAUST compiler  0.9.9.6b8
privatise.cpp
Go to the documentation of this file.
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 
00022 
00023 
00024 #include "sigtype.hh"
00025 #include "compatibility.hh"
00026 #include <stdio.h>
00027 
00028 #include "sigprint.hh"
00029 #include "sigtyperules.hh"
00030 #include "privatise.hh"
00031 
00032 
00033 /*****************************************************************************
00034                          privatise : compile a list of signals
00035 *****************************************************************************/
00036 
00037 static Tree makePrivatisationKey(const Tree& t);
00038 static Tree makePrivatisationLabel(const Tree& exp);
00039 
00040 static Tree privatisation (const Tree& k, const Tree& t);
00041 static Tree computePrivatisation (const Tree& k, const Tree& t);
00042 static Tree labelize(const Tree& label, const Tree& exp);
00043 
00044 
00045 Tree privatise(const Tree& t)
00046 {
00047 
00048     return privatisation(makePrivatisationKey(t), t);
00049 }
00050 
00051 
00052 // -- implementation -----------------
00053 
00054 static Tree makePrivatisationKey(const Tree& t)
00055 {
00056     char    name[256];
00057     snprintf(name, 256, "PRIVATISE %p : ", (CTree*)t);
00058     return tree(unique(name));
00059 }
00060 
00061 static Tree makePrivatisationLabel(const Tree& t)
00062 {
00063     char    name[256];
00064     snprintf(name, 256, "OWNER IS %p : ", (CTree*)t);
00065     return tree(unique(name));
00066 }
00067 
00068 
00069 // -- implementation -----------------
00070 
00071 static Tree privatisation (const Tree& k, const Tree& t)
00072 {
00073     Tree v;
00074 
00075     if (t->arity() == 0) {
00076         return t;
00077 
00078     } else if (getProperty(t, k, v)) {
00079         /*  Terme deja visité. La propriété nous indique
00080             la version privatisée ou nil si elle est identique
00081             au terme initial.
00082         */
00083         return isNil(v) ? t : v;
00084 
00085     } else {
00086         /*  Calcul du terme privatisé et mis à jour
00087             de la propriété. Nil indique que le terme
00088             privatisé est identique à celui de depart
00089             (pour eviter les boucles avec les compteurs
00090             de references)
00091         */
00092         v = computePrivatisation(k,t);
00093         if (v != t) {
00094             setProperty(t, k, v );
00095         } else {
00096             setProperty(t, k, nil);
00097         }
00098         return v;
00099     }
00100 }
00101 
00102 static Tree computePrivatisation(const Tree& k, const Tree& exp)
00103 {
00104     Tree    tbl, size, idx, wrt, content, id, var, body;
00105 
00106     if ( isSigWRTbl(exp, id, tbl, idx, wrt) )   {
00107         /*  Ce qui ne peut pas être partagé, ce sont les
00108             tables dans lesquelles on ecrit. Pour cela
00109             on leur donne un label unique
00110         */
00111         return sigWRTbl(
00112                     id,
00113                     labelize( makePrivatisationLabel(exp), privatisation(k, tbl) ),
00114                     privatisation(k, idx),
00115                     privatisation(k, wrt) );
00116 
00117     } else if ( isSigTable(exp, id, size, content) ) {
00118         /*  Rien à privatiser dans une table (car size est
00119             censée etre une expression entiere)
00120         */
00121         return exp;
00122 
00123     } else if ( isSigGen(exp, content) ) {
00124         /*  On ne visite pas les contenus des tables
00125         */
00126         printf("erreur 1 dans computePrivatisation\n");
00127         exit(1);
00128 
00129     } else if ( isRec(exp, var, body) ) {
00130         /*  On ne visite pas les contenus des tables
00131         */
00132         setProperty(exp, k, nil);
00133         return rec(var, privatisation(k,body));
00134 
00135     } else {
00136         /*  On parcours les autres arbres en privatisant les branches
00137         */
00138         int n = exp->arity();
00139 
00140         switch (n) {
00141 
00142             case 1 :
00143                 return tree(
00144                         exp->node(),
00145                         privatisation(k, exp->branch(0)) );
00146             case 2 :
00147                 return tree(
00148                         exp->node(),
00149                         privatisation(k, exp->branch(0)),
00150                         privatisation(k, exp->branch(1)) );
00151             case 3 :
00152                 return tree (
00153                         exp->node(),
00154                         privatisation(k, exp->branch(0)),
00155                         privatisation(k, exp->branch(1)),
00156                         privatisation(k, exp->branch(2)) );
00157             case 4 :
00158                 return tree (
00159                         exp->node(),
00160                         privatisation(k, exp->branch(0)),
00161                         privatisation(k, exp->branch(1)),
00162                         privatisation(k, exp->branch(2)),
00163                         privatisation(k, exp->branch(3)) );
00164         }
00165         printf("erreur 2 dans computePrivatisation\n");
00166         exit(1);
00167     }
00168     printf("situation anormale dans computePrivatisation\n");
00169     return exp;
00170 }
00171 
00172 static Tree labelize(const Tree& newid, const Tree& exp)
00173 {
00174     Tree    tbl, size, idx, wrt, content, oldid;
00175 
00176     if ( isSigWRTbl(exp, oldid, tbl, idx, wrt) )    {
00177         /*  Ce qui ne peut pas être partagé, ce sont les
00178             tables dans lesquelles on ecrit. Pour cela
00179             on leur donne un label unique
00180         */
00181         return sigWRTbl(newid, tbl, idx, wrt);
00182 
00183     } else  if ( isSigTable(exp, oldid, size, content) ) {
00184         /*  Rien à privatiser dans une table (car size est
00185             censée etre une expression entiere)
00186         */
00187         return sigTable(newid, size, content);
00188 
00189     } else {
00190 
00191         printf("erreur labelize\n");
00192         exit(1);
00193     }
00194 
00195     return exp;
00196 }
00197