Rename interpretor to interpreter.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / compiler / signals / signals.cpp
diff --git a/interpreter/preprocessor/faust-0.9.47mr3/compiler/signals/signals.cpp b/interpreter/preprocessor/faust-0.9.47mr3/compiler/signals/signals.cpp
new file mode 100644 (file)
index 0000000..1f33e59
--- /dev/null
@@ -0,0 +1,449 @@
+/************************************************************************
+ ************************************************************************
+    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.
+ ************************************************************************
+ ************************************************************************/
+
+
+/*****************************************************************************
+       HISTORY
+    22/01/05 : added int cast in select2 and select3 selection signal
+*****************************************************************************/
+
+
+
+#include "signals.hh"
+
+
+////////////////////////////////////////////////////////////////////////
+/**
+ * Signals
+ *
+ */
+///////////////////////////////////////////////////////////////////////
+
+Tree  sigInt(int i)                                                            { return tree(i);                                       }
+bool  isSigInt(Tree t, int* i)                                                 { return isInt(t->node(), i);           }
+
+Tree  sigReal(double r)                                                        { return tree(r);                                       }
+bool  isSigReal(Tree t, double* r)                                     { return isDouble(t->node(), r);        }
+
+Sym SIGINPUT = symbol ("sigInput");
+Tree  sigInput(int i)                                                          { return tree(SIGINPUT, tree(i));       }
+bool  isSigInput(Tree t, int* i)                                       { Tree x; return isTree(t, SIGINPUT, x) && isInt(x->node(),i);  }
+
+Sym SIGOUTPUT = symbol ("sigOutput");
+Tree  sigOutput(int i, Tree t0)                                                { return tree(SIGOUTPUT, tree(i), t0);  }
+bool  isSigOutput(Tree t, int* i, Tree& t0)                    { Tree x; return isTree(t, SIGOUTPUT, x, t0) && isInt(x->node(),i);     }
+
+Sym SIGDELAY1 = symbol ("sigDelay1");
+Tree  sigDelay0(Tree t0)                                                       { return sigFixDelay(t0, sigInt(0));}
+
+Tree  sigDelay1(Tree t0)                                                       { return tree(SIGDELAY1, t0);           }
+bool  isSigDelay1(Tree t, Tree& t0)                                    { return isTree(t, SIGDELAY1, t0);      }
+
+Sym SIGFIXDELAY = symbol ("sigFixDelay");
+Tree  sigFixDelay(Tree t0, Tree t1)                                    { return tree(SIGFIXDELAY, t0, sigIntCast(t1));                 }
+bool  isSigFixDelay(Tree t, Tree& t0, Tree& t1)                { return isTree(t, SIGFIXDELAY, t0, t1);        }
+
+Sym SIGPREFIX = symbol ("sigPrefix");
+Tree  sigPrefix(Tree t0, Tree t1)                                      { return tree(SIGPREFIX, t0, t1);               }
+bool  isSigPrefix(Tree t, Tree& t0, Tree& t1)          { return isTree(t, SIGPREFIX, t0, t1);  }
+
+Sym SIGIOTA = symbol ("sigIota");
+Tree  sigIota(Tree t0)                                                         { return tree(SIGIOTA, t0);             }
+bool  isSigIota(Tree t, Tree& t0)                                      { return isTree(t, SIGIOTA, t0);        }
+
+
+// Read only and read write tables
+
+Sym SIGRDTBL = symbol ("SigRDTbl");
+Tree sigRDTbl (Tree t, Tree i)                                         { return tree(SIGRDTBL, t, i);  }
+bool isSigRDTbl (Tree s, Tree& t, Tree& i)                     { return isTree(s, SIGRDTBL, t, i);     }
+
+Sym SIGWRTBL = symbol ("SigWRTbl");
+Tree sigWRTbl (Tree id, Tree t, Tree i, Tree s)                                        { return tree(SIGWRTBL, id, t, i, s);   }
+bool isSigWRTbl (Tree u, Tree& id, Tree& t, Tree& i, Tree& s)  { return isTree(u, SIGWRTBL, id, t, i, s);      }
+
+Sym SIGTABLE = symbol ("SigTable");
+Tree sigTable (Tree id, Tree n, Tree sig)                              { return tree(SIGTABLE, id, n, sig);            }
+bool isSigTable (Tree t, Tree& id, Tree& n, Tree& sig) { return isTree(t, SIGTABLE, id, n, sig);       }
+
+// Signal used to generate the initial content of a table
+
+Sym SIGGEN = symbol ("SigGen");
+Tree sigGen (Tree s)                                                   { return tree(SIGGEN, s);               }
+bool isSigGen (Tree t, Tree& x)                                        { return isTree(t, SIGGEN, x);  }
+bool isSigGen (Tree t)                                                 { return t->node()== Node(SIGGEN);      }
+
+
+// Documentator Tables : special version of tables only for documentation purposes
+
+Sym SIGDOCONSTANTTBL = symbol ("SigDocConstantTbl");
+Tree   sigDocConstantTbl    (Tree n, Tree sig)                  { return tree(SIGDOCONSTANTTBL, n, sig);        }
+bool isSigDocConstantTbl    (Tree t, Tree& n, Tree& sig)        { return isTree(t, SIGDOCONSTANTTBL, n, sig);  }
+
+Sym SIGDOCWRITETBL = symbol ("SigDocWriteTbl");
+Tree   sigDocWriteTbl   (Tree n, Tree sig, Tree widx, Tree wsig)                { return tree(SIGDOCWRITETBL, n, sig, widx, wsig);             }
+bool isSigDocWriteTbl   (Tree t, Tree& n, Tree& sig, Tree& widx, Tree& wsig)    { return isTree(t, SIGDOCWRITETBL, n, sig, widx, wsig);        }
+
+Sym SIGDOCACCESSTBL = symbol ("SigDocAccessTbl");
+Tree   sigDocAccessTbl   (Tree tbl, Tree ridx)                  { return tree(SIGDOCACCESSTBL, tbl, ridx);             }
+bool isSigDocAccessTbl   (Tree t, Tree& tbl, Tree& ridx)        { return isTree(t, SIGDOCACCESSTBL, tbl, ridx);        }
+
+
+// Select on signal among severals
+
+Sym SIGSELECT2 = symbol ("SigSelect2");
+Sym SIGSELECT3 = symbol ("SigSelect3");
+
+Tree sigSelect2 (Tree selector, Tree s1, Tree s2)                                                      { return tree(SIGSELECT2, sigIntCast(selector), s1, s2); }
+bool isSigSelect2 (Tree t, Tree& selector, Tree& s1, Tree& s2)                         { return isTree(t, SIGSELECT2, selector, s1, s2); }
+
+Tree sigSelect3 (Tree selector, Tree s1, Tree s2, Tree s3)                                     { return tree(SIGSELECT3, sigIntCast(selector), s1, s2, s3); }
+bool isSigSelect3 (Tree t, Tree& selector, Tree& s1, Tree& s2, Tree& s3)       { return isTree(t, SIGSELECT3, selector, s1, s2, s3); }
+
+
+// multirate
+
+Sym SIGVECTORIZE = symbol ("SigVectorize");
+Tree sigVectorize (Tree n, Tree s)                       { return tree(SIGVECTORIZE, n, s); }
+bool isSigVectorize (Tree a, Tree& n, Tree& s)           { return isTree(a, SIGVECTORIZE, n, s); }
+
+Sym SIGSERIALIZE = symbol ("SigSerialize");
+Tree sigSerialize (Tree s1)                             { return tree(SIGSERIALIZE, s1); }
+bool isSigSerialize (Tree a, Tree& s1)                  { return isTree(a, SIGSERIALIZE, s1); }
+
+Sym SIGCONCAT = symbol ("SigConcat");
+Tree sigConcat (Tree s1, Tree s2)                       { return tree(SIGCONCAT, s1, s2); }
+bool isSigConcat (Tree a, Tree& s1, Tree& s2)           { return isTree(a, SIGCONCAT, s1, s2); }
+
+Sym SIGVECTORAT = symbol ("SigVectorAt");
+Tree sigVectorAt (Tree s1, Tree s2)                     { return tree(SIGVECTORAT, s1, s2); }
+bool isSigVectorAt(Tree a, Tree& s1, Tree& s2)          { return isTree(a, SIGVECTORAT, s1, s2); }
+
+Sym SIGUPSAMPLE = symbol ("SigUpsample");
+Tree sigUpSample (Tree n, Tree s)                       { return tree(SIGUPSAMPLE, n, s); }
+bool isSigUpSample (Tree a, Tree& n, Tree& s)           { return isTree(a, SIGUPSAMPLE, n, s); }
+
+Sym SIGDOWNSAMPLE = symbol ("SigDownsample");
+Tree sigDownSample (Tree n, Tree s)                       { return tree(SIGDOWNSAMPLE, n, s); }
+bool isSigDownSample (Tree a, Tree& n, Tree& s)           { return isTree(a, SIGDOWNSAMPLE, n, s); }
+
+
+// Arithmetical operations
+
+Sym SIGBINOP = symbol ("SigBinOp");
+Tree sigBinOp(int op, Tree x, Tree y)                                  { return tree(SIGBINOP, tree(op), x, y); }
+bool isSigBinOp(Tree s, int* op, Tree& x, Tree& y)             { Tree t; return isTree(s, SIGBINOP, t, x, y) && isInt(t->node(),op); }
+
+
+// Foreign Functions
+
+Sym SIGFFUN = symbol ("SigFFun");
+Tree sigFFun (Tree ff, Tree largs)                                             { return tree(SIGFFUN, ff, largs);                      }
+bool isSigFFun (Tree s, Tree& ff, Tree& largs)                 { return isTree(s, SIGFFUN, ff, largs);         }
+
+
+Sym SIGFCONST = symbol ("SigFConst");
+Tree sigFConst      (Tree type, Tree name, Tree file)             { return tree(SIGFCONST, type, name, file);         }
+bool isSigFConst    (Tree s)                                      { Tree t,n,f; return isTree(s, SIGFCONST, t, n, f); }
+bool isSigFConst    (Tree s, Tree& type, Tree& name, Tree& file)  { return isTree(s, SIGFCONST,type, name, file);     }
+
+
+Sym SIGFVAR = symbol ("SigFVar");
+Tree sigFVar      (Tree type, Tree name, Tree file)               { return tree(SIGFVAR, type, name, file);           }
+bool isSigFVar    (Tree s)                                        { Tree t,n,f; return isTree(s, SIGFVAR, t, n, f);   }
+bool isSigFVar    (Tree s, Tree& type, Tree& name, Tree& file)    { return isTree(s, SIGFVAR, type, name, file);      }
+
+// nouvelle version utilisant rec et ref
+
+Sym SIGPROJ = symbol ("SigProj");
+Tree sigProj (int i, Tree rgroup)                              { return tree(SIGPROJ, tree(i), rgroup);        }
+bool isProj (Tree t, int* i, Tree& rgroup)             { Tree x; return isTree(t, SIGPROJ, x, rgroup) && isInt(x->node(), i);  }
+
+
+// Int and Float casting
+
+Sym SIGINTCAST = symbol ("sigIntCast");
+Sym SIGFLOATCAST = symbol ("sigFloatCast");
+
+Tree  sigIntCast(Tree t)                                               
+{ 
+       Node n = t->node();
+       
+       int i;          if (isInt(n, &i))                       return t; 
+       double x;       if (isDouble(n, &x))            return tree(int(x));
+                               if (isSigIntCast(t))            return t;
+        
+       return tree(SIGINTCAST, t);   
+}
+
+Tree  sigFloatCast(Tree t)                                             
+{ 
+       Node n = t->node();
+       
+       int i;          if (isInt(n, &i))                       return tree(double(i)); 
+       double x;       if (isDouble(n, &x))            return t;
+                               if (isSigFloatCast(t))          return t;
+                if (isSigInput(t, &i))      return t;
+        
+       return tree(SIGFLOATCAST, t);   
+}
+
+//Tree  sigFloatCast(Tree t)                                           { return isSigFloatCast(t)? t : tree(SIGFLOATCAST, t); }
+
+bool  isSigIntCast(Tree t)                                             { Tree x; return isTree(t, SIGINTCAST, x);      }
+bool  isSigIntCast(Tree t, Tree& x)                            { return isTree(t, SIGINTCAST, x);                      }
+
+bool  isSigFloatCast(Tree t)                                   { Tree x; return isTree(t, SIGFLOATCAST, x);}
+bool  isSigFloatCast(Tree t, Tree& x)                  { return isTree(t, SIGFLOATCAST, x);            }
+
+
+
+
+/*****************************************************************************
+                                                        User Interface Elements
+*****************************************************************************/
+
+Sym SIGBUTTON = symbol ("SigButton");
+Tree sigButton          (Tree lbl)                                     { return tree(SIGBUTTON, lbl);                                  }
+bool isSigButton (Tree s)                                      { Tree lbl; return isTree(s, SIGBUTTON, lbl);   }
+bool isSigButton (Tree s, Tree& lbl)           { return isTree(s, SIGBUTTON, lbl);                             }
+
+
+Sym SIGCHECKBOX = symbol ("SigCheckbox");
+Tree sigCheckbox   (Tree lbl)                          { return tree(SIGCHECKBOX, lbl);                                        }
+bool isSigCheckbox (Tree s)                                    { Tree lbl; return isTree(s, SIGCHECKBOX, lbl); }
+bool isSigCheckbox (Tree s, Tree& lbl)         { return isTree(s, SIGCHECKBOX, lbl);                           }
+
+
+Sym SIGHSLIDER = symbol ("SigHSlider");
+Tree sigHSlider   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
+                                                                                       { return tree(SIGHSLIDER, lbl, list4(cur,min,max,step));                }
+bool isSigHSlider (Tree s)                                     { Tree lbl, params; return isTree(s, SIGHSLIDER, lbl, params);  }
+
+bool isSigHSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
+{
+       Tree params;
+       if (isTree(s, SIGHSLIDER, lbl, params)) {
+               cur = nth(params, 0);
+               min = nth(params, 1);
+               max = nth(params, 2);
+               step= nth(params, 3);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
+Sym SIGVSLIDER = symbol ("SigVSlider");
+Tree sigVSlider   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
+                                                                                       { return tree(SIGVSLIDER, lbl, list4(cur,min,max,step));                }
+bool isSigVSlider (Tree s)                                     { Tree lbl, params; return isTree(s, SIGVSLIDER, lbl, params);  }
+
+bool isSigVSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
+{
+       Tree params;
+       if (isTree(s, SIGVSLIDER, lbl, params)) {
+               cur = nth(params, 0);
+               min = nth(params, 1);
+               max = nth(params, 2);
+               step= nth(params, 3);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
+Sym SIGNUMENTRY = symbol ("SigNumEntry");
+Tree sigNumEntry   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
+                                                                                       { return tree(SIGNUMENTRY, lbl, list4(cur,min,max,step));               }
+bool isSigNumEntry (Tree s)                                    { Tree lbl, params; return isTree(s, SIGNUMENTRY, lbl, params); }
+
+bool isSigNumEntry (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
+{
+       Tree params;
+       if (isTree(s, SIGNUMENTRY, lbl, params)) {
+               cur = nth(params, 0);
+               min = nth(params, 1);
+               max = nth(params, 2);
+               step= nth(params, 3);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+// output elements
+
+
+
+Sym SIGHBARGRAPH = symbol ("SigHBargraph");
+Tree sigHBargraph   (Tree lbl, Tree min, Tree max, Tree x)                             { return tree(SIGHBARGRAPH, lbl, min, max, x);          }
+bool isSigHBargraph (Tree s)                                                                                   { Tree lbl, min, max, x; return isTree(s, SIGHBARGRAPH, lbl, min, max, x);      }
+bool isSigHBargraph (Tree s, Tree& lbl, Tree& min, Tree& max, Tree& x) { return isTree(s, SIGHBARGRAPH, lbl, min, max, x);     }
+
+
+Sym SIGVBARGRAPH = symbol ("SigVBargraph");
+Tree sigVBargraph   (Tree lbl, Tree min, Tree max, Tree x)                             { return tree(SIGVBARGRAPH, lbl, min, max, x);          }
+bool isSigVBargraph (Tree s)                                                                                   { Tree lbl, min, max, x; return isTree(s, SIGVBARGRAPH, lbl, min, max, x);      }
+bool isSigVBargraph (Tree s, Tree& lbl, Tree& min, Tree& max, Tree& x) { return isTree(s, SIGVBARGRAPH, lbl, min, max, x);     }
+
+
+Sym SIGATTACH = symbol ("sigAttach");
+Tree  sigAttach(Tree t0, Tree t1)                                      { return tree(SIGATTACH, t0, t1);               }
+bool  isSigAttach(Tree t, Tree& t0, Tree& t1)          { return isTree(t, SIGATTACH, t0, t1);  }
+
+
+
+Tree addNums(Tree a, Tree b)
+{
+       Tree r = tree(addNode(a->node(),b->node()));
+       //cerr.flags(ios::showpoint); cerr << "addNums " << *a << "+" << *b << " -> " << *r << endl;
+       return r;
+}
+
+Tree subNums(Tree a, Tree b)
+{
+       Tree r = tree(subNode(a->node(),b->node()));
+       //cerr.flags(ios::showpoint); cerr << "subNums " << *a << "-" << *b << " -> " << *r << endl;
+       return r;
+}
+
+Tree mulNums(Tree a, Tree b)
+{
+       Tree r = tree(mulNode(a->node(),b->node()));
+       //cerr.flags(ios::showpoint); cerr << "mulNums " << *a << "*" << *b << " -> " << *r << endl;
+       return r;
+}
+
+Tree divNums(Tree a, Tree b)
+{
+       Tree r = tree(divNode(a->node(),b->node()));
+       //cerr.flags(ios::showpoint); cerr << "divNums " << *a << "/" << *b << " -> " << *r << endl;
+       return r;
+}
+
+Tree divExtendedNums(Tree a, Tree b)
+{
+       Tree r = tree(divExtendedNode(a->node(),b->node()));
+       //cerr.flags(ios::showpoint); cerr << "divExtendeNums " << *a << "/" << *b << " -> " << *r << endl;
+       return r;
+}
+
+Tree minusNum(Tree a)
+{
+       Tree r = tree(minusNode(a->node()));
+       //cerr.flags(ios::showpoint); cerr << "minusNum " << *a << " -> " << *r << endl;
+       return r;
+}
+
+Tree inverseNum(Tree a)
+{
+       Tree r = tree(inverseNode(a->node()));
+       //cerr.flags(ios::showpoint); cerr << "inverseNum " << *a << " -> " << *r << endl;
+       return r;
+}
+
+bool isSigAdd(Tree a, Tree& x, Tree& y)
+{
+       int     op;
+       return isSigBinOp(a, &op, x, y) && (op == kAdd);
+}
+
+bool isSigMul(Tree a, Tree& x, Tree& y)
+{
+       int     op;
+       return isSigBinOp(a, &op, x, y) && (op == kMul);
+}
+
+bool isSigSub(Tree a, Tree& x, Tree& y)
+{
+       int     op;
+       return isSigBinOp(a, &op, x, y) && (op == kSub);
+}
+
+bool isSigDiv(Tree a, Tree& x, Tree& y)
+{
+       int     op;
+       return isSigBinOp(a, &op, x, y) && (op == kDiv);
+}
+
+
+
+
+/*****************************************************************************
+                                                        matrix extension
+*****************************************************************************/
+Sym SIGTUPLE           = symbol ("SigTuple");
+Sym SIGTUPLEACCESS     = symbol ("SigTupleAccess");
+
+// a tuple of signals is basically a list of signals.
+// mode = 0 means normal, mode = 1 means blocked
+Tree sigTuple (int mode, Tree ls)                                      { return tree(SIGTUPLE, tree(mode), ls); }
+bool isSigTuple (Tree s, int* mode, Tree& ls)          { Tree m; return isTree(s, SIGTUPLE, m, ls) && isInt(m->node(), mode); }
+
+// Access the components of a tuple.
+// ts is tuple of signals, idx is a scalar signal between 0..n
+Tree sigTupleAccess(Tree ts, Tree idx)                         { return tree(SIGTUPLEACCESS, ts, idx); }
+bool isSigTupleAccess(Tree s, Tree& ts, Tree& idx)     { return isTree(s, SIGTUPLEACCESS, ts, idx); }
+
+// create a tuple of signals
+Tree sigCartesianProd (Tree s1, Tree s2)
+{
+       Tree    l1, l2;
+       int             m1, m2;
+
+       if (isSigTuple(s1, &m1, l1) && (m1 == 0)) {
+               // nothing to do
+       } else {
+               l1 = list1(s1);
+       }
+
+       if (isSigTuple(s2, &m2, l2) && (m2 == 0)) {
+               // nothing to do
+       } else {
+               l2 = list1(s2);
+       }
+
+
+       return sigTuple(0, concat(l1,l2));
+}
+
+
+
+/**
+ * Test if exp is very simple that is it
+ * can't be considered a real component
+ * @param exp the signal we want to test
+ * @return true if it a very simple signal
+ */
+bool verySimple(Tree exp)
+{
+       int             i;
+       double  r;
+       Tree    type, name, file;
+       
+       return  isSigInt(exp, &i) 
+                       ||      isSigReal(exp, &r)
+                       ||      isSigInput(exp, &i)
+                       ||      isSigFConst(exp, type, name, file);
+}