lestes::lang::cplus::lex::condition_stack Class Reference

Conditional directive stack. More...

#include <condition_stack.hh>

Inheritance diagram for lestes::lang::cplus::lex::condition_stack:

lestes::std::object lestes::std::mem::keystone List of all members.

Public Types

enum  directive_type {
  DIR_IF = 1, DIR_IFDEF = 2, DIR_IFNDEF = 3, DIR_ELIF = 4,
  DIR_ELSE = 5, DIR_ENDIF = 6, DIR_EOF = 7
}
 Types of directives. More...

Public Member Functions

bool active_get (void) const
 Tests if the output is active.
bool process (directive_type a_dir, bool value, const ptr< source_location > &a_location)
 Processes a directive.
ulint depth (void) const
 Returns depth of the stack.

Static Public Member Functions

static ptr< condition_stackcreate (void)
 Returns new object.

Protected Member Functions

 condition_stack (void)
 Creates new object.
virtual void gc_mark (void)
 Marks the object.

Private Types

typedef ::lestes::std::vector<
srp< condition > > 
cstack_type
 Conditions stack type.

Private Attributes

bool active
 Output activity flag.
srp< cstack_typecstack
 Conditions stack.

Detailed Description

Conditional directive stack.

Represents stack of conditional directives. Holds information in stack of unfinished directives.

Definition at line 60 of file condition_stack.hh.


Member Typedef Documentation

typedef ::lestes::std::vector< srp<condition> > lestes::lang::cplus::lex::condition_stack::cstack_type [private]

Conditions stack type.

Definition at line 94 of file condition_stack.hh.


Member Enumeration Documentation

enum lestes::lang::cplus::lex::condition_stack::directive_type

Types of directives.

Enumerator:
DIR_IF  Directive if.
DIR_IFDEF  Directive ifdef.
DIR_IFNDEF  Directive ifndef.
DIR_ELIF  Directive elif.
DIR_ELSE  Directive else.
DIR_ENDIF  Directive endif.
DIR_EOF  End of file.

Definition at line 63 of file condition_stack.hh.

00063                      {
00064                 //! Directive #if.
00065                 DIR_IF = 1,
00066                 //! Directive #ifdef.
00067                 DIR_IFDEF = 2,
00068                 //! Directive #ifndef.
00069                 DIR_IFNDEF = 3,
00070                 //! Directive #elif.
00071                 DIR_ELIF = 4,
00072                 //! Directive #else.
00073                 DIR_ELSE = 5,
00074                 //! Directive #endif.
00075                 DIR_ENDIF = 6,
00076                 //! End of file.
00077                 DIR_EOF = 7
00078         } directive_type;


Constructor & Destructor Documentation

lestes::lang::cplus::lex::condition_stack::condition_stack ( void   )  [protected]

Creates new object.

Creates empty condition stack.

Postcondition:
active == true

Definition at line 49 of file condition_stack.cc.

References lestes::lang::cplus::lex::condition::create_empty(), and cstack.

Referenced by create().

00049                                     :
00050         active(true),
00051         cstack(cstack_type::create())
00052 {
00053         cstack->push_back(condition::create_empty());
00054 }
        


Member Function Documentation

bool lestes::lang::cplus::lex::condition_stack::active_get ( void   )  const

Tests if the output is active.

Tests if the output is active.

Returns:
true If tokens shall be output for the current condition.

Definition at line 60 of file condition_stack.cc.

References active.

00061 {
00062         return active;
00063 }

bool lestes::lang::cplus::lex::condition_stack::process ( directive_type  a_dir,
bool  value,
const ptr< source_location > &  a_location 
)

Processes a directive.

Processes conditional directive, issues any error messages.

Precondition:
a_location != NULL
Parameters:
a_dir The directive to process
value The value of the condition for if-like directives.
a_location The location of the directive.
Returns:
true If the directive is correct in the current context.

Definition at line 73 of file condition_stack.cc.

References active, lestes::lang::cplus::lex::condition::COND_ELIF, lestes::lang::cplus::lex::condition::COND_ELSE, lestes::lang::cplus::lex::condition::COND_EMPTY, lestes::lang::cplus::lex::condition::COND_IF, lestes::lang::cplus::lex::condition::COND_IFDEF, lestes::lang::cplus::lex::condition::COND_IFNDEF, lestes::lang::cplus::lex::conditional_starts_here, lestes::lang::cplus::lex::condition::create(), cstack, DIR_ELIF, DIR_ELSE, DIR_ENDIF, DIR_EOF, DIR_IF, DIR_IFDEF, DIR_IFNDEF, lestes::lang::cplus::lex::elif_after_else, lestes::lang::cplus::lex::elif_without_if, lestes::lang::cplus::lex::else_after_else, lestes::lang::cplus::lex::else_without_if, lestes::lang::cplus::lex::endif_without_if, lassert, lassert2, lestes::report, and lestes::lang::cplus::lex::unterminated_conditional.

