Ignore:
Timestamp:
Jan 24, 2024, 6:05:16 AM (5 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
71b5aad5
Parents:
367725d
Message:

Update ReplacePseudoFunc?, mostly the runtime lookup for attribute pseudo-function. It is imcomplete and returning dummy value

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/ReplacePseudoFunc.cpp

    r367725d r544deb9  
     1#include "ReplacePseudoFunc.hpp"
     2
     3#include <set>
     4
    15#include "AST/Decl.hpp"
     6#include "AST/Inspect.hpp"
    27#include "AST/Pass.hpp"
    38#include "AST/Stmt.hpp"
    4 #include "AST/Inspect.hpp"
    59#include "Common/utility.h"
    6 #include "ReplacePseudoFunc.hpp"
    7 
     10#include "ResolvExpr/Resolver.h"
     11#include "SymTab/Mangler.h"  // for Mangler
    812namespace Validate {
    913
    1014namespace {
    1115
    12 struct ReplacePseudoFuncCore {
    13     ast::Expr const * postvisit( ast::ApplicationExpr const * decl );
     16std::set<std::string> queryLabels;
     17std::set<std::string> queryValues;
     18
     19struct FindGenEnumArray final : public ast::WithShortCircuiting {
     20    void previsit(const ast::ApplicationExpr* enumDecl);
    1421};
     22
     23void FindGenEnumArray::previsit(const ast::ApplicationExpr* expr) {
     24    auto fname = ast::getFunctionName(expr);
     25    if (fname == "labelE" || fname == "valueE") {
     26        if (expr->args.size() != 1) {
     27            SemanticError(expr, "Position Expression only take one parameter");
     28        }
     29        const ast::VariableExpr* arg =
     30            expr->args.front().as<const ast::VariableExpr>();
     31        if (!arg) {
     32            SemanticError(expr, "Unimplement Pseudo Function Cases");
     33        }
     34        const ast::ObjectDecl* argAsVar = arg->var.as<const ast::ObjectDecl>();
     35        const std::string referredName = argAsVar->name;
     36        const ast::EnumInstType* argType =
     37            argAsVar->type.as<const ast::EnumInstType>();
     38        if (!argType) {
     39            SemanticError(
     40                argAsVar,
     41                "Position can only be used on an enumeration instance");
     42        }
     43        ast::ptr<ast::EnumDecl> base = argType->base;
     44        assert(base);
     45        if (fname == "labelE") queryLabels.insert(base->name);
     46        if (fname == "valueE") queryValues.insert(base->name);
     47    }
    1548}
    1649
    17 ast::Expr const * ReplacePseudoFuncCore::postvisit( ast::ApplicationExpr const * expr) {
    18     auto fname = ast::getFunctionName( expr );
    19     if ( fname == "posE" || fname == "valueE" || fname == "labelE" ) {
    20         // std::cerr << "Found App in ReplacePseudoFunc" << std::endl;
    21         if ( expr->args.size() != 1 ) {
    22             SemanticError( expr, "Position Expression only take one parameter" );
     50struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>,
     51                                         public ast::WithSymbolTable,
     52                                         public ast::WithShortCircuiting {
     53    void previsit(const ast::EnumDecl* enumDecl);
     54};
     55
     56void PseudoFuncGenerateRoutine::previsit(const ast::EnumDecl* enumDecl) {
     57    visit_children = false;
     58    const CodeLocation& location = enumDecl->location;
     59    if (enumDecl->members.size() == 0 || !enumDecl->base) return;
     60
     61    std::vector<ast::ptr<ast::Init>> inits;
     62    std::vector<ast::ptr<ast::Init>> labels;
     63    for (const ast::Decl* mem : enumDecl->members) {
     64        auto memAsObjectDecl = dynamic_cast<const ast::ObjectDecl*>(mem);
     65        inits.emplace_back(memAsObjectDecl->init);
     66        labels.emplace_back(new ast::SingleInit(
     67            location, ast::ConstantExpr::from_string(location, mem->name)));
     68    }
     69    if (queryValues.count(enumDecl->name)) {
     70        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);
     78        symtab.addId(values);
     79        values->mangleName = Mangle::mangle(values);
     80        declsToAddAfter.push_back(values);
     81    }
     82    if (queryLabels.count(enumDecl->name)) {
     83        auto label_strings = new ast::ListInit(location, std::move(labels));
     84        auto label_arr = new ast::ObjectDecl(
     85            location, "labels_" + enumDecl->name,
     86            new ast::ArrayType(
     87                new ast::PointerType(new ast::BasicType{ast::BasicType::Char}),
     88                ast::ConstantExpr::from_int(location, enumDecl->members.size()),
     89                ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim),
     90            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
     97struct ReplacePseudoFuncCore : public ast::WithShortCircuiting,
     98                               public ast::WithSymbolTable,
     99                               public ast::WithConstTranslationUnit {
     100    ast::Expr const* postvisit(ast::ApplicationExpr const* decl);
     101};
     102
     103ast::Expr const* ReplacePseudoFuncCore::postvisit(
     104    ast::ApplicationExpr const* expr) {
     105    auto fname = ast::getFunctionName(expr);
     106    auto location = expr->location;
     107    if (fname == "posE" || fname == "valueE" || fname == "labelE") {
     108        if (expr->args.size() != 1) {
     109            SemanticError(expr,
     110                          "Pseudo Enum Expression only take one parameter");
    23111        }
    24         const ast::VariableExpr * arg = expr->args.front().as<const ast::VariableExpr>();
    25         if ( !arg ) {
    26             SemanticError( expr, "Unimplement Pseudo Function Cases" );
     112        ast::ptr<ast::VariableExpr> arg =
     113            expr->args.front().as<const ast::VariableExpr>();
     114        if (!arg) {
     115            SemanticError(expr, "Unimplement Pseudo Function Cases");
    27116        }
    28         const ast::ObjectDecl * argAsVar = arg->var.as<const ast::ObjectDecl>();
     117        const ast::ObjectDecl* argAsVar = arg->var.as<const ast::ObjectDecl>();
    29118        const std::string referredName = argAsVar->name;
    30         const ast::EnumInstType * argType = argAsVar->type.as<const ast::EnumInstType>();
    31         if ( !argType ) {
    32             SemanticError( argAsVar, "Position can only be used on an enumeration instance" );
     119        const ast::EnumInstType* argType =
     120            argAsVar->type.as<const ast::EnumInstType>();
     121        if (!argType) {
     122            SemanticError(argAsVar,
     123                          "Pseudo Enum Expression can only be used on an "
     124                          "enumeration instance");
    33125        }
    34         const ast::EnumDecl * base = argType->base;
    35         for ( size_t i = 0; i < base->members.size(); i++ ) {
    36             if ( base->members[i]->name == referredName ) {
    37                 if ( fname == "posE ")
    38                     return ast::ConstantExpr::from_int( expr->location, i );
    39                 else if (fname == "labelE" )
    40                     return ast::ConstantExpr::from_string( expr->location, referredName );
     126        const ast::EnumDecl* base = argType->base;
     127        for (size_t i = 0; i < base->members.size(); i++) {
     128            if (base->members[i]->name == referredName) {
     129                if (fname == "posE")
     130                    return ast::ConstantExpr::from_int(expr->location, i);
     131                else if (fname == "labelE")
     132                    return ast::ConstantExpr::from_string(expr->location,
     133                                                          referredName);
    41134                else
    42                     return new ast::TypeExpr( expr->location, argType );
     135                    return new ast::TypeExpr(expr->location, argType);
     136            }
     137        }
     138
     139        ResolvExpr::ResolveContext context{symtab, transUnit().global};
     140
     141        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                }
    43186            }
    44187        }
     
    47190}
    48191
     192}  // namespace
    49193
    50 
    51 void replacePseudoFunc( ast::TranslationUnit & translationUnit ) {
    52     ast::Pass<ReplacePseudoFuncCore>::run( translationUnit );
     194void replacePseudoFunc(ast::TranslationUnit& translationUnit) {
     195    ast::Pass<FindGenEnumArray>::run(translationUnit);
     196    ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
     197    ast::Pass<ReplacePseudoFuncCore>::run(translationUnit);
    53198}
    54 
    55 }
     199}  // namespace Validate
Note: See TracChangeset for help on using the changeset viewer.