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 class SqrtPrim : public xtended { 29 public: SqrtPrim()30 SqrtPrim() : xtended("sqrt") {} 31 arity()32 virtual unsigned int arity() { return 1; } 33 needCache()34 virtual bool needCache() { return true; } 35 infereSigType(const vector<::Type> & args)36 virtual ::Type infereSigType(const vector<::Type>& args) 37 { 38 faustassert(args.size() == 1); 39 Type t = args[0]; 40 interval i = t->getInterval(); 41 if (i.valid) { 42 if (i.lo >= 0) { 43 return castInterval(floatCast(t), interval(sqrt(i.lo), sqrt(i.hi))); 44 } else if (gGlobal->gMathExceptions) { 45 cerr << "WARNING : potential out of domain in sqrt(" << i << ")" << endl; 46 } 47 } 48 return castInterval(floatCast(t), interval()); 49 } 50 infereSigOrder(const vector<int> & args)51 virtual int infereSigOrder(const vector<int>& args) { return args[0]; } 52 computeSigOutput(const vector<Tree> & args)53 virtual Tree computeSigOutput(const vector<Tree>& args) 54 { 55 // check simplifications 56 num n; 57 if (isNum(args[0], n)) { 58 if (double(n) < 0) { 59 stringstream error; 60 error << "ERROR : out of domain sqrt(" << ppsig(args[0]) << ")" << endl; 61 throw faustexception(error.str()); 62 } else { 63 return tree(sqrt(double(n))); 64 } 65 } else { 66 return tree(symbol(), args[0]); 67 } 68 } 69 generateCode(CodeContainer * container,const list<ValueInst * > & args,::Type result,vector<::Type> const & types)70 virtual ValueInst* generateCode(CodeContainer* container, const list<ValueInst*>& args, ::Type result, 71 vector< ::Type> const& types) 72 { 73 faustassert(args.size() == arity()); 74 faustassert(types.size() == arity()); 75 76 Typed::VarType result_type; 77 vector<Typed::VarType> arg_types; 78 list<ValueInst*> casted_args; 79 prepareTypeArgsResult(result, args, types, result_type, arg_types, casted_args); 80 81 return container->pushFunction(subst("sqrt$0", isuffix()), result_type, arg_types, casted_args); 82 } 83 old_generateCode(Klass * klass,const vector<string> & args,const vector<::Type> & types)84 virtual string old_generateCode(Klass* klass, const vector<string>& args, const vector<::Type>& types) 85 { 86 faustassert(args.size() == arity()); 87 faustassert(types.size() == arity()); 88 89 return subst("sqrt$1($0)", args[0], isuffix()); 90 } 91 generateLateq(Lateq * lateq,const vector<string> & args,const vector<::Type> & types)92 virtual string generateLateq(Lateq* lateq, const vector<string>& args, const vector<::Type>& types) 93 { 94 faustassert(args.size() == arity()); 95 faustassert(types.size() == arity()); 96 97 return subst("\\sqrt{$0}", args[0]); 98 } 99 }; 100