00074 {
00075         lassert(a_location);
00076 
00077         condition::type_type cond = condition::COND_EMPTY;
00078         ptr<condition> curr = cstack->back();
00079         condition::type_type curr_type = curr->type_get();
00080         bool curr_waiting = true;
00081         
00082         switch (a_dir) {
00083                 case DIR_IFNDEF:
00084                         cond = condition::COND_IFNDEF;
00085                         break;
00086                 case DIR_IF:
00087                         cond = condition::COND_IF;
00088                         break;
00089                 case DIR_IFDEF:
00090                         cond = condition::COND_IFDEF;
00091                         break;
00092                 case DIR_ELIF:
00093                         switch (curr_type) {
00094                                 case condition::COND_EMPTY:
00095                                         report << elif_without_if << a_location;
00096                                         return false;
00097                                 case condition::COND_ELSE:
00098                                         report << elif_after_else << a_location;
00099                                         report << conditional_starts_here << curr->location_get();
00100                                         return false;
00101                                 default:
00102                                         break;
00103                         }
00104                         curr_waiting = curr->waiting_get();
00105                         cond = condition::COND_ELIF;
00106                         break;
00107                 case DIR_ELSE:
00108                         switch (curr_type) {
00109                                 case condition::COND_EMPTY:
00110                                         report << else_without_if << a_location;
00111                                         return false;
00112                                 case condition::COND_ELSE:
00113                                         report << else_after_else << a_location;
00114                                         report << conditional_starts_here << curr->location_get();
00115                                         return false;
00116                                 default:
00117                                         break;
00118                         }
00119                         // implicitly fulfilled condition
00120                         value = true;
00121                         curr_waiting = curr->waiting_get();
00122                         cond = condition::COND_ELSE;
00123                         break;
00124                 case DIR_ENDIF:
00125                         if (curr_type == condition::COND_EMPTY) {
00126                                 report << endif_without_if << a_location;
00127                                 return false;
00128                         }
00129                         break;
00130                 case DIR_EOF:
00131                         if (curr_type != condition::COND_EMPTY) {
00132                                 report << unterminated_conditional << curr->name_get() << curr->location_get();
00133                                 return false;
00134                         }
00135                         break;
00136                 default:
00137                         lassert2(false,"You should never get here");
00138                         break;
00139         }
00140         
00141         // active = curr_active && value
00142         switch (a_dir) {
00143                 case DIR_ELSE:
00144                 case DIR_ELIF:
00145                         {
00146                                 // remove old condition on the same level
00147                                 cstack->pop_back();
00148                                 bool curr_active = curr->active_get();
00149 
00150                                 // new waiting = curr_active && curr_waiting && !value
00151                                 // keep the original location
00152                                 cstack->push_back(
00153                                                 condition::create(cond,curr_active && curr_waiting && !value,curr_active,curr->location_get()));
00154                                 active = curr_active && curr_waiting && value;
00155                         }
00156                         break;
00157                 case DIR_IFNDEF:
00158                 case DIR_IF:
00159                 case DIR_IFDEF:
00160                         // new waiting = active && curr_waiting && !value
00161                         cstack->push_back(condition::create(cond,active && curr_waiting && !value,active,a_location));
00162                         active = active && curr_waiting && value;
00163                         break;
00164                 case DIR_ENDIF:
00165                         // restore active value
00166                         active = curr->active_get();
00167                         // remove the old condition
00168                         cstack->pop_back();
00169                         break;
00170                 case DIR_EOF:
00171                         // do nothing
00172                         break;
00173                 default:
00174                         lassert2(false,"You should never get here");
00175                         break;
00176         }
00177 
00178         return true;
00179 }

ulint lestes::lang::cplus::lex::condition_stack::depth ( void   )  const

Returns depth of the stack.

Returns depth of the condition stack.

Returns:
The number of nested conditions.

Definition at line 185 of file condition_stack.cc.

References cstack.

00186 {
00187         // subtract the padding
00188         return cstack->size() - 1;
00189 }

ptr< condition_stack > lestes::lang::cplus::lex::condition_stack::create ( void   )  [static]

Returns new object.

Returns empty condition stack.

Returns:
An empty condition stack.

Definition at line 204 of file condition_stack.cc.

References condition_stack().

00205 {
00206         return new condition_stack();
00207 }

void lestes::lang::cplus::lex::condition_stack::gc_mark ( void   )  [protected, virtual]

Marks the object.

Marks the object.

Reimplemented from lestes::std::mem::keystone.

Definition at line 194 of file condition_stack.cc.

References cstack, and lestes::std::mem::keystone::gc_mark().

00195 {
00196         cstack.gc_mark();
00197 	::lestes::std::object::gc_mark();
00198 }


Member Data Documentation

bool lestes::lang::cplus::lex::condition_stack::active [private]

Output activity flag.

Definition at line 96 of file condition_stack.hh.

Referenced by active_get(), and process().

srp<cstack_type> lestes::lang::cplus::lex::condition_stack::cstack [private]

Conditions stack.

Definition at line 98 of file condition_stack.hh.

Referenced by condition_stack(), depth(), gc_mark(), and process().


The documentation for this class was generated from the following files:
Generated on Mon Feb 12 18:24:16 2007 for lestes by doxygen 1.5.1-20070107