1 /************************************************************************ 2 ************************************************************************ 3 FAUST compiler 4 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale 5 --------------------------------------------------------------------- 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 ************************************************************************ 20 ************************************************************************/ 21 22 #include <math.h> 23 24 #include "Text.hh" 25 #include "floats.hh" 26 #include "xtended.hh" 27 28 #ifndef M_PI 29 #define M_PI 3.14159265358979323846 30 #endif 31 32 class TanPrim : public xtended { 33 public: TanPrim()34 TanPrim() : xtended("tan") {} 35 arity()36 virtual unsigned int arity() { return 1; } 37 needCache()38 virtual bool needCache() { return true; } 39 infereSigType(const vector<::Type> & args)40 virtual ::Type infereSigType(const vector<::Type>& args) 41 { 42 faustassert(args.size() == 1); 43 interval srcInterval = args[0]->getInterval(); 44 const double halfpi = M_PI / 2; 45 interval resultInterval; 46 47 // the check can be improved to ensure that no infinity is in the range 48 if (srcInterval.valid) { 49 if ((-halfpi < srcInterval.lo) && (srcInterval.hi < halfpi)) 50 resultInterval = interval(tan(srcInterval.lo), tan(srcInterval.hi)); 51 } 52 return castInterval(floatCast(args[0]), resultInterval); 53 } 54 infereSigOrder(const vector<int> & args)55 virtual int infereSigOrder(const vector<int>& args) { return args[0]; } 56 computeSigOutput(const vector<Tree> & args)57 virtual Tree computeSigOutput(const vector<Tree>& args) 58 { 59 num n; 60 if (isNum(args[0], n)) { 61 return tree(tan(double(n))); 62 } else { 63 return tree(symbol(), args[0]); 64 } 65 } 66 generateCode(CodeContainer * container,const list<ValueInst * > & args,::Type result,vector<::Type> const & types)67 virtual ValueInst* generateCode(CodeContainer* container, const list<ValueInst*>& args, ::Type result, 68 vector< ::Type> const& types) 69 { 70 faustassert(args.size() == arity()); 71 faustassert(types.size() == arity()); 72 73 Typed::VarType result_type; 74 vector<Typed::VarType> arg_types; 75 list<ValueInst*> casted_args; 76 prepareTypeArgsResult(result, args, types, result_type, arg_types, casted_args); 77 78 return container->pushFunction(subst("tan$0", isuffix()), result_type, arg_types, casted_args); 79 } 80 old_generateCode(Klass * klass,const vector<string> & args,const vector<::Type> & types)81 virtual string old_generateCode(Klass* klass, const vector<string>& args, const vector<::Type>& types) 82 { 83 faustassert(args.size() == arity()); 84 faustassert(types.size() == arity()); 85 86 return subst("tan$1($0)", args[0], isuffix()); 87 } 88 generateLateq(Lateq * lateq,const vector<string> & args,const vector<::Type> & types)89 virtual string generateLateq(Lateq* lateq, const vector<string>& args, const vector<::Type>& types) 90 { 91 faustassert(args.size() == arity()); 92 faustassert(types.size() == arity()); 93 94 return subst("\\tan\\left($0\\right)", args[0]); 95 } 96 }; 97