164
// ----------------------------------------
165
// support for "labels as values" extension
166
// ----------------------------------------
168
// extended goto syntax
169
advice within (derived (syntax ())) &&
170
execution ("% ...::jump_stmt()") : around () {
171
JoinPoint::That *syntax = tjp->that ();
172
if (labels_as_values &&
173
syntax->look_ahead (Puma::TOK_GOTO) &&
174
syntax->look_ahead (Puma::TOK_MUL, 2)) {
175
syntax->consume (); // skip the 'goto' keyword
176
Puma::CTree *&result = *(Puma::CTree**)tjp->result ();
177
result = (syntax->parse (&JoinPoint::That::expr) &&
178
syntax->parse (Puma::TOK_SEMI_COLON)) ?
179
syntax->builder().jump_stmt () : 0;
185
// the address of a label
186
advice within (derived (syntax ())) &&
187
execution ("% ...::unary_expr()") : around () {
188
JoinPoint::That *syntax = tjp->that ();
189
if (labels_as_values &&
190
syntax->look_ahead (Puma::TOK_AND_AND)) {
191
syntax->consume (); // consume the '&&' token, already checked
192
Puma::CTree *&result = *(Puma::CTree**)tjp->result ();
193
result = syntax->identifier () ? syntax->builder().unary_expr () : 0;
199
// extended semantic analysis
200
advice within ("Puma::%CSemVisitor") &&
201
execution ("% ...::check_goto_label(...)") &&
202
args (tree) : around (Puma::CTree *tree) {
203
if (tree->NodeName () == Puma::CT_SimpleName::NodeId ())
205
else if (tree->NodeName () == Puma::CT_DerefExpr::NodeId ())
206
tjp->that ()->resolveExpr (((Puma::CT_DerefExpr*)tree)->Expr (), tree);
209
// label address has type void*
210
advice within ("Puma::%CSemExpr") &&
211
execution ("% ...::resolve(Puma::CT_UnaryExpr *, Puma::CTree *)") : around () {
212
int oper = (*tjp->arg<0>())->token ()->type ();
213
if (oper == Puma::TOK_AND_AND) {
214
// TODO: It would be better to whether the label really exists, but
215
// at the moment I don't see a way how to do that.
216
// (In the gcc extension the label can be defined anywhere in
217
// the translation unit!)
218
// It is also not possible to use the error handling macros here.
219
Puma::CTypeInfo *t = new Puma::CTypePointer (&Puma::CTYPE_VOID);
220
(*tjp->arg<0>())->setType (t);
163
227
// ----------------------
164
228
// TYPEOF keyword support
165
229
// ----------------------