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
[email protected]
https://lists.sourceforge.net/lists/listinfo/faudiostream-devel