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 #ifndef __XTENDED__
23 #define __XTENDED__
24 
25 #include <vector>
26 
27 #include "garbageable.hh"
28 #include "instructions.hh"
29 #include "klass.hh"
30 #include "lateq.hh"
31 #include "sigtype.hh"
32 #include "sigvisitor.hh"
33 #include "tlib.hh"
34 #include "ppsig.hh"
35 
36 class CodeContainer;
37 
38 class xtended : public virtual Garbageable {
39    private:
40     Symbol* fSymbol;  ///< the symbol the xtended is attached to
41 
42    public:
xtended(const char * name)43     xtended(const char* name) : fSymbol(::symbol(name)) { setUserData(fSymbol, (void*)this); }
~xtended()44     virtual ~xtended() {}
45 
symbol()46     Sym         symbol() { return fSymbol; }
name()47     const char* name() { return ::name(fSymbol); }
48 
box()49     Tree box()
50     {
51         Tree b = tree(fSymbol);
52         faustassert(getUserData(b) != nullptr);
53         return b;
54     }
55 
56     // virtual method to be implemented by subclasses
57     virtual unsigned int arity() = 0;
58 
59     virtual ValueInst* generateCode(CodeContainer* container, const list<ValueInst*>& args, ::Type result_type,
60                                     vector<::Type> const& types) = 0;
61 
62     // SL : 28/09/17
63     // Old CPP backend
64     virtual string old_generateCode(Klass* klass, const vector<string>& args, const vector<Type>& types) = 0;
65 
66     virtual string generateLateq(Lateq* lateq, const vector<string>& args, const vector< ::Type>& types) = 0;
67     virtual int    infereSigOrder(const vector<int>& args)                                               = 0;
68     virtual ::Type infereSigType(const vector< ::Type>& args)                                            = 0;
69     virtual Tree   computeSigOutput(const vector<Tree>& args)                                            = 0;
70     virtual bool   needCache()                                                                           = 0;
71 
isSpecialInfix()72     virtual bool isSpecialInfix()
73     {
74         return false;
75     }  ///< generally false, but true for binary op # such that #(x) == _#x
76 
77     void prepareTypeArgsResult(::Type result, const list<ValueInst*>& args, vector<::Type> const& types,
78                                Typed::VarType& result_type, vector<Typed::VarType>& arg_types,
79                                list<ValueInst*>& casted_args);
80 };
81 
82 // True if two floating point numbers are close enough to be considered identical.
83 // It is used to recognize PI/n and 0 in some symbolic simplifications.
comparable(double x,double y)84 inline bool comparable(double x, double y)
85 {
86     return fabs(x - y) < 0.00001;
87 }
88 
promote2real(int type,ValueInst * val)89 inline ValueInst* promote2real(int type, ValueInst* val)
90 {
91     return (type == kReal) ? val : InstBuilder::genCastFloatInst(val);
92 }
promote2int(int type,ValueInst * val)93 inline ValueInst* promote2int(int type, ValueInst* val)
94 {
95     return (type == kInt) ? val : InstBuilder::genCastInt32Inst(val);
96 }
97 
cast2real(int type,ValueInst * val)98 inline ValueInst* cast2real(int type, ValueInst* val)
99 {
100     return (type == kReal) ? InstBuilder::genCastFloatInst(val) : val;
101 }
cast2int(int type,ValueInst * val)102 inline ValueInst* cast2int(int type, ValueInst* val)
103 {
104     return (type == kInt) ? InstBuilder::genCastInt32Inst(val) : val;
105 }
106 
107 #endif
108