FAUST compiler  0.9.9.6b8
minprim.cpp
Go to the documentation of this file.
1 #include "xtended.hh"
2 #include "Text.hh"
3 #include <math.h>
4 #include "sigtyperules.hh"
5 
6 #include "floats.hh"
7 
8 class MinPrim : public xtended
9 {
10 
11  public:
12 
13  MinPrim() : xtended("min") {}
14 
15  virtual unsigned int arity () { return 2; }
16 
17  virtual bool needCache () { return true; }
18 
19  virtual Type infereSigType (const vector<Type>& types)
20  {
21  assert (types.size() == arity());
22  interval i = types[0]->getInterval();
23  interval j = types[1]->getInterval();
24  return castInterval(types[0]|types[1], min(i,j));
25  }
26 
27  virtual void sigVisit (Tree sig, sigvisitor* visitor) {}
28 
29  virtual int infereSigOrder (const vector<int>& args)
30  {
31  assert (args.size() == arity());
32  return max(args[0], args[1]);
33  }
34 
35 
36  virtual Tree computeSigOutput (const vector<Tree>& args)
37  {
38  double f,g; int i,j;
39 
40  assert (args.size() == arity());
41 
42  if (isDouble(args[0]->node(),&f)) {
43 
44  if (isDouble(args[1]->node(), &g)) {
45  return tree(min(f, g));
46  } else if (isInt(args[1]->node(),&j)) {
47  return tree(min(f, double(j)));
48  } else {
49  return tree(symbol(), args[0], args[1]);
50  }
51 
52  } else if (isInt(args[0]->node(),&i)) {
53 
54  if (isDouble(args[1]->node(), &g)) {
55  return tree(min(double(i), g));
56  } else if (isInt(args[1]->node(),&j)) {
57  return tree(min(i, j));
58  } else {
59  return tree(symbol(), args[0], args[1]);
60  }
61 
62  } else {
63 
64  return tree(symbol(), args[0], args[1]);
65  }
66  }
67 
68 // virtual string generateCode (Klass* klass, const vector<string>& args, const vector<Type>& types)
69 // {
70 // assert (args.size() == arity());
71 // assert (types.size() == arity());
79 
80 // // generates code compatible with overloaded min
81 // int n0 = types[0]->nature();
82 // int n1 = types[1]->nature();
83 // if (n0==n1) {
84 // return subst("min($0, $1)", args[0], args[1]);
85 // } else {
86 // if (n0==kInt) {
87 // return subst("min($2$0, $1)", args[0], args[1], icast());
88 // } else {
89 // return subst("min($0, $2$1)", args[0], args[1], icast());
90 // }
91 // }
92 // }
93 
94  virtual string generateCode (Klass* klass, const vector<string>& args, const vector<Type>& types)
95  {
96  assert (args.size() == arity());
97  assert (types.size() == arity());
98 
99  // generates code compatible with overloaded min
100  int n0 = types[0]->nature();
101  int n1 = types[1]->nature();
102  if (n0==kReal) {
103  if (n1==kReal) {
104  // both are floats, no need to cast
105  return subst("min($0, $1)", args[0], args[1]);
106  } else {
107  assert(n1==kInt); // second argument is not float, cast it to float
108  return subst("min($0, $2$1)", args[0], args[1], icast());
109  }
110  } else if (n1==kReal) {
111  assert(n0==kInt); // first not float but second is, cast first to float
112  return subst("min($2$0, $1)", args[0], args[1], icast());
113  } else {
114  assert(n0==kInt); assert(n1==kInt); // both are integers, check for booleans
115  int b0 = types[0]->boolean();
116  int b1 = types[1]->boolean();
117  if (b0==kNum) {
118  if (b1==kNum) {
119  // both are integers, no need to cast
120  return subst("min($0, $1)", args[0], args[1]);
121  } else {
122  assert(b1==kBool); // second is boolean, cast to int
123  return subst("min($0, (int)$1)", args[0], args[1]);
124  }
125  } else if (b1==kNum) {
126  assert(b0==kBool); // first is boolean, cast to int
127  return subst("min((int)$0, $1)", args[0], args[1], icast());
128  } else {
129  assert(b0==kBool); assert(b1==kBool); // both are booleans, no need to cast
130  return subst("min((int)$0, (int)$1)", args[0], args[1]);
131  }
132  }
133  }
134 
135  virtual string generateLateq (Lateq* lateq, const vector<string>& args, const vector<Type>& types)
136  {
137  assert (args.size() == arity());
138  assert (types.size() == arity());
139 
140  Type t = infereSigType(types);
141  return subst("\\min\\left( $0, $1 \\right)", args[0], args[1]);
142  }
143 
144 };
145 
146 
148 
149 
virtual Tree computeSigOutput(const vector< Tree > &args)
Definition: minprim.cpp:36
virtual int infereSigOrder(const vector< int > &args)
Definition: minprim.cpp:29
Definition: sigtype.hh:54
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
Definition: lateq.hh:56
const char * icast()
Definition: floats.cpp:47
Definition: sigtype.hh:55
double max(double x, double y)
Definition: interval.hh:60
virtual void sigVisit(Tree sig, sigvisitor *visitor)
Definition: minprim.cpp:27
xtended * gMinPrim
Definition: minprim.cpp:147
string subst(const string &model, const vector< string > &args)
Text substitution.
Definition: Text.cpp:47
Definition: sigtype.hh:55
Definition: klass.hh:55
virtual string generateCode(Klass *klass, const vector< string > &args, const vector< Type > &types)
Definition: minprim.cpp:94
bool isDouble(const Node &n)
Definition: node.hh:143
Definition: sigtype.hh:54
virtual bool needCache()
Definition: minprim.cpp:17
Sym symbol()
Definition: xtended.hh:24
virtual unsigned int arity()
Definition: minprim.cpp:15
Tree tree(const Node &n)
Definition: tree.hh:186
virtual string generateLateq(Lateq *lateq, const vector< string > &args, const vector< Type > &types)
Definition: minprim.cpp:135
Type castInterval(Type t, const interval &i)
Definition: sigtype.hh:278
API to the typing system of signals.
bool isInt(const Node &n)
Definition: node.hh:126
virtual Type infereSigType(const vector< Type > &types)
Definition: minprim.cpp:19
double min(double x, double y)
Definition: interval.hh:59
MinPrim()
Definition: minprim.cpp:13