Changeset c75b30a for src/Validate/ReplacePseudoFunc.cpp
- Timestamp:
- Jan 31, 2024, 6:25:02 PM (4 months ago)
- Branches:
- master
- Children:
- 32490deb
- Parents:
- 16afb2a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/ReplacePseudoFunc.cpp
r16afb2a rc75b30a 17 17 std::set<std::string> queryValues; 18 18 19 struct WrapEnumValueExpr final : public ast::WithShortCircuiting, 20 public ast::WithSymbolTable, 21 public ast::WithConstTranslationUnit { 22 void previsit(const ast::DeclStmt* expr); 23 void previsit(const ast::ApplicationExpr* expr); 24 void previsit(const ast::CastExpr* expr); 25 26 ast::Expr const* postvisit(const ast::VariableExpr* expr); 27 }; 28 19 29 struct FindGenEnumArray final : public ast::WithShortCircuiting { 20 30 void previsit(const ast::ApplicationExpr* enumDecl); 21 31 }; 32 33 struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>, 34 public ast::WithSymbolTable, 35 public ast::WithShortCircuiting { 36 void previsit(const ast::EnumDecl* enumDecl); 37 }; 38 39 struct ReplacePseudoFuncCore : public ast::WithShortCircuiting, 40 public ast::WithSymbolTable, 41 public ast::WithConstTranslationUnit { 42 ast::Expr const* postvisit(ast::ApplicationExpr const* decl); 43 }; 44 45 void WrapEnumValueExpr::previsit(const ast::ApplicationExpr* expr) { 46 47 auto varExpr = expr->func.as<ast::VariableExpr>(); 48 auto fname = ast::getFunctionName(expr); 49 if ( !varExpr || varExpr->var->linkage == ast::Linkage::Intrinsic ) { 50 if ( fname == "?{}" || fname == "?=?" ) 51 visit_children = false; 52 } 53 54 if (fname == "labelE" || fname == "valueE" || fname == "posE") 55 visit_children = false; 56 } 57 58 void WrapEnumValueExpr::previsit(const ast::DeclStmt*) { 59 visit_children = false; 60 } 61 62 void WrapEnumValueExpr::previsit(const ast::CastExpr* expr) { 63 if (expr->result && expr->result.as<ast::ReferenceType>()) { 64 visit_children = false; 65 } 66 } 67 68 ast::Expr const* WrapEnumValueExpr::postvisit(const ast::VariableExpr* expr) { 69 visit_children = false; 70 if (!expr->result) { 71 return expr; 72 } 73 if (auto enumInst = expr->result.as<ast::EnumInstType>()) { 74 if (enumInst->base && enumInst->base->base) { 75 auto untyped = new ast::UntypedExpr( 76 expr->location, new ast::NameExpr(expr->location, "valueE"), 77 {new ast::VariableExpr(*expr)}); 78 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 79 auto result = ResolvExpr::findVoidExpression(untyped, context); 80 if (result.get()) { 81 ast::ptr<ast::ApplicationExpr> ret = 82 result.strict_as<ast::ApplicationExpr>(); 83 return new ast::ApplicationExpr(*ret); 84 } 85 } 86 } 87 return expr; 88 } 22 89 23 90 void FindGenEnumArray::previsit(const ast::ApplicationExpr* expr) { … … 48 115 } 49 116 50 struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>,51 public ast::WithSymbolTable,52 public ast::WithShortCircuiting {53 void previsit(const ast::EnumDecl* enumDecl);54 };55 56 117 void PseudoFuncGenerateRoutine::previsit(const ast::EnumDecl* enumDecl) { 57 118 visit_children = false; … … 67 128 location, ast::ConstantExpr::from_string(location, mem->name))); 68 129 } 130 // Values only 69 131 if (queryValues.count(enumDecl->name)) { 70 132 auto init = new ast::ListInit(location, std::move(inits)); 71 auto values = new ast::ObjectDecl(72 location, "values_" + enumDecl->name,73 new ast::ArrayType(74 enumDecl->base,75 ast::ConstantExpr::from_int(location, enumDecl->members.size()),76 ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim),77 init,ast::Storage::Static, ast::Linkage::AutoGen);133 const ast::ArrayType* arrT = new ast::ArrayType( 134 enumDecl->base, 135 ast::ConstantExpr::from_int(location, enumDecl->members.size()), 136 ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim); 137 ast::ObjectDecl* values = new ast::ObjectDecl( 138 location, "values_" + enumDecl->name, arrT, init, 139 ast::Storage::Static, ast::Linkage::AutoGen); 78 140 symtab.addId(values); 79 141 values->mangleName = Mangle::mangle(values); … … 82 144 if (queryLabels.count(enumDecl->name)) { 83 145 auto label_strings = new ast::ListInit(location, std::move(labels)); 84 auto label _arr= new ast::ObjectDecl(146 auto labels = new ast::ObjectDecl( 85 147 location, "labels_" + enumDecl->name, 86 148 new ast::ArrayType( … … 89 151 ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim), 90 152 label_strings, ast::Storage::Static, ast::Linkage::AutoGen); 91 symtab.addId(label_arr); 92 label_arr->mangleName = Mangle::mangle(label_arr); 93 declsToAddAfter.push_back(label_arr); 94 } 95 } 96 97 struct ReplacePseudoFuncCore : public ast::WithShortCircuiting, 98 public ast::WithSymbolTable, 99 public ast::WithConstTranslationUnit { 100 ast::Expr const* postvisit(ast::ApplicationExpr const* decl); 101 }; 153 symtab.addId(labels); 154 labels->mangleName = Mangle::mangle(labels); 155 declsToAddAfter.push_back(labels); 156 } 157 } 158 159 ast::ApplicationExpr const* getPseudoFuncApplication( 160 const CodeLocation location, ResolvExpr::ResolveContext context, 161 const ast::VariableExpr* arg, const ast::EnumDecl* base, const std::string & name) { 162 ast::Expr* toResolve = new ast::NameExpr(location, name + base->name); 163 auto result = ResolvExpr::findVoidExpression(toResolve, context); 164 assert(result.get()); 165 auto arrAsVar = result.strict_as<ast::VariableExpr>(); 166 auto untyped = new ast::UntypedExpr( 167 location, new ast::NameExpr(location, "?[?]"), 168 {new ast::VariableExpr(*arrAsVar), new ast::VariableExpr(*arg)}); 169 auto typedResult = ResolvExpr::findVoidExpression(untyped, context); 170 171 ast::ptr<ast::ApplicationExpr> ret = 172 typedResult.strict_as<ast::ApplicationExpr>(); 173 return ast::deepCopy(ret); 174 } 102 175 103 176 ast::Expr const* ReplacePseudoFuncCore::postvisit( … … 125 198 } 126 199 const ast::EnumDecl* base = argType->base; 200 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 201 // If resolvable as constant 127 202 for (size_t i = 0; i < base->members.size(); i++) { 128 203 if (base->members[i]->name == referredName) { … … 133 208 referredName); 134 209 else 135 return new ast::TypeExpr(expr->location, argType); 136 } 137 } 138 139 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 210 return getPseudoFuncApplication(location, context, arg.get(), 211 base, "values_"); 212 } 213 } 140 214 141 215 if (fname == "labelE") { 142 ast::Expr* toResolve = 143 new ast::NameExpr(expr->location, "labels_" + base->name); 144 auto result = ResolvExpr::findVoidExpression(toResolve, context); 145 if (result.get()) { 146 auto arrAsVar = result.strict_as<ast::VariableExpr>(); 147 auto untyped = new ast::UntypedExpr( 148 location, new ast::NameExpr(location, "?[?]"), 149 {new ast::VariableExpr(*arrAsVar), 150 ast::ConstantExpr::from_int( 151 location, 152 0)}); /// TODO: dummy value. 153 /// To make it works need to change the unifier 154 155 auto typedResult = 156 ResolvExpr::findVoidExpression(untyped, context); 157 if (result.get()) { 158 ast::ptr<ast::ApplicationExpr> ret = 159 typedResult.strict_as<ast::ApplicationExpr>(); 160 return new ast::ApplicationExpr(*ret); 161 } 162 } 163 } 164 165 if (fname == "valueE") { 166 ast::Expr* toResolve = 167 new ast::NameExpr(expr->location, "values_" + base->name); 168 auto result = ResolvExpr::findVoidExpression(toResolve, context); 169 if (result.get()) { 170 auto arrAsVar = result.strict_as<ast::VariableExpr>(); 171 auto untyped = new ast::UntypedExpr( 172 location, new ast::NameExpr(location, "?[?]"), 173 {new ast::VariableExpr(*arrAsVar), 174 ast::ConstantExpr::from_int( 175 location, 176 0)}); /// TODO: dummy value. 177 /// To make it works need to change the unifier 178 179 auto typedResult = 180 ResolvExpr::findVoidExpression(untyped, context); 181 if (result.get()) { 182 ast::ptr<ast::ApplicationExpr> ret = 183 typedResult.strict_as<ast::ApplicationExpr>(); 184 return new ast::ApplicationExpr(*ret); 185 } 186 } 216 if (auto labelExpr = 217 getPseudoFuncApplication(location, context, arg.get(), base, "labels_")) { 218 return labelExpr; 219 } 220 } else if (fname == "valueE") { 221 if (auto valueExpr = 222 getPseudoFuncApplication(location, context, arg.get(), base, "values_")) { 223 return valueExpr; 224 } 225 } else { // it is position; replace itself 226 return std::move( arg.get() ); 187 227 } 188 228 } … … 193 233 194 234 void replacePseudoFunc(ast::TranslationUnit& translationUnit) { 235 ast::Pass<WrapEnumValueExpr>::run(translationUnit); 195 236 ast::Pass<FindGenEnumArray>::run(translationUnit); 196 237 ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
Note: See TracChangeset
for help on using the changeset viewer.