FAUST compiler  0.9.9.6b8
sigorderrules.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     Signals Order Rules
00025     Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
00026     ---------------------------------------------------------------------
00027     A small typing system that computes the "order" of a signal :
00028         0 = numerical constant
00029         1 = non-numerical constants (FConst)
00030         2 = User Interface
00031         3 = Audio
00032     This order will be used to put expressions in normal form.
00033     
00034     Contrary to the full type system, it doesn't require environments
00035     or special treatments for recursions
00036  ************************************************************************
00037  ************************************************************************/
00038  
00039  
00040 #include <stdio.h>
00041 #include "sigtype.hh"
00042 #include "sigprint.hh"
00043 #include "prim2.hh"
00044 #include "tlib.hh"
00045 #include "sigorderrules.hh"
00046 #include "xtended.hh"
00047 
00048 Tree ORDERPROP = tree(symbol("OrderProp"));
00049 
00050 static int infereSigOrder(Tree sig);
00051 
00062 int getSigOrder(Tree sig)
00063 {
00064     Tree tt;
00065     if (getProperty(sig, ORDERPROP, tt)) { 
00066         return tree2int(tt); 
00067     } else {
00068         int order = infereSigOrder(sig);
00069         setProperty(sig, ORDERPROP, tree(order));
00070         return order;
00071     }
00072 }   
00073 
00074 // shortcut for order inference algorithm
00075 #define O getSigOrder
00076 
00077 
00078 
00084 static int infereSigOrder(Tree sig)
00085 {
00086     int         i;
00087     double      r;
00088     Tree        sel, s1, s2, s3, s4, ff, id, ls, l, x, y, var, body, type, name, file;
00089 
00090     xtended* xt = (xtended*) getUserData(sig);
00091     // primitive elements
00092     if (xt)                                 
00093     {
00094         //return 3;
00095         vector<int> args;
00096         for (int i=0; i<sig->arity(); i++) { args.push_back( O(sig->branch(i)) ); }
00097         return xt->infereSigOrder(args);
00098     }
00099 
00100     
00101     else if (isSigInt(sig, &i))                 return 0;
00102         
00103     else if (isSigReal(sig, &r))                return 0;
00104         
00105     else if (isSigInput(sig, &i))               return 3;
00106         
00107     else if (isSigOutput(sig, &i, s1))          return 3;
00108         
00109     else if (isSigDelay1(sig, s1))              return 3;
00110     
00111     else if (isSigPrefix(sig, s1, s2))          return 3;
00112     
00113     else if (isSigFixDelay(sig, s1, s2))        return 3;
00114     
00115     else if (isSigBinOp(sig, &i, s1, s2))       return max(O(s1),O(s2));
00116     
00117     else if (isSigIntCast(sig, s1))             return O(s1);
00118         
00119     else if (isSigFloatCast(sig, s1))           return O(s1);
00120 
00121     else if (isSigFFun(sig,ff,ls) && isNil(ls)) return 1;
00122 
00123     else if (isSigFFun(sig, ff, ls))            return max(1,O(ls));
00124 
00125     else if (isSigFConst(sig,type,name,file))   return 1;
00126 
00127     else if (isSigFVar(sig,type,name,file))     return 2;
00128         
00129     else if (isSigButton(sig))                  return 2;
00130     
00131     else if (isSigCheckbox(sig))                return 2;
00132     
00133     else if (isSigVSlider(sig))                 return 2;
00134      
00135     else if (isSigHSlider(sig))                 return 2;
00136     
00137     else if (isSigNumEntry(sig))                return 2;
00138         
00139     else if (isSigHBargraph(sig, l, x, y, s1))  return O(s1);
00140         
00141     else if (isSigVBargraph(sig, l, x, y, s1))  return O(s1);
00142         
00143     else if (isSigAttach(sig, s1, s2))          return O(s1);
00144                 
00145     else if (isRec(sig, var, body))             exit(1); //return 3;  // not supposed to happen.
00146                 
00147     else if (isRef(sig, var))                   exit(1); //return 3;  // not supposed to happen. 
00148 
00149     else if (isProj(sig, &i, s1))               return 3;
00150                                                         
00151     else if (isSigTable(sig, id, s1, s2))       return 3;
00152         
00153     else if (isSigWRTbl(sig, id, s1, s2, s3))   return 3; 
00154             
00155     else if (isSigRDTbl(sig, s1, s2))           return 3;
00156 
00157     else if (isSigDocConstantTbl(sig, s1, s2))  return 3;
00158 
00159     else if (isSigDocWriteTbl(sig,s1,s2,s3,s4)) return 3;
00160 
00161     else if (isSigDocAccessTbl(sig,s1,s2))      return 3;
00162 
00163     else if (isSigGen(sig, s1))                 return 3;
00164         
00165     else if (isSigSelect2(sig,sel,s1,s2))       return 3;
00166         
00167     else if (isSigSelect3(sig,sel,s1,s2,s3))    return 3;   
00168     
00169     else if (isList(sig)) 
00170     {
00171         int r = 0;
00172         while (isList(sig)) { int x = O(hd(sig)); if (x > r) r = x; sig = tl(sig); }
00173         return r;
00174     }
00175     
00176     // unrecognized signal here
00177     fprintf(stderr, "ERROR infering signal order : unrecognized signal  : "); print(sig, stderr); fprintf(stderr, "\n");
00178     exit(1);
00179     return 0;
00180 }
00181