+++ /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 <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include "tlib.hh"
-
-// Declaration of implementation
-static Tree calcDeBruijn2Sym (Tree t);
-static Tree substitute(Tree t, int n, Tree id);
-static Tree calcsubstitute(Tree t, int level, Tree id);
-static Tree liftn(Tree t, int threshold);
-static Tree calcliftn(Tree t, int threshold);
-
-// recursive trees
-
-Sym DEBRUIJN = symbol ("DEBRUIJN");
-Sym DEBRUIJNREF = symbol ("DEBRUIJNREF");
-Sym SUBSTITUTE = symbol ("SUBSTITUTE");
-
-Sym SYMREC = symbol ("SYMREC");
-Sym SYMRECREF = symbol ("SYMRECREF");
-Sym SYMLIFTN = symbol ("LIFTN");
-
-//Tree NOVAR = tree("NOVAR");
-
-//-----------------------------------------------------------------------------------------
-// rec, isRec : declare recursive trees
-//-----------------------------------------------------------------------------------------
-
-// de Bruijn declaration of a recursive tree
-Tree rec(Tree body)
-{
- return tree(DEBRUIJN, body);
-}
-
-bool isRec(Tree t, Tree& body)
-{
- return isTree(t, DEBRUIJN, body);
-}
-
-Tree ref(int level)
-{
- assert(level > 0);
- return tree(DEBRUIJNREF, tree(level)); // reference to enclosing recursive tree starting from 1
-}
-
-bool isRef(Tree t, int& level)
-{
- Tree u;
-
- if (isTree(t, DEBRUIJNREF, u)) {
- return isInt(u->node(), &level);
- } else {
- return false;
- }
-}
-
-
-//-----------------------------------------------------------------------------------------
-// Recursive tree in symbolic notation (using a recursive definition property)
-//-----------------------------------------------------------------------------------------
-Tree RECDEF = tree(symbol("RECDEF"));
-
-// declaration of a recursive tree using a symbolic variable
-Tree rec(Tree var, Tree body)
-{
- Tree t = tree(SYMREC, var);
- t->setProperty(RECDEF, body);
- return t;
-}
-
-bool isRec(Tree t, Tree& var, Tree& body)
-{
- if (isTree(t, SYMREC, var)) {
- body = t->getProperty(RECDEF);
- return true;
- } else {
- return false;
- }
-}
-
-
-Tree ref(Tree id)
-{
- return tree(SYMREC, id); // reference to a symbolic id
-}
-
-bool isRef(Tree t, Tree& v)
-{
- return isTree(t, SYMREC, v);
-}
-
-//-----------------------------------------------------------------------------------------
-// L'aperture d'un arbre est la plus profonde reference de Bruijn qu'il contienne.
-// Les references symboliques compte pour zero ce qui veut dire qu'un arbre d'aperture
-// 0 ne compte aucun reference de bruijn libres.
-
-int CTree::calcTreeAperture( const Node& n, const tvec& br )
-{
- int x;
- if (n == DEBRUIJNREF) {
-
- if (isInt(br[0]->node(), &x)) {
- return x;
- } else {
- return 0;
- }
-
- } else if (n == DEBRUIJN) {
-
- return br[0]->fAperture - 1;
-
- } else {
- // return max aperture of branches
- int rc = 0;
- tvec::const_iterator b = br.begin();
- tvec::const_iterator z = br.end();
- while (b != z) {
- if ((*b)->aperture() > rc) rc = (*b)->aperture();
- ++b;
- }
- return rc;
- }
-}
-
-Tree lift(Tree t) { return liftn(t, 1); }
-
-void printSignal(Tree sig, FILE* out, int prec=0);
-
-// lift (t) : increase free references by 1
-
-#if 0
-static Tree _liftn(Tree t, int threshold);
-
-static Tree liftn(Tree t, int threshold)
-{
- fprintf(stderr, "call of liftn("); printSignal(t, stderr); fprintf(stderr, ", %d)\n", threshold);
- Tree r = _liftn(t, threshold);
- fprintf(stderr, "return of liftn("); printSignal(t, stderr); fprintf(stderr, ", %d) -> ", threshold);
- printSignal(r, stderr); fprintf(stderr, "\n");
- return r;
-}
-#endif
-
-
-static Tree liftn(Tree t, int threshold)
-{
- Tree L = tree( Node(SYMLIFTN), tree(Node(threshold)) );
- Tree t2 = t->getProperty(L);
-
- if (!t2) {
- t2 = calcliftn(t, threshold);
- t->setProperty(L, t2);
- }
- return t2;
-
-}
-
-static Tree calcliftn(Tree t, int threshold)
-{
- int n;
- Tree u;
-
- if (isClosed(t)) {
-
- return t;
-
- } else if (isRef(t,n)) {
-
- if (n < threshold) {
- // it is a bounded reference
- return t;
- } else {
- // it is a free reference
- return ref(n+1);
- }
-
- } else if (isRec(t,u)) {
-
- return rec(liftn(u, threshold+1));
-
- } else {
- int n = t->arity();
- //Tree br[4];
- tvec br(n);
- for (int i = 0; i < n; i++) {
- br[i] = liftn(t->branch(i), threshold);
- }
- //return CTree::make(t->node(), n, br);
- return CTree::make(t->node(), br);
- }
-
-}
-
-//-----------------------------------------------------------
-// Transform a tree from deBruijn to symbolic representation
-//-----------------------------------------------------------
-Tree DEBRUIJN2SYM = tree(symbol("deBruijn2Sym"));
-
-Tree deBruijn2Sym (Tree t)
-{
- assert(isClosed(t));
- Tree t2 = t->getProperty(DEBRUIJN2SYM);
-
- if (!t2) {
- t2 = calcDeBruijn2Sym(t);
- t->setProperty(DEBRUIJN2SYM, t2);
- }
- return t2;
-}
-
-static Tree calcDeBruijn2Sym (Tree t)
-{
- Tree body, var;
- int i;
-
- if (isRec(t,body)) {
-
- var = tree(unique("W"));
- return rec(var, deBruijn2Sym(substitute(body,1,ref(var))));
-
- } else if (isRef(t,var)) {
-
- return t;
-
- } else if (isRef(t,i)) {
-
- fprintf(stderr, "ERREUR, une reference de Bruijn touvee ! : ");
- printSignal(t, stderr);
- fprintf(stderr, ")\n");
- exit(1);
- return t;
-
- } else {
-
- //Tree br[4];
- int a = t->arity();
- tvec br(a);
-
- for (int i = 0; i < a; i++) {
- br[i] = deBruijn2Sym(t->branch(i));
- }
- //return CTree::make(t->node(), a, br);
- return CTree::make(t->node(), br);
- }
-}
-
-static Tree substitute(Tree t, int level, Tree id)
-{
- Tree S = tree( Node(SUBSTITUTE), tree(Node(level)), id );
- Tree t2 = t->getProperty(S);
-
- if (!t2) {
- t2 = calcsubstitute(t, level, id);
- t->setProperty(S, t2);
- }
- return t2;
-
-}
-
-static Tree calcsubstitute(Tree t, int level, Tree id)
-{
- int l;
- Tree body;
-
- if (t->aperture()<level) {
-// fprintf(stderr, "aperture %d < level %d !!\n", t->aperture(), level);
- return t;
- }
- if (isRef(t,l)) return (l == level) ? id : t;
- if (isRec(t,body)) return rec(substitute(body, level+1, id));
-
- int ar = t->arity();
- //Tree br[4];
- tvec br(ar);
- for (int i = 0; i < ar; i++) {
- br[i] = substitute(t->branch(i), level, id);
- }
- //return CTree::make(t->node(), ar, br);
- return CTree::make(t->node(), br);
-}
-
-
-//--------------------------------------------------------------------------
-// UpdateAperture (t) : recursively mark open and closed terms.
-// closed term : fAperture == 0, open term fAperture == -1
-
-struct Env {
- Tree fTree; Env* fNext;
- Env(Tree t, Env* nxt) : fTree(t), fNext(nxt) {}
-};
-
-static void markOpen(Tree t);
-static int recomputeAperture(Tree t, Env* p);
-static int orderof (Tree t, Env* p);
-
-void updateAperture(Tree t)
-{
- markOpen(t);
- recomputeAperture(t, NULL);
-}
-
-//----------------------implementation--------------------------------
-
-static void markOpen(Tree t)
-{
- if (t->aperture() == INT_MAX) return;
- t->setAperture(INT_MAX);
- int ar = t->arity();
- for (int i = 0; i < ar; i++) {
- markOpen(t->branch(i));
- }
-}
-
-static int recomputeAperture(Tree t, Env* env)
-{
- Tree var, body;
-
- if (t->aperture() == 0) return 0;
-
- if (isRef(t, var)) {
-
- return orderof(var, env);
-
- } else if (isRec(t, var, body)) {
-
- Env e(var,env);
- int a = recomputeAperture(body, &e) - 1;
- if (a<=0) { /*print(t, stderr);*/ t->setAperture(0); }
- return a;
-
- } else {
- // return max aperture of branches
- int ma = 0;
- int ar = t->arity();
- for (int i = 0; i<ar; i++) {
- int a = recomputeAperture(t->branch(i), env);
- if (ma < a) ma = a;
- }
- if (ma <= 0) { /*print(t, stderr);*/ t->setAperture(0); }
- return ma;
- }
-}
-
-
-static int orderof (Tree t, Env* p)
-{
- if (p == NULL) return 0;
- if (t == p->fTree) return 1;
-
- int pos = 1;
- while (p != NULL) {
- if (t == p->fTree) return pos;
- p = p->fNext;
- pos++;
- }
- return 0;
-}