Ignore:
Timestamp:
Jan 31, 2024, 6:25:02 PM (4 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
32490deb
Parents:
16afb2a
Message:

Introduce posE, valueE, labelE pseudo language to the language. Rework the internal representation of enumeration.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/ReplacePseudoFunc.cpp

    r16afb2a rc75b30a  
    1717std::set<std::string> queryValues;
    1818
     19struct 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
    1929struct FindGenEnumArray final : public ast::WithShortCircuiting {
    2030    void previsit(const ast::ApplicationExpr* enumDecl);
    2131};
     32
     33struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>,
     34                                         public ast::WithSymbolTable,
     35                                         public ast::WithShortCircuiting {
     36    void previsit(const ast::EnumDecl* enumDecl);
     37};
     38
     39struct ReplacePseudoFuncCore : public ast::WithShortCircuiting,
     40                               public ast::WithSymbolTable,
     41                               public ast::WithConstTranslationUnit {
     42    ast::Expr const* postvisit(ast::ApplicationExpr const* decl);
     43};
     44
     45void 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
     58void WrapEnumValueExpr::previsit(const ast::DeclStmt*) {
     59    visit_children = false;
     60}
     61
     62void WrapEnumValueExpr::previsit(const ast::CastExpr* expr) {
     63    if (expr->result && expr->result.as<ast::ReferenceType>()) {
     64        visit_children = false;
     65    }
     66}
     67
     68ast::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}
    2289
    2390void FindGenEnumArray::previsit(const ast::ApplicationExpr* expr) {
     
    48115}
    49116
    50 struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>,
    51                                          public ast::WithSymbolTable,
    52                                          public ast::WithShortCircuiting {
    53     void previsit(const ast::EnumDecl* enumDecl);
    54 };
    55 
    56117void PseudoFuncGenerateRoutine::previsit(const ast::EnumDecl* enumDecl) {
    57118    visit_children = false;
     
    67128            location, ast::ConstantExpr::from_string(location, mem->name)));
    68129    }
     130    // Values only
    69131    if (queryValues.count(enumDecl->name)) {
    70132        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);
    78140        symtab.addId(values);
    79141        values->mangleName = Mangle::mangle(values);
     
    82144    if (queryLabels.count(enumDecl->name)) {
    83145        auto label_strings = new ast::ListInit(location, std::move(labels));
    84         auto label_arr = new ast::ObjectDecl(
     146        auto labels = new ast::ObjectDecl(
    85147            location, "labels_" + enumDecl->name,
    86148            new ast::ArrayType(
     
    89151                ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim),
    90152            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
     159ast::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}
    102175
    103176ast::Expr const* ReplacePseudoFuncCore::postvisit(
     
    125198        }
    126199        const ast::EnumDecl* base = argType->base;
     200        ResolvExpr::ResolveContext context{symtab, transUnit().global};
     201        // If resolvable as constant
    127202        for (size_t i = 0; i < base->members.size(); i++) {
    128203            if (base->members[i]->name == referredName) {
     
    133208                                                          referredName);
    134209                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        }
    140214
    141215        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() );
    187227        }
    188228    }
     
    193233
    194234void replacePseudoFunc(ast::TranslationUnit& translationUnit) {
     235    ast::Pass<WrapEnumValueExpr>::run(translationUnit);
    195236    ast::Pass<FindGenEnumArray>::run(translationUnit);
    196237    ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
Note: See TracChangeset for help on using the changeset viewer.