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 _TYPING_INSTRUCTIONS_H 23 #define _TYPING_INSTRUCTIONS_H 24 25 #include "instructions.hh" 26 27 using namespace std; 28 29 /* 30 Typing visitor: to be used when knowing the exact type of the currenty compiled value is needed. 31 */ 32 33 struct TypingVisitor : public InstVisitor { 34 Typed::VarType fCurType; 35 TypingVisitorTypingVisitor36 TypingVisitor() : fCurType(Typed::kNoType) {} 37 ~TypingVisitorTypingVisitor38 virtual ~TypingVisitor() {} 39 visitTypingVisitor40 virtual void visit(LoadVarInst* inst) 41 { 42 // Stack or struct variables 43 if (gGlobal->hasVarType(inst->getName())) { 44 fCurType = gGlobal->getVarType(inst->getName()); 45 IndexedAddress* indexed = dynamic_cast<IndexedAddress*>(inst->fAddress); 46 if (indexed) { 47 // IndexedAddress is also used for struct type 48 DeclareStructTypeInst* struct_type = isStructType(indexed->getName()); 49 if (struct_type) { 50 Int32NumInst* field_index = static_cast<Int32NumInst*>(indexed->fIndex); 51 fCurType = struct_type->fType->getType(field_index->fNum); 52 } else { 53 fCurType = Typed::getTypeFromPtr(fCurType); 54 } 55 } 56 // Specific cases for FunArgs 57 } else if (startWith(inst->getName(), "count") || startWith(inst->getName(), "sample_rate")) { 58 fCurType = Typed::kInt32; 59 } else { 60 fCurType = Typed::kNoType; 61 throw faustexception("ERROR in TypingVisitor : variable '" + inst->getName() + "' has Typed::kNoType\n"); 62 } 63 } 64 visitTypingVisitor65 virtual void visit(TeeVarInst* inst) 66 { 67 if (gGlobal->hasVarType(inst->getName())) { 68 fCurType = gGlobal->getVarType(inst->getName()); 69 } else { 70 fCurType = Typed::kNoType; 71 } 72 } 73 visitTypingVisitor74 virtual void visit(LoadVarAddressInst* inst) 75 { 76 // Not implemented 77 faustassert(false); 78 } 79 visitTypingVisitor80 virtual void visit(FloatNumInst* inst) { fCurType = Typed::kFloat; } 81 visitTypingVisitor82 virtual void visit(Int32NumInst* inst) { fCurType = Typed::kInt32; } 83 visitTypingVisitor84 virtual void visit(Int64NumInst* inst) { fCurType = Typed::kInt64; } 85 visitTypingVisitor86 virtual void visit(BoolNumInst* inst) { fCurType = Typed::kBool; } 87 visitTypingVisitor88 virtual void visit(DoubleNumInst* inst) { fCurType = Typed::kDouble; } 89 visitTypingVisitor90 virtual void visit(BinopInst* inst) 91 { 92 if (isBoolOpcode(inst->fOpcode)) { 93 fCurType = Typed::kBool; 94 } else { 95 inst->fInst1->accept(this); 96 Typed::VarType type1 = fCurType; 97 if (isRealType(type1)) { 98 fCurType = type1; 99 } else { 100 inst->fInst2->accept(this); 101 Typed::VarType type2 = fCurType; 102 if (isRealType(type2)) { 103 fCurType = type2; 104 } else if (isInt32Type(type1) || isInt32Type(type2)) { 105 fCurType = Typed::kInt32; 106 } else if (isInt64Type(type1) || isInt64Type(type2)) { 107 fCurType = Typed::kInt64; 108 } else if (isBoolType(type1) && isBoolType(type2)) { 109 fCurType = Typed::kInt32; 110 } else { 111 // Should never happen... 112 faustassert(false); 113 } 114 } 115 } 116 } 117 visitTypingVisitor118 virtual void visit(::CastInst* inst) { fCurType = inst->fType->getType(); } 119 visitTypingVisitor120 virtual void visit(BitcastInst* inst) { fCurType = inst->fType->getType(); } 121 visitTypingVisitor122 virtual void visit(Select2Inst* inst) 123 { 124 inst->fThen->accept(this); 125 Typed::VarType type1 = fCurType; 126 if (isRealType(type1)) { 127 fCurType = type1; 128 } else { 129 inst->fElse->accept(this); 130 Typed::VarType type2 = fCurType; 131 if (isRealType(type2)) { 132 fCurType = type2; 133 } else if (isInt32Type(type1) || isInt32Type(type2)) { 134 fCurType = Typed::kInt32; 135 } else if (isInt64Type(type1) || isInt64Type(type2)) { 136 fCurType = Typed::kInt64; 137 } else if (isBoolType(type1) && isBoolType(type2)) { 138 fCurType = Typed::kBool; 139 } else { 140 // Should never happen... 141 faustassert(false); 142 } 143 } 144 } 145 visitTypingVisitor146 virtual void visit(IfInst* inst) 147 { 148 // Type in the one of 'then' or 'else' 149 inst->fThen->accept(this); 150 } 151 visitTypingVisitor152 virtual void visit(FunCallInst* inst) 153 { 154 if (gGlobal->hasVarType(inst->fName)) { 155 fCurType = gGlobal->getVarType(inst->fName); 156 } else { 157 // Should never happen... 158 cerr << "TypingVisitor::visit(FunCallInst* inst) name " << inst->fName << std::endl; 159 faustassert(false); 160 } 161 } 162 }; 163 164 struct BasicTypingCloneVisitor : public BasicCloneVisitor { 165 TypingVisitor fTypingVisitor; 166 BasicTypingCloneVisitorBasicTypingCloneVisitor167 BasicTypingCloneVisitor() {} 168 169 // Memory visitBasicTypingCloneVisitor170 virtual ValueInst* visit(LoadVarInst* inst) 171 { 172 fTypingVisitor.visit(inst); 173 return BasicCloneVisitor::visit(inst); 174 } 175 176 // Numbers visitBasicTypingCloneVisitor177 virtual ValueInst* visit(FloatNumInst* inst) 178 { 179 fTypingVisitor.visit(inst); 180 return BasicCloneVisitor::visit(inst); 181 } visitBasicTypingCloneVisitor182 virtual ValueInst* visit(Int32NumInst* inst) 183 { 184 fTypingVisitor.visit(inst); 185 return BasicCloneVisitor::visit(inst); 186 } visitBasicTypingCloneVisitor187 virtual ValueInst* visit(Int64NumInst* inst) 188 { 189 fTypingVisitor.visit(inst); 190 return BasicCloneVisitor::visit(inst); 191 } visitBasicTypingCloneVisitor192 virtual ValueInst* visit(BoolNumInst* inst) 193 { 194 fTypingVisitor.visit(inst); 195 return BasicCloneVisitor::visit(inst); 196 } visitBasicTypingCloneVisitor197 virtual ValueInst* visit(DoubleNumInst* inst) 198 { 199 fTypingVisitor.visit(inst); 200 return BasicCloneVisitor::visit(inst); 201 } 202 203 // Numerical computation visitBasicTypingCloneVisitor204 virtual ValueInst* visit(BinopInst* inst) 205 { 206 fTypingVisitor.visit(inst); 207 return BasicCloneVisitor::visit(inst); 208 } 209 210 // Cast visitBasicTypingCloneVisitor211 virtual ValueInst* visit(::CastInst* inst) 212 { 213 fTypingVisitor.visit(inst); 214 return BasicCloneVisitor::visit(inst); 215 } visitBasicTypingCloneVisitor216 virtual ValueInst* visit(BitcastInst* inst) 217 { 218 fTypingVisitor.visit(inst); 219 return BasicCloneVisitor::visit(inst); 220 } 221 222 // Function call visitBasicTypingCloneVisitor223 virtual ValueInst* visit(FunCallInst* inst) 224 { 225 fTypingVisitor.visit(inst); 226 return BasicCloneVisitor::visit(inst); 227 } 228 229 // Conditionnal visitBasicTypingCloneVisitor230 virtual ValueInst* visit(Select2Inst* inst) 231 { 232 fTypingVisitor.visit(inst); 233 return BasicCloneVisitor::visit(inst); 234 } visitBasicTypingCloneVisitor235 virtual StatementInst* visit(IfInst* inst) 236 { 237 fTypingVisitor.visit(inst); 238 return BasicCloneVisitor::visit(inst); 239 } 240 }; 241 242 #endif 243