Stephane, Yann,

Can I suggest another feature? The patch is not for inclusion yet,
but I'd like to discuss the idea / implementation.

It adds the new keyword `meta` which returns the environment with
2 primitives (so far):

        1. serial(sig)  - returns sig->serial()
        2. order(sig)   - getSigOrder(sig)

Note that they compute the returned value at compile time.

Why the environment? Because this way it is very easy to add more
primitives (e.g. typeof(sig) which returns kBool / kInt / kReal)
using a single keyword.

Why do we want this feature? Well, I certainly do ;) but I do not
have a simple and convincing example.

-------------------------------------------------------------------------------
But let me provide a basic example even if it is not convincing.
Consider:

        process(x,y) = atan2(x,x), atan2(x,y);
        
it compiles to

        float fTemp0 = float(input0[i0]);
        output0[i0] = FAUSTFLOAT(std::atan2(fTemp0, fTemp0));
        output1[i0] = FAUSTFLOAT(std::atan2(fTemp0, float(input1[i0])));

note that atan2(fTemp0, fTemp0) == %pi/4 (lets ignore the fTemp0 == 0
case for the sake of simplicity), so this code is suboptimal.

Let's try to improve this code:

        my_atan2(a,b) = select2(a == b, atan2(a,b), ma.PI/4);
        process(x,y) = my_atan2(x,x), my_atan2(x,y);

result:

        float fTemp0 = float(input0[i0]);
        output0[i0] = FAUSTFLOAT(((fTemp0 == fTemp0) ? 0.7853982f : 
std::atan2(fTemp0, fTemp0)));
        float fTemp1 = float(input1[i0]);
        output1[i0] = FAUSTFLOAT(((fTemp0 == fTemp1) ? 0.7853982f : 
std::atan2(fTemp0, fTemp1)));

