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