File: privatise.cpp

package info (click to toggle)
faust 2.54.9%2Bds0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 352,732 kB
  • sloc: cpp: 260,515; javascript: 33,578; ansic: 16,680; vhdl: 14,052; sh: 13,271; java: 5,900; objc: 3,875; makefile: 3,228; python: 2,176; cs: 1,642; lisp: 1,140; ruby: 951; xml: 762; yacc: 564; lex: 247; awk: 110; tcl: 26
file content (167 lines) | stat: -rw-r--r-- 5,212 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/************************************************************************
 ************************************************************************
    FAUST compiler
    Copyright (C) 2003-2018 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 Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 ************************************************************************
 ************************************************************************/

#include <stdio.h>
#include "compatibility.hh"
#include "sigtype.hh"

#include "exception.hh"
#include "global.hh"
#include "privatise.hh"
#include "sigprint.hh"
#include "sigtyperules.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 : ", (void*)(CTree*)t);
    return tree(unique(name));
}

static Tree makePrivatisationLabel(const Tree& t)
{
    char name[256];
    snprintf(name, 256, "OWNER IS %p : ", (void*)(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)) {
        /*
         Already visited Term. The property indicates us
         the privatized version or nil if it is identical
         to the initial term.
        */
        return isNil(v) ? t : v;

    } else {
        /*
         Computation of the privatized and update the property.
         Nil indicates that the privatized term is identical
         to the one we start with (to avoid loops with reference counters).
        */
        v = computePrivatisation(k, t);
        if (v != t) {
            setProperty(t, k, v);
        } else {
            setProperty(t, k, gGlobal->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)) {
        /*
         What cannot be shared are the tables in which
         we write. For this purpose we give them a unique label.
        */
        return sigWRTbl(id, labelize(makePrivatisationLabel(exp), privatisation(k, tbl)), privatisation(k, idx),
                        privatisation(k, wrt));

    } else if (isSigTable(exp, id, size, content)) {
        /*
         Nothing to privatize in a table (because size is supposed to
         be an integer expression).
        */
        return exp;

    } else if (isSigGen(exp, content)) {
        /*
         We do not visit the contents of the tables.
         */
        throw faustexception("ERROR : computePrivatisation");

    } else if (isRec(exp, var, body)) {
        /*
         We do not visit the contents of the tables.
         */
        setProperty(exp, k, gGlobal->nil);
        return rec(var, privatisation(k, body));

    } else {
        /*
         We go through the other trees by privatizing the branches.
         */

        tvec br;
        int  n = exp->arity();
        for (int i = 0; i < n; i++) {
            br.push_back(privatisation(k, exp->branch(i)));
        }

        return tree(exp->node(), br);
    }
}

static Tree labelize(const Tree& newid, const Tree& exp)
{
    Tree tbl, size, idx, wrt, content, oldid;

    if (isSigWRTbl(exp, oldid, tbl, idx, wrt)) {
        /*
         What cannot be shared are the tables in which
         we write. For this purpose we give them a unique label.
        */
        return sigWRTbl(newid, tbl, idx, wrt);

    } else if (isSigTable(exp, oldid, size, content)) {
        /*
         Nothing to privatize in a table (because size is supposed to
         be an integer expression).
        */
        return sigTable(newid, size, content);

    } else {
        throw faustexception("ERROR : labelize");
    }

    return exp;
}