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 |
|
---|
15 | namespace Validate {
|
---|
16 |
|
---|
17 | namespace {
|
---|
18 |
|
---|
19 | ast::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 |
|
---|
26 | struct 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 |
|
---|
69 | void replacePseudoFunc(ast::TranslationUnit& translationUnit) {
|
---|
70 | ast::Pass<ReplaceSuccAndPred>::run(translationUnit);
|
---|
71 | }
|
---|
72 | } // namespace Validate
|
---|