source: src/ControlStruct/TranslateEnumRange.cpp @ df56e25

Last change on this file since df56e25 was fca78f1, checked in by Andrew Beach <ajbeach@…>, 4 months ago

Added ForeachStmt? (felt better than ForEachStmt?). This new node is a bit optimistic in that currently it is covering a very narrow case, but with improvements to it and RangeExpr?, it could handle many more kind of loops.

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