Dear all,
are there any plans to make non-local exits out of a method legal? This works in CodeWarrior Pascal and looks somehow better than a goto. The following program illustrates the issue: I could not find a way to make a non-local exit out of q using the exit statement.
program exittest;
{ compile with gp --nonlocal-exit exittest.pas }
type o = object procedure p; end;
procedure o.p;
procedure q; begin exit(p); { error: invalid argument `p' to `Exit' } exit(o.p); { error: syntax error before `.' } end;
begin { o.p } end;
begin { exittest } end.
Best regards, Peter
Peter Schorn wrote:
are there any plans to make non-local exits out of a method legal? This works in CodeWarrior Pascal and looks somehow better than a goto. The following program illustrates the issue: I could not find a way to make a non-local exit out of q using the exit statement.
program exittest;
{ compile with gp --nonlocal-exit exittest.pas }
type o = object procedure p; end;
procedure o.p;
procedure q; begin exit(p); { error: invalid argument `p' to `Exit' } exit(o.p); { error: syntax error before `.' } end; begin { o.p } end;
begin { exittest } end.
Should be easy. Does CodeWarrior support both forms?
Waldek Hebisch wrote:
Peter Schorn wrote:
are there any plans to make non-local exits out of a method legal? This works in CodeWarrior Pascal and looks somehow better than a goto. The following program illustrates the issue: I could not find a way to make a non-local exit out of q using the exit statement.
program exittest;
{ compile with gp --nonlocal-exit exittest.pas }
type o = object procedure p; end;
procedure o.p;
procedure q; begin exit(p); { error: invalid argument `p' to `Exit' } exit(o.p); { error: syntax error before `.' } end; begin { o.p } end;
begin { exittest } end.
Should be easy. Does CodeWarrior support both forms?
CodeWarrior only supports the first form (exit(p)).
In message 440F3381.1050908@acm.org, Peter Schorn peter.schorn@acm.org writes
Waldek Hebisch wrote:
Should be easy. Does CodeWarrior support both forms?
CodeWarrior only supports the first form (exit(p)).
UCSD also supported exit(p).
Martin Liddle wrote:
In message 440F3381.1050908@acm.org, Peter Schorn writes
Waldek Hebisch wrote:
Should be easy. Does CodeWarrior support both forms?
CodeWarrior only supports the first form (exit(p)).
UCSD also supported exit(p).
I do not think that UCSD supports methods (objects). For ordinary procedures GPC already supports exit(p)
Peter Schorn wrote:
Waldek Hebisch wrote:
Peter Schorn wrote:
are there any plans to make non-local exits out of a method legal? This works in CodeWarrior Pascal and looks somehow better than a goto. The following program illustrates the issue: I could not find a way to make a non-local exit out of q using the exit statement.
<snip>
Should be easy. Does CodeWarrior support both forms?
CodeWarrior only supports the first form (exit(p)).
OK. The following patch (to may current version, but should work with gpc-20060215) should do this:
Index: parse.y =================================================================== RCS file: /mn/a8/cvsroot/gpc/p/parse.y,v retrieving revision 1.13 diff -u -p -r1.13 parse.y --- parse.y 7 Mar 2006 16:56:39 -0000 1.13 +++ parse.y 9 Mar 2006 00:38:30 -0000 @@ -1515,6 +1515,8 @@ unlabelled_statement: { build_predef_call (p_Exit, build_tree_list (NULL_TREE, void_type_node)); } | p_Exit '(' id ')' { build_predef_call (p_Exit, build_tree_list (NULL_TREE, $3)); } + | p_Exit '(' id '.' id ')' + { build_predef_call (p_Exit, build_tree_list ($3, $5)); } | builtin_procedure_statement | p_with with_list p_do pushlevel optional_statement poplevel { restore_identifiers ($2); } Index: predef.c =================================================================== RCS file: /mn/a8/cvsroot/gpc/p/predef.c,v retrieving revision 1.12 diff -u -p -r1.12 predef.c --- predef.c 6 Mar 2006 12:18:41 -0000 1.12 +++ predef.c 9 Mar 2006 01:14:13 -0000 @@ -1216,18 +1216,44 @@ build_predef_call (int r_num, tree apar) if (r_num == p_Exit && apar) { tree id = TREE_VALUE (apar); + tree obn = TREE_PURPOSE (apar); apar = NULL_TREE; - chk_dialect ("`Exit' with an argument is", U_M_PASCAL); + if (obn) + chk_dialect ("`Exit' with a qualified indentifier as an argument is", + GNU_PASCAL); + else + chk_dialect ("`Exit' with an argument is", U_M_PASCAL); if (id == void_type_node || (current_module->main_program && id == current_module->name)) r_num = p_Halt; - else if (!(current_function_decl && id == DECL_NAME (current_function_decl))) + else if (!(current_function_decl && !obn + && id == DECL_NAME (current_function_decl))) { - struct function *p; + struct function *p = outer_function_chain; + while (p) + { + if (!obn && DECL_NAME (p->decl) == id) + break; + if (PASCAL_METHOD (p->decl)) + { + tree ot = DECL_CONTEXT (p->decl); + tree on, mn; + gcc_assert (ot && PASCAL_TYPE_OBJECT (ot)); + if (TYPE_POINTER_TO (ot) && + PASCAL_TYPE_CLASS (TYPE_POINTER_TO (ot))) + ot = TYPE_POINTER_TO (ot); + on = DECL_NAME (TYPE_NAME (TYPE_MAIN_VARIANT (ot))); + if (obn && on != obn) + continue; + mn = get_method_name (on, id); + if (mn == DECL_NAME (p->decl)) + break; + } #ifdef EGCS97 - for (p = outer_function_chain; p && DECL_NAME (p->decl) != id; p = p->outer) ; + p = p->outer; #else - for (p = outer_function_chain; p && DECL_NAME (p->decl) != id; p = p->next) ; + p = p->next; #endif + } if (!p) error ("invalid argument `%s' to `Exit'", IDENTIFIER_NAME (id)); else if (DECL_LANG_SPECIFIC (p->decl) && DECL_LANG_NONLOCAL_EXIT_LABEL (p->decl))
Waldek Hebisch wrote:
OK. The following patch (to may current version, but should work with gpc-20060215) should do this:
chk_dialect ("`Exit' with a qualified indentifier as an argument is",
Typo (identifier).
Do we really need qualified identifiers here? (BTW, by QI I normally mean InterfaceName.RoutineName which makes no sense here. I suppose you mean ObjectType.MethodName.) Do other compilers support them? AIUI, Peter Schorn tried them only because GPC didn't support plain method names.
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
OK. The following patch (to may current version, but should work with gpc-20060215) should do this:
chk_dialect ("`Exit' with a qualified indentifier as an argument is",
Typo (identifier).
Yes
Do we really need qualified identifiers here? (BTW, by QI I normally mean InterfaceName.RoutineName which makes no sense here. I suppose you mean ObjectType.MethodName.) Do other compilers support them? AIUI, Peter Schorn tried them only because GPC didn't support plain method names.
I have added them mostly for consistency -- since such names are legal in other contexts forbiding them here would create irregularity. They add a little extra functionlity: if the method name is shadowed qualified name still can reach the method.
Waldek Hebisch wrote:
Do we really need qualified identifiers here? (BTW, by QI I normally mean InterfaceName.RoutineName which makes no sense here. I suppose you mean ObjectType.MethodName.) Do other compilers support them? AIUI, Peter Schorn tried them only because GPC didn't support plain method names.
I have added them mostly for consistency -- since such names are legal in other contexts forbiding them here would create irregularity. They add a little extra functionlity: if the method name is shadowed qualified name still can reach the method.
OTOH, I consider it a deprecated feature as it has all the disadvantages of a nonlocal goto, both WRT implementation and program readability, so I'm not sure we should add functionality except what's required for compatibility. (Without it, it's not really a serious limitation, as one can always rename local subroutines without global effects.)
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Do we really need qualified identifiers here? (BTW, by QI I normally mean InterfaceName.RoutineName which makes no sense here. I suppose you mean ObjectType.MethodName.) Do other compilers support them? AIUI, Peter Schorn tried them only because GPC didn't support plain method names.
I have added them mostly for consistency -- since such names are legal in other contexts forbiding them here would create irregularity. They add a little extra functionlity: if the method name is shadowed qualified name still can reach the method.
OTOH, I consider it a deprecated feature as it has all the disadvantages of a nonlocal goto, both WRT implementation and program readability, so I'm not sure we should add functionality except what's required for compatibility. (Without it, it's not really a serious limitation, as one can always rename local subroutines without global effects.)
I have pretty strong opinion that consistency is important. However I do not think this feature is worth long disscusion: it is just a little piece of syntatic sugar which is rarely needed. I prefer to do it "right" (if at all). OTOH if you insist the we should not add qualified (dotted) names here I will remove this part.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Do we really need qualified identifiers here? (BTW, by QI I normally mean InterfaceName.RoutineName which makes no sense here. I suppose you mean ObjectType.MethodName.) Do other compilers support them? AIUI, Peter Schorn tried them only because GPC didn't support plain method names.
I have added them mostly for consistency -- since such names are legal in other contexts forbiding them here would create irregularity. They add a little extra functionlity: if the method name is shadowed qualified name still can reach the method.
OTOH, I consider it a deprecated feature as it has all the disadvantages of a nonlocal goto, both WRT implementation and program readability, so I'm not sure we should add functionality except what's required for compatibility. (Without it, it's not really a serious limitation, as one can always rename local subroutines without global effects.)
I have pretty strong opinion that consistency is important.
I also prefer consistency. But I do not see it so much applicable here, as this "function" is syntactically special, anyway. In particular, the change adds another rule in the parser -- if it could reuse an existing rule for un-/qualified identifiers, and thus require the same number of rules, or even fewer rules than without it, I'd rather see the consistency. Same for the internal passing to build_predef_call -- you had to use the TREE_PURPOSE slot which is otherwise used only for field width specifications, i.e. it's handled quite differently from other uses of qualified or object.method identifiers.
OTOH, my concern is that we have too many unimportant features to keep and support later (as we know, removing a feature is always very hard).
However I do not think this feature is worth long disscusion: it is just a little piece of syntatic sugar which is rarely needed. I prefer to do it "right" (if at all). OTOH if you insist the we should not add qualified (dotted) names here I will remove this part.
I do not insist. Just stated my reasoning above. What do those who actually use non-local Exit think? Would `Exit (object.method)' be seen as a possibly useful extension, or wouldn't you use it anyway?
Frank