doesn't look very good although the compiler will optimize out the 1st `fTemp0 
== fTemp0` check.

Now let's use meta.serial:

        same_signal(a,b) = meta.serial(a) == meta.serial(b);

        my_atan2(a,b) = select2(same_signal(a,b), atan2(a,b), ma.PI/4);
        process(x,y) = my_atan2(x,x), my_atan2(x,y);

result:

        output0[i0] = FAUSTFLOAT(0.7853982f);
        output1[i0] = FAUSTFLOAT(std::atan2(float(input0[i0]), 
float(input1[i0])));

Oleg.
---
 compiler/extended/metaprim.hh | 94 +++++++++++++++++++++++++++++++++++
 compiler/global.cpp           |  3 ++
 compiler/global.hh            |  2 +
 compiler/parser/faustlexer.l  |  2 +
 compiler/parser/faustparser.y |  3 ++
 5 files changed, 104 insertions(+)
 create mode 100644 compiler/extended/metaprim.hh

diff --git a/compiler/extended/metaprim.hh b/compiler/extended/metaprim.hh
new file mode 100644
index 000000000..20cc5982e
--- /dev/null
+++ b/compiler/extended/metaprim.hh
@@ -0,0 +1,94 @@
+/************************************************************************
+ ************************************************************************
+    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 "xtended.hh"
+#include "simplify.hh"
+#include "sigorderrules.hh"
+
+class MetaPrim : public xtended {
+    private:
+       int fOp;
+    public:
+       MetaPrim(int op, const char *name) : xtended(name), fOp(op) {}
+
+       virtual unsigned int arity() { return 1; }
+
+       virtual bool needCache() { return true; }
+
+       virtual int infereSigOrder(const std::vector<int>& args) { return 0; }
+
+       virtual Tree computeSigOutput(const std::vector<Tree>& args)
+       {
+               Tree sig = simplify(args[0]);
+               int ret = -1;
+
+               switch (fOp) {
+               case 0:
+                       ret = sig->serial();
+                       break;
+               case 1:
+                       ret = getSigOrder(sig);
+                       break;
+               default:
+                       faustassert(false);
+               }
+
+               return tree(ret);
+       }
+
+       virtual ::Type infereSigType(ConstTypes args)
+       {
+               faustassert(false); return 0;
+       }
+
+       virtual ValueInst* generateCode(CodeContainer* container, Values& args, 
::Type result, ConstTypes types)
+       {
+               faustassert(false); return 0;
+       }
+
+       virtual std::string generateCode(Klass* klass, const 
std::vector<std::string>& args, ConstTypes types)
+       {
+               faustassert(false); return 0;
+       }
+
+       virtual std::string generateLateq(Lateq* lateq, const 
std::vector<std::string>& args, ConstTypes types)
+       {
+               return "TODO";
+       }
+};
+
+static Tree add_meta_def(Tree defs, int op, const char *d_n)
+{
+       Tree id = boxIdent(d_n);
+       std::string x_n = std::string("meta_") + d_n;
+       MetaPrim *meta = new MetaPrim(op, x_n.c_str());
+       return cons(cons(id, meta->box()), defs);
+}
+
+static Tree mkMetaEnv()
+{
+       Tree defs = gGlobal->nil;
+
+       defs = add_meta_def(defs, 0, "serial");
+       defs = add_meta_def(defs, 1, "order");
+
+       return boxWithLocalDef(boxEnvironment(), defs);
+}
diff --git a/compiler/global.cpp b/compiler/global.cpp
index 29af5eb9d..6636eac92 100644
--- a/compiler/global.cpp
+++ b/compiler/global.cpp
@@ -48,6 +48,7 @@
 #include "sourcereader.hh"
 #include "sqrtprim.hh"
 #include "tanprim.hh"
+#include "metaprim.hh"
 #include "tree.hh"
 #include "occur.hh"
 #include "enrobage.hh"
@@ -592,6 +593,8 @@ void global::init()
     // Predefined nil tree
     nil = tree(NIL);
 
+    gMetaEnv = mkMetaEnv();
+
     PROCESS = symbol("process");
 
     BOXTYPEPROP      = tree(symbol("boxTypeProp"));
diff --git a/compiler/global.hh b/compiler/global.hh
index e8ced28c8..dbb001e7c 100644
--- a/compiler/global.hh
+++ b/compiler/global.hh
@@ -322,6 +322,8 @@ struct global {
     xtended* gAtan2Prim;
     xtended* gAsinPrim;
  
+    Tree gMetaEnv;
+
     // Signals
     Sym BOXIDENT;
     Sym BOXCUT;
diff --git a/compiler/parser/faustlexer.l b/compiler/parser/faustlexer.l
index c92210cb5..c9342848f 100644
--- a/compiler/parser/faustlexer.l
+++ b/compiler/parser/faustlexer.l
@@ -198,6 +198,8 @@ NSID     {ID}("::"{ID})*
 "sum"         return ISUM;
 "prod"        return IPROD;
 
+"meta"        return META;
+
 "inputs"      return INPUTS;
 "outputs"     return OUTPUTS;
 
diff --git a/compiler/parser/faustparser.y b/compiler/parser/faustparser.y
index 0f29d3403..5c9d49379 100644
--- a/compiler/parser/faustparser.y
+++ b/compiler/parser/faustparser.y
@@ -217,6 +217,8 @@ inline Tree unquote(char* str)
 %token ISUM
 %token IPROD
 
+%token META
+
 %token INPUTS
 %token OUTPUTS
 
@@ -587,6 +589,7 @@ primitive       : INT                           { $$ = 
boxInt(str2int(FAUSTtext)
                 | ffunction                     { $$ = boxFFun($1); }
                 | fconst                        { $$ = $1; }
                 | fvariable                     { $$ = $1; }
+                | META                          { $$ = gGlobal->gMetaEnv; }
                 | COMPONENT LPAR uqstring RPAR  { $$ = boxComponent($3); }
                 | LIBRARY LPAR uqstring RPAR    { $$ = boxLibrary($3); }
                 | ENVIRONMENT LBRAQ stmtlist RBRAQ { $$ = 
boxWithLocalDef(boxEnvironment(),formatDefinitions($3)); }
-- 
2.39.2




_______________________________________________
Faudiostream-devel mailing list
Faudiostream-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-devel

Reply via email to