diff --git a/compiler/extended/internalprim.hh b/compiler/extended/internalprim.hh new file mode 100644 index 0000000000..86278e87a0 --- /dev/null +++ b/compiler/extended/internalprim.hh @@ -0,0 +1,102 @@ +/************************************************************************ + ************************************************************************ + 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" + +enum InternalOp { kId, kRate, kLo, kHi }; + +class InternalPrim : public xtended { + private: + InternalOp fOp; + public: + InternalPrim(InternalOp op, const char *name) : xtended(name), fOp(op) {} + + virtual Tree computeSigOutput(const std::vector& args) + { + Tree sig = simplify(args[0]); + int ret = -1; + + switch (fOp) { + case kId: + ret = sig->serial(); + break; + case kRate: + ret = getSigOrder(sig); + break; + case kLo: case kHi: { + typeAnnotation(sig, false); + interval i = getCertifiedSigType(sig)->getInterval(); + return tree(fOp == kLo ? i.lo() : i.hi()); + } + default: + faustassert(false); + } + + return tree(ret); + } + + virtual unsigned int arity() { return 1; } + + virtual bool needCache() { return true; } + + virtual ::Type inferSigType(ConstTypes args) + { + faustassert(false); return 0; + } + virtual int inferSigOrder(const std::vector& 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& args, ConstTypes types) + { + faustassert(false); return 0; + } + virtual std::string generateLateq(Lateq* lateq, const std::vector& args, ConstTypes types) + { + return "TODO"; + } +}; + +static Tree add_internal_def(Tree defs, InternalOp op, const char *d_n) +{ + Tree id = boxIdent(d_n); + std::string x_n = std::string("internal.") + d_n; + InternalPrim *internal = new InternalPrim(op, x_n.c_str()); + return cons(cons(id, internal->box()), defs); +} + +static Tree mkInternalEnv() +{ + Tree defs = gGlobal->nil; + + defs = add_internal_def(defs, kId, "id"); + defs = add_internal_def(defs, kRate, "rate"); + defs = add_internal_def(defs, kLo, "lo"); + defs = add_internal_def(defs, kHi, "hi"); + + return boxWithLocalDef(boxEnvironment(), defs); +} diff --git a/compiler/global.cpp b/compiler/global.cpp index 54b372204e..9cae1b950e 100644 --- a/compiler/global.cpp +++ b/compiler/global.cpp @@ -49,6 +49,7 @@ #include "sourcereader.hh" #include "sqrtprim.hh" #include "tanprim.hh" +#include "internalprim.hh" #include "tree.hh" #include "occur.hh" #include "enrobage.hh" @@ -614,6 +615,8 @@ void global::init() // Predefined nil tree nil = tree(NIL); + gInternalEnv = mkInternalEnv(); + PROCESS = symbol("process"); BOXTYPEPROP = tree(symbol("boxTypeProp")); diff --git a/compiler/global.hh b/compiler/global.hh index 0be0ca213e..f780297bfb 100644 --- a/compiler/global.hh +++ b/compiler/global.hh @@ -326,7 +326,9 @@ struct global { xtended* gAtanPrim; xtended* gAtan2Prim; xtended* gAsinPrim; - + + Tree gInternalEnv; + // Signals Sym BOXIDENT; Sym BOXCUT; diff --git a/compiler/parser/faustlexer.l b/compiler/parser/faustlexer.l index 10871bd940..a1e4d25489 100644 --- a/compiler/parser/faustlexer.l +++ b/compiler/parser/faustlexer.l @@ -199,6 +199,8 @@ NSID {ID}("::"{ID})* "sum" return ISUM; "prod" return IPROD; +"internal" return INTERNAL; + "inputs" return INPUTS; "outputs" return OUTPUTS; diff --git a/compiler/parser/faustparser.y b/compiler/parser/faustparser.y index d11678a328..3c69d13c2c 100644 --- a/compiler/parser/faustparser.y +++ b/compiler/parser/faustparser.y @@ -218,6 +218,8 @@ inline Tree unquote(char* str) %token ISUM %token IPROD +%token INTERNAL + %token INPUTS %token OUTPUTS @@ -589,6 +591,7 @@ primitive : INT { $$ = boxInt(str2int(FAUSTtext) | ffunction { $$ = boxFFun($1); } | fconst { $$ = $1; } | fvariable { $$ = $1; } + | INTERNAL { $$ = gGlobal->gInternalEnv; } | COMPONENT LPAR uqstring RPAR { $$ = boxComponent($3); } | LIBRARY LPAR uqstring RPAR { $$ = boxLibrary($3); } | ENVIRONMENT LBRAQ stmtlist RBRAQ { $$ = boxWithLocalDef(boxEnvironment(),formatDefinitions($3)); }