source: src/Validate/ReplacePseudoFunc.cpp

Last change on this file was fb2e916, checked in by JiadaL <j82liang@…>, 2 weeks ago

Fix some warning

  • Property mode set to 100644
File size: 2.7 KB
Line 
1#include "ReplacePseudoFunc.hpp"
2
3#include <set>
4
5#include "AST/Decl.hpp"
6#include "AST/Inspect.hpp"
7#include "AST/Pass.hpp"
8#include "AST/Print.hpp"
9#include "AST/Stmt.hpp"
10#include "Common/utility.h"
11#include "ResolvExpr/CandidateFinder.hpp"
12#include "ResolvExpr/Resolver.h"
13#include "SymTab/Mangler.h"
14
15namespace Validate {
16
17namespace {
18
19ast::ptr<ast::Expr> reduceCastExpr(ast::ptr<ast::Expr> expr) {
20    if (auto castExpr = expr.as<ast::CastExpr>()) {
21        return reduceCastExpr(castExpr->arg);
22    }
23    return expr;
24}
25
26struct ReplaceSuccAndPred final : public ast::WithSymbolTable,
27                                  public ast::WithConstTranslationUnit {
28    const ast::Expr* postvisit(const ast::ApplicationExpr* expr) {
29        auto fname = ast::getFunctionName(expr);
30        if (fname == "succ" || fname == "pred") {
31            const CodeLocation& location = expr->location;
32            if (expr->args.size() != 1) return expr;
33
34            auto param = expr->args.front();
35            if (auto argAsVar = reduceCastExpr(param).as<ast::VariableExpr>()) {
36                if (auto argAsDecl = argAsVar->var.as<ast::ObjectDecl>()) {
37                    if (auto enumInst =
38                            argAsDecl->type.as<ast::EnumInstType>()) {
39                        auto castTo = new ast::EnumAttrType(
40                            enumInst, ast::EnumAttribute::Posn);
41                        auto castExpr =
42                            new ast::CastExpr(param->location, param, castTo);
43
44                        auto untyped = new ast::UntypedExpr(
45                            expr->location,
46                            new ast::NameExpr(location, fname == "succ"
47                                                            ? "_successor_"
48                                                            : "_predessor_"),
49                            {castExpr});
50                        ResolvExpr::ResolveContext context{symtab,
51                                                           transUnit().global};
52                        auto typedResult =
53                            ResolvExpr::findVoidExpression(untyped, context);
54                        ast::ptr<ast::ApplicationExpr> ret =
55                            typedResult.strict_as<ast::ApplicationExpr>();
56                        return ast::deepCopy(ret);
57                    } else if (argAsDecl->type.as<ast::EnumAttrType>()) {
58                        std::cerr << "PseudoFunc: succ/pred should not be applied on EnumAttrType directly" << std::endl;
59                    }
60                }
61            }
62        }
63        return expr;
64    }
65};
66
67}  // namespace
68
69void replacePseudoFunc(ast::TranslationUnit& translationUnit) {
70    ast::Pass<ReplaceSuccAndPred>::run(translationUnit);
71}
72}  // namespace Validate
Note: See TracBrowser for help on using the repository browser.