00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <lestes/common.hh>
00035 #include <lestes/lang/cplus/lex/condition_stack.hh>
00036 #include <lestes/lang/cplus/lex/condition_stack.m.hh>
00037 #include <lestes/lang/cplus/lex/condition.hh>
00038 #include <lestes/std/source_location.hh>
00039
00040 package(lestes);
00041 package(lang);
00042 package(cplus);
00043 package(lex);
00044
00045
00046
00047
00048
00049 condition_stack::condition_stack(void):
00050 active(true),
00051 cstack(cstack_type::create())
00052 {
00053 cstack->push_back(condition::create_empty());
00054 }
00055
00056
00057
00058
00059
00060 bool condition_stack::active_get(void) const
00061 {
00062 return active;
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 bool condition_stack::process(directive_type a_dir, bool value, const ptr<source_location> &a_location)
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
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
00142 switch (a_dir) {
00143 case DIR_ELSE:
00144 case DIR_ELIF:
00145 {
00146
00147 cstack->pop_back();
00148 bool curr_active = curr->active_get();
00149
00150
00151
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
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
00166 active = curr->active_get();
00167
00168 cstack->pop_back();
00169 break;
00170 case DIR_EOF:
00171
00172 break;
00173 default:
00174 lassert2(false,"You should never get here");
00175 break;
00176 }
00177
00178 return true;
00179 }
00180
00181
00182
00183
00184
00185 ulint condition_stack::depth(void) const
00186 {
00187
00188 return cstack->size() - 1;
00189 }
00190
00191
00192
00193
00194 void condition_stack::gc_mark(void)
00195 {
00196 cstack.gc_mark();
00197 ::lestes::std::object::gc_mark();
00198 }
00199
00200
00201
00202
00203
00204 ptr<condition_stack> condition_stack::create(void)
00205 {
00206 return new condition_stack();
00207 }
00208
00209 end_package(lex);
00210 end_package(cplus);
00211 end_package(lang);
00212 end_package(lestes);
00213
00214