Changeset 0522ebe for src/Validate
- Timestamp:
- Feb 26, 2024, 3:49:23 AM (3 months ago)
- Branches:
- master
- Children:
- a4da45e
- Parents:
- c17dc80
- Location:
- src/Validate
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/Autogen.cpp
rc17dc80 r0522ebe 206 206 ast::FunctionDecl * genLabelProto() const; 207 207 ast::FunctionDecl * genValueProto() const; 208 // ast::FunctionDecl * genValueProto2() const; 208 209 }; 209 210 … … 790 791 } 791 792 793 // ast::FunctionDecl * EnumFuncGenerator::genValueProto2() const { 794 // return genProto( "valueE", 795 // { new ast::ObjectDecl( getLocation(), "_i", new ast::EnumPosType( new ast::EnumInstType( decl ) ) )}, 796 // { new ast::ObjectDecl( getLocation(), "_ret", ast::deepCopy( decl->base ) ) } ); 797 // } 798 792 799 void EnumFuncGenerator::genAttrFuncForward() { 793 800 if ( decl->base ) { 794 801 ast::FunctionDecl *(EnumFuncGenerator::*attrProtos[3])() const = { 795 802 &EnumFuncGenerator::genPosProto, &EnumFuncGenerator::genLabelProto, 796 &EnumFuncGenerator::genValueProto }; 803 &EnumFuncGenerator::genValueProto 804 // , &EnumFuncGenerator::genValueProto2 805 }; 797 806 for ( auto & generator : attrProtos ) { 798 807 produceForwardDecl( (this->*generator)() ); -
src/Validate/ReplacePseudoFunc.cpp
rc17dc80 r0522ebe 6 6 #include "AST/Inspect.hpp" 7 7 #include "AST/Pass.hpp" 8 #include "AST/Print.hpp" 8 9 #include "AST/Stmt.hpp" 9 10 #include "Common/utility.h" 11 #include "ResolvExpr/CandidateFinder.hpp" 10 12 #include "ResolvExpr/Resolver.h" 11 13 #include "SymTab/Mangler.h" 12 14 13 #include "AST/Print.hpp"14 15 #include "ResolvExpr/CandidateFinder.hpp"16 17 15 namespace Validate { 18 16 … … 21 19 std::set<std::string> queryLabels; 22 20 std::set<std::string> queryValues; 21 22 struct ReplaceEnumInstWithPos final : public ast::WithShortCircuiting { 23 void previsit(const ast::ObjectDecl*) { visit_children = false; } 24 const ast::ObjectDecl* postvisit(const ast::ObjectDecl* decl) { 25 auto enumInst = decl->type.strict_as<ast::EnumInstType>(); 26 auto enumPos = new ast::EnumPosType(enumInst); 27 auto ret = ast::mutate_field(decl, &ast::ObjectDecl::type, enumPos); 28 ret = ast::mutate_field(ret, &ast::ObjectDecl::mangleName, 29 Mangle::mangle(ret)); 30 return ret; 31 } 32 }; 33 34 const inline std::string getValueArrayName(std::string enumName) { 35 return "values_" + enumName; 36 } 23 37 24 38 // struct AutoInit { … … 32 46 void previsit(const ast::ApplicationExpr* expr); 33 47 void previsit(const ast::CastExpr* expr); 34 void previsit(const ast::VariableExpr* 48 void previsit(const ast::VariableExpr*) { visit_children = false; } 35 49 36 50 ast::Expr const* postvisit(const ast::VariableExpr* expr); … … 66 80 auto varExpr = expr->func.as<ast::VariableExpr>(); 67 81 auto fname = ast::getFunctionName(expr); 68 if ( !varExpr || varExpr->var->linkage == ast::Linkage::Intrinsic ) { 69 if ( fname == "?{}" || fname == "?=?" ) 70 visit_children = false; 71 } 82 if (!varExpr || varExpr->var->linkage == ast::Linkage::Intrinsic) { 83 if (fname == "?{}" || fname == "?=?") visit_children = false; 84 } 72 85 73 86 if (fname == "labelE" || fname == "valueE" || fname == "posE") { … … 94 107 auto untyped = new ast::UntypedExpr( 95 108 expr->location, new ast::NameExpr(expr->location, "valueE"), 96 { std::move( expr )});109 {std::move(expr)}); 97 110 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 98 111 auto result = ResolvExpr::findVoidExpression(untyped, context); 99 112 ast::ptr<ast::ApplicationExpr> ret = 100 101 return ast::deepCopy( ret);113 result.strict_as<ast::ApplicationExpr>(); 114 return ast::deepCopy(ret); 102 115 } 103 116 } … … 132 145 } 133 146 134 const ast::Init * getAutoInit( const CodeLocation & location, 135 const ast::Type * type, ResolvExpr::ResolveContext context, const ast::Init * prev ) { 136 if ( auto prevInit = dynamic_cast< const ast::SingleInit * >( prev ) ) { 147 const ast::Init* getAutoInit(const CodeLocation& location, 148 const ast::Type* type, 149 ResolvExpr::ResolveContext context, 150 const ast::Init* prev) { 151 if (auto prevInit = dynamic_cast<const ast::SingleInit*>(prev)) { 137 152 auto prevInitExpr = prevInit->value; 138 if ( auto constInit = prevInitExpr.as< ast::ConstantExpr >()) {153 if (auto constInit = prevInitExpr.as<ast::ConstantExpr>()) { 139 154 // Assume no string literal for now 140 155 return new ast::SingleInit( 141 location, 142 ast::ConstantExpr::from_int( 143 location, constInit->intValue() + 1 ) 144 ); 156 location, ast::ConstantExpr::from_int( 157 location, constInit->intValue() + 1)); 145 158 } else { 146 159 auto untypedThisInit = new ast::UntypedExpr( 147 location, 148 new ast::NameExpr( location, "?++" ), 149 { prevInitExpr } 150 ); 151 auto typedInit = ResolvExpr::findSingleExpression(untypedThisInit, type, 152 context ); 153 return new ast::SingleInit( location, typedInit ); 154 } 155 } 156 SemanticError( prev, "Auto Init a List is not implemented" ); 160 location, new ast::NameExpr(location, "?++"), {prevInitExpr}); 161 auto typedInit = ResolvExpr::findSingleExpression(untypedThisInit, 162 type, context); 163 return new ast::SingleInit(location, typedInit); 164 } 165 } 166 SemanticError(prev, "Auto Init a List is not implemented"); 157 167 return prev; 158 168 } … … 167 177 auto type = enumDecl->base; 168 178 169 for ( size_t i = 0; i < enumDecl->members.size(); i++) {170 ast::ptr<ast::Decl> mem = enumDecl->members.at( i);171 auto memAsObjectDecl = mem.as< ast::ObjectDecl>();172 assert( memAsObjectDecl);173 if ( memAsObjectDecl->init) {174 inits.emplace_back( memAsObjectDecl->init);179 for (size_t i = 0; i < enumDecl->members.size(); i++) { 180 ast::ptr<ast::Decl> mem = enumDecl->members.at(i); 181 auto memAsObjectDecl = mem.as<ast::ObjectDecl>(); 182 assert(memAsObjectDecl); 183 if (memAsObjectDecl->init) { 184 inits.emplace_back(memAsObjectDecl->init); 175 185 } else { 176 const CodeLocation & location = mem->location; 177 if ( i == 0 ) { 178 inits.emplace_back( new ast::SingleInit( 179 location, 180 ast::ConstantExpr::from_int( mem->location, 0 ) 181 ) ); 186 const CodeLocation& location = mem->location; 187 if (i == 0) { 188 inits.emplace_back(new ast::SingleInit( 189 location, ast::ConstantExpr::from_int(mem->location, 0))); 182 190 } else { 183 inits.emplace_back( getAutoInit( location, enumDecl->base, 184 ResolvExpr::ResolveContext{symtab, transUnit().global}, 185 inits.at( i - 1 ).as<ast::SingleInit>()) ); 191 inits.emplace_back(getAutoInit( 192 location, enumDecl->base, 193 ResolvExpr::ResolveContext{symtab, transUnit().global}, 194 inits.at(i - 1).as<ast::SingleInit>())); 186 195 } 187 196 } 188 197 labels.emplace_back(new ast::SingleInit( 189 location, ast::ConstantExpr::from_string(location, mem->name)));190 } 198 location, ast::ConstantExpr::from_string(location, mem->name))); 199 } 191 200 if (queryValues.count(enumDecl->name)) { 192 201 auto init = new ast::ListInit(location, std::move(inits)); … … 219 228 ast::ApplicationExpr const* getPseudoFuncApplication( 220 229 const CodeLocation location, ResolvExpr::ResolveContext context, 221 const ast::VariableExpr* arg, const ast::EnumDecl* base, const std::string & name) { 230 const ast::VariableExpr* arg, const ast::EnumDecl* base, 231 const std::string& name) { 222 232 ast::Expr* toResolve = new ast::NameExpr(location, name + base->name); 223 auto result = ResolvExpr::findVoidExpression(toResolve, context); 224 assert(result.get()); 225 auto arrAsVar = result.strict_as<ast::VariableExpr>(); 226 auto untyped = new ast::UntypedExpr( 227 location, new ast::NameExpr(location, "?[?]"), 228 { std::move(arrAsVar), std::move(arg) }); 229 auto typedResult = ResolvExpr::findVoidExpression(untyped, context); 230 231 ast::ptr<ast::ApplicationExpr> ret = 232 typedResult.strict_as<ast::ApplicationExpr>(); 233 return ast::deepCopy(ret); 233 // Find the request arrary 234 auto arr = ResolvExpr::findVoidExpression(toResolve, context); 235 assert(arr.get()); 236 auto arrAsVar = arr.strict_as<ast::VariableExpr>(); 237 // change EnumInstType to EnumPosType to avoid recursive resolution 238 auto argAsDecl = arg->var.as<ast::ObjectDecl>(); 239 if (argAsDecl->type.as<ast::EnumInstType>()) { 240 ast::Pass<ReplaceEnumInstWithPos> replacer; 241 auto rep = argAsDecl->accept(replacer); 242 auto mutatedArg = ast::mutate_field(arg, &ast::VariableExpr::var, rep); 243 auto untyped = 244 new ast::UntypedExpr(location, new ast::NameExpr(location, "?[?]"), 245 {std::move(arrAsVar), mutatedArg}); 246 auto typedResult = ResolvExpr::findVoidExpression(untyped, context); 247 ast::ptr<ast::ApplicationExpr> ret = 248 typedResult.strict_as<ast::ApplicationExpr>(); 249 return ast::deepCopy(ret); 250 } else { 251 auto untyped = 252 new ast::UntypedExpr(location, new ast::NameExpr(location, "?[?]"), 253 {std::move(arrAsVar), arg}); 254 auto typedResult = ResolvExpr::findVoidExpression(untyped, context); 255 256 ast::ptr<ast::ApplicationExpr> ret = 257 typedResult.strict_as<ast::ApplicationExpr>(); 258 return ast::deepCopy(ret); 259 } 234 260 } 235 261 … … 250 276 const ast::ObjectDecl* argAsVar = arg->var.as<const ast::ObjectDecl>(); 251 277 const std::string referredName = argAsVar->name; 252 const ast::EnumInstType* argType = 253 argAsVar->type.as<const ast::EnumInstType>(); 254 if (!argType) { 278 279 if (const ast::EnumInstType* argTypeAsEnumInst = 280 argAsVar->type.as<const ast::EnumInstType>()) { 281 const ast::EnumDecl* base = argTypeAsEnumInst->base; 282 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 283 // If resolvable as constant 284 for (size_t i = 0; i < base->members.size(); i++) { 285 if (base->members[i]->name == referredName) { 286 if (fname == "posE") 287 return ast::ConstantExpr::from_int(expr->location, i); 288 else if (fname == "labelE") 289 return ast::ConstantExpr::from_string(expr->location, 290 referredName); 291 else { 292 return getPseudoFuncApplication( 293 location, context, arg.get(), base, "values_"); 294 } 295 } 296 } 297 298 if (fname == "labelE") { 299 if (auto labelExpr = getPseudoFuncApplication( 300 location, context, arg.get(), base, "labels_")) { 301 return labelExpr; 302 } 303 } else if (fname == "valueE") { 304 if (auto valueExpr = getPseudoFuncApplication( 305 location, context, arg.get(), base, "values_")) { 306 return valueExpr; 307 } 308 } else { // it is position; replace itself 309 return std::move(arg.get()); 310 } 311 } else if (const ast::EnumPosType* argTypeAsPos = 312 argAsVar->type.as<const ast::EnumPosType>()) { 313 const ast::EnumDecl* base = argTypeAsPos->instance->base; 314 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 315 if (fname == "labelE") { 316 if (auto labelExpr = getPseudoFuncApplication( 317 location, context, arg.get(), base, "labels_")) { 318 return labelExpr; 319 } 320 } else if (fname == "valueE") { 321 if (auto valueExpr = getPseudoFuncApplication( 322 location, context, arg.get(), base, "values_")) { 323 return valueExpr; 324 } 325 } else { // it is position; replace itself 326 return std::move(arg.get()); 327 } 328 } else { 255 329 SemanticError(argAsVar, 256 330 "Pseudo Enum Expression can only be used on an " 257 331 "enumeration instance"); 258 332 } 259 const ast::EnumDecl* base = argType->base;260 ResolvExpr::ResolveContext context{symtab, transUnit().global};261 // If resolvable as constant262 for (size_t i = 0; i < base->members.size(); i++) {263 if (base->members[i]->name == referredName) {264 if (fname == "posE")265 return ast::ConstantExpr::from_int(expr->location, i);266 else if (fname == "labelE")267 return ast::ConstantExpr::from_string(expr->location,268 referredName);269 else {270 return getPseudoFuncApplication(location, context, arg.get(),271 base, "values_");272 }273 274 }275 }276 277 if (fname == "labelE") {278 if (auto labelExpr =279 getPseudoFuncApplication(location, context, arg.get(), base, "labels_")) {280 return labelExpr;281 }282 } else if (fname == "valueE") {283 if (auto valueExpr =284 getPseudoFuncApplication(location, context, arg.get(), base, "values_")) {285 return valueExpr;286 }287 } else { // it is position; replace itself288 return std::move( arg.get() );289 }290 333 } 291 334 return expr; 292 335 } 336 337 ast::ptr<ast::Expr> reduceCastExpr(ast::ptr<ast::Expr> expr) { 338 if (auto castExpr = expr.as<ast::CastExpr>()) { 339 return reduceCastExpr(castExpr->arg); 340 } 341 return expr; 342 } 343 344 struct ReplaceEnumInst final { 345 const ast::Expr* postvisit(const ast::ApplicationExpr* expr) { 346 auto fname = ast::getFunctionName(expr); 347 if (fname != "?[?]") return expr; 348 if (expr->args.size() != 2) return expr; 349 350 auto arg1AsVar = 351 reduceCastExpr(expr->args.front()).as<ast::VariableExpr>(); 352 auto arg2AsVar = 353 reduceCastExpr(expr->args.back()).as<ast::VariableExpr>(); 354 355 if (!arg1AsVar || !arg2AsVar) return expr; 356 357 auto arg1Asecl = arg1AsVar->var.as<ast::ObjectDecl>(); 358 auto arg2Asecl = arg2AsVar->var.as<ast::ObjectDecl>(); 359 360 if (!arg1Asecl || !arg2Asecl) return expr; 361 auto arrInst = arg1Asecl->type.as<ast::ArrayType>(); 362 auto pointerInst = arg1Asecl->type.as<ast::PointerType>(); 363 if (!arrInst && !pointerInst) { 364 return expr; 365 } 366 auto enumInst = arg2Asecl->type.as<ast::EnumInstType>(); 367 if (!enumInst) return expr; 368 369 const std::string arrName = arg1Asecl->name; 370 if (arrName != getValueArrayName(enumInst->base->name)) return expr; 371 ast::Pass<ReplaceEnumInstWithPos> replacer; 372 auto rep = arg2Asecl->accept(replacer); 373 if (!rep) return expr; 374 auto mutObj = 375 ast::mutate_field(arg2AsVar, &ast::VariableExpr::var, rep); 376 auto mut = ast::mutate_field_index(expr, &ast::ApplicationExpr::args, 1, 377 mutObj); 378 return mut; 379 } 380 }; 293 381 294 382 } // namespace … … 299 387 ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit); 300 388 ast::Pass<ReplacePseudoFuncCore>::run(translationUnit); 389 ast::Pass<ReplaceEnumInst>::run(translationUnit); 301 390 } 302 391 } // namespace Validate
Note: See TracChangeset
for help on using the changeset viewer.