Author: larry
Date: Mon Apr 24 00:59:42 2006
New Revision: 8928

Modified:
   doc/trunk/design/syn/S02.pod

Log:
Rules for parsing and compiling unrecognized identifiers.


Modified: doc/trunk/design/syn/S02.pod
==============================================================================
--- doc/trunk/design/syn/S02.pod        (original)
+++ doc/trunk/design/syn/S02.pod        Mon Apr 24 00:59:42 2006
@@ -12,7 +12,7 @@
 
   Maintainer: Larry Wall <[EMAIL PROTECTED]>
   Date: 10 Aug 2004
-  Last Modified: 23 Apr 2006
+  Last Modified: 24 Apr 2006
   Number: 2
   Version: 30
 
@@ -1531,7 +1531,67 @@
 always be taken to mean a subroutine or method name.  (Class names
 (and other type names) are predeclared, or prefixed with the C<::>
 type sigil when you're declaring a new one.)  A consequence of this
-is that there's no longer any "C<use strict 'subs'>".
+is that there's no longer any "C<use strict 'subs'>".  Since the syntax
+for method calls is distinguished from sub calls, it is only unreconized
+sub calls that must be treated specially.
+
+You still must declare your subroutines, but an unrecognized bare
+identifier is provisionally compiled as a subroutine call on that
+assumption that such a declaration will occur by the end of the current
+compilation unit.  If it is not, the compile fails at C<CHECK> time.
+(You are still free to predeclare subroutines explicitly, of course.)
+The postdeclaration may be in any lexical or package scope that
+could have made the declaration visible to the provisional call had the
+declaration occurred before rather than after than the provisional
+call.  This fixup is done only for provisional calls.  If there
+is I<any> real predeclaration visible, it always takes precedence.
+In case of multiple ambiguous postdeclarations, either they must all
+be multis, or a compile-time error is declared and you must predeclare,
+even if one postdeclaration is obviously "closer".  A single
+C<proto> predeclaration may make all postdeclared C<multi> work fine,
+since that's a run-time dispatch, and all multis are effectively
+visible at the point of the controlling C<proto> declaration.
+
+If the unrecogized subname is followed by C<< postcircumfix:<( )> >>, it is
+compiled as a provisional function call of the parenthesized form.
+If it is not, it is compiled as a provisional function call of
+the list operator form, which may or may not have an argument list.
+When in doubt, the attempt is made to parse an argument list.  As with
+any list operator, an immediate postfix operator means there are no
+arguments, whereas anything following whitespace will be interpreted
+as an argument list if possible.  It is illegal for a provisional
+subroutine call to be followed by a colon postfix, since such a colon
+is allowed only on an indirect object or a method call in dot form.
+(It is also allowed on a label when a statement is expected.)
+So for any undeclared identifier "C<foo>":
+
+    foo.bar            # foo().bar     -- postfix prevents args
+    foo .bar           # foo($_.bar)   -- no postfix starts with whitespace
+    foo. .bar          # foo().bar     -- long dot, so postfix
+    foo++              # foo()++       -- postfix
+    foo 1,2,3          # foo(1,2,3)    -- args always expected after listop
+    foo + 1            # foo(+1)       -- term always expected after listop
+    foo;               # foo();        -- no postfix, but no args either
+    foo:               #   label       -- must be label at statement boundary.
+                                       -- illegal otherwise
+    foo: bar:          #   two labels in a row
+    .foo:              # $_.foo: 1     -- must be "dot" method with : args
+    .foo(1)            # $_.foo(1)     -- must be "dot" method with () args
+    .foo               # $_.foo()      -- must be "dot" method with no args
+    .$foo:             # $_.$foo: 1    -- indirect "dot" method with : args
+    foo bar: 1         # bar.foo(1)    -- bar must be predecl as class or sub
+                                       -- foo method call even if declared sub
+    foo bar 1          # foo(bar(1))   -- both subject to postdeclaration
+                                       -- never taken as indirect object
+    foo $bar: 1                # $bar.foo(1)   -- indirect object even if 
declared sub
+    foo bar():         # bar().foo(1)  -- even if foo declared sub
+    foo bar baz: 1     # foo(bar baz: 1) -- colon controls "bar", not foo.
+    foo (bar baz): 1   # bar(baz()).foo(1) -- colon controls "foo"
+    $foo $bar          # illegal       -- two terms in a row
+    $foo $bar:         # illegal       -- use $bar.$foo for indirection
+    (foo bar) baz: 1   # illegal       -- use $baz.$(foo bar) for indirection
+
+Parens are required around any indirect object that would be ambiguous.
 
 =item *
 

Reply via email to