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 CeilPrim : public xtended { 29 public: CeilPrim()30 CeilPrim() : xtended("ceil") {} 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() == arity()); 39 return floatCast(args[0]); 40 } 41 infereSigOrder(const vector<int> & args)42 virtual int infereSigOrder(const vector<int>& args) 43 { 44 faustassert(args.size() == arity()); 45 return args[0]; 46 } 47 computeSigOutput(const vector<Tree> & args)48 virtual Tree computeSigOutput(const vector<Tree>& args) 49 { 50 num n; 51 faustassert(args.size() == arity()); 52 if (isNum(args[0], n)) { 53 return tree(ceil(double(n))); 54 } else { 55 if (gGlobal->gMathApprox) { 56 // res = T(int(n)); return (r == n) ? n : (n >= 0 ? r + 1 : r); 57 Tree r = sigFloatCast(sigIntCast(args[0])); 58 return sigSelect2(sigBinOp(kEQ, args[0], r), sigSelect2(sigBinOp(kGE, args[0], sigInt(0)), r, sigBinOp(kAdd, r, sigInt(1))), args[0]); 59 } else { 60 return tree(symbol(), args[0]); 61 } 62 } 63 } 64 generateCode(CodeContainer * container,const list<ValueInst * > & args,::Type result,vector<::Type> const & types)65 virtual ValueInst* generateCode(CodeContainer* container, const list<ValueInst*>& args, ::Type result, 66 vector< ::Type> const& types) 67 { 68 faustassert(args.size() == arity()); 69 faustassert(types.size() == arity()); 70 71 Typed::VarType result_type; 72 vector<Typed::VarType> arg_types; 73 list<ValueInst*> casted_args; 74 prepareTypeArgsResult(result, args, types, result_type, arg_types, casted_args); 75 76 return container->pushFunction(subst("ceil$0", isuffix()), result_type, arg_types, casted_args); 77 } 78 old_generateCode(Klass * klass,const vector<string> & args,const vector<::Type> & types)79 virtual string old_generateCode(Klass* klass, const vector<string>& args, const vector<::Type>& types) 80 { 81 faustassert(args.size() == arity()); 82 faustassert(types.size() == arity()); 83 84 return subst("ceil$1($0)", args[0], isuffix()); 85 } 86 generateLateq(Lateq * lateq,const vector<string> & args,const vector<::Type> & types)87 virtual string generateLateq(Lateq* lateq, const vector<string>& args, const vector<::Type>& types) 88 { 89 faustassert(args.size() == arity()); 90 faustassert(types.size() == arity()); 91 92 return subst("\\left\\lceil $0 \\right\\rceil", args[0]); 93 } 94 }; 95