source: src/ControlStruct/TranslateEnumRange.cpp @ 9739c56f

Last change on this file since 9739c56f was 9739c56f, checked in by Andrew Beach <ajbeach@…>, 3 weeks ago

Clean-up in TranslateEnumRange?.

  • Property mode set to 100644
File size: 2.1 KB
Line 
1#include "TranslateEnumRange.hpp"
2
3#include "AST/Pass.hpp"
4#include "AST/TranslationUnit.hpp"
5
6namespace ControlStruct {
7
8namespace {
9
10struct TranslateEnumRangeCore {
11        const ast::Stmt * postvisit( const ast::ForStmt * stmt );
12};
13
14const ast::Stmt * TranslateEnumRangeCore::postvisit( const ast::ForStmt * stmt ) {
15        if ( !stmt->range_over ) return stmt;
16        auto mutStmt = ast::mutate( stmt );
17        auto & location = mutStmt->location;
18
19        if ( auto declStmt = mutStmt->inits.front().as<ast::DeclStmt>() ) {
20                if ( auto objDecl = declStmt->decl.as<ast::ObjectDecl>() ) {
21                        if ( !objDecl->init ) {
22                                ast::SingleInit * newInit = new ast::SingleInit( location,
23                                        ast::UntypedExpr::createCall( location,
24                                                mutStmt->is_inc ? "lowerBound" : "upperBound", {} ),
25                                        ast::ConstructFlag::MaybeConstruct
26                                );
27                                auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
28                                auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
29                                mutStmt->inits[0] = declWithInit;
30                        }
31                }
32        }
33
34        auto declStmt = mutStmt->inits.front().strict_as<ast::DeclStmt>();
35        auto initDecl = declStmt->decl.strict_as<ast::ObjectDecl>();
36        auto indexName = initDecl->name;
37
38        // Both inc and dec check if the current posn less than the number of enumerator
39        // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow,
40        // it wraps around and become unsigned max
41        ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
42                mutStmt->is_inc ? "?<=?" : "?>=?",
43                {
44                        new ast::NameExpr( location, indexName ),
45                        ast::UntypedExpr::createCall( location,
46                                mutStmt->is_inc ? "upperBound" : "lowerBound", {} )
47                } );
48        auto increment = ast::UntypedExpr::createCall( location,
49                mutStmt->is_inc ? "succ_unsafe" : "pred_unsafe",
50                { new ast::NameExpr( location, indexName ) } );
51        auto assig = ast::UntypedExpr::createAssign( location,
52                new ast::NameExpr( location, indexName ), increment );
53        mutStmt->cond = condition;
54        mutStmt->inc = assig;
55        return mutStmt;
56}
57
58} // namespace
59
60void translateEnumRange( ast::TranslationUnit & translationUnit ) {
61        ast::Pass<TranslateEnumRangeCore>::run( translationUnit );
62}
63
64} // namespace ControlStruct
Note: See TracBrowser for help on using the repository browser.