source: src/ControlStruct/TranslateEnumRange.cpp@ 0dffe91

Last change on this file since 0dffe91 was fca78f1, checked in by Andrew Beach <ajbeach@…>, 12 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
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::ForeachStmt * stmt );
12};
13
14const ast::Stmt * TranslateEnumRangeCore::postvisit( const ast::ForeachStmt * stmt ) {
15 auto & location = stmt->location;
16
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 );
29 }
30
31 auto indexName = objDecl->name;
32
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,
37 stmt->isIncreasing ? "?<=?" : "?>=?",
38 {
39 new ast::NameExpr( location, indexName ),
40 ast::UntypedExpr::createCall( location,
41 stmt->isIncreasing ? "upperBound" : "lowerBound", {} )
42 } );
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 );
58}
59
60} // namespace
61
62void translateEnumRange( ast::TranslationUnit & translationUnit ) {
63 ast::Pass<TranslateEnumRangeCore>::run( translationUnit );
64}
65
66} // namespace ControlStruct
Note: See TracBrowser for help on using the repository browser.