perl 5.003_01: pod/perlxstut.pod
[p5sagit/p5-mst-13.2.git] / perly.y
diff --git a/perly.y b/perly.y
index 907df3e..57c9630 100644 (file)
--- a/perly.y
+++ b/perly.y
@@ -36,6 +36,7 @@ dep()
 %token <ival> '{' ')'
 
 %token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
+%token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
 %token <pval> LABEL
 %token <ival> FORMAT SUB ANONSUB PACKAGE USE
 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
@@ -44,17 +45,17 @@ dep()
 %token <ival> RELOP EQOP MULOP ADDOP
 %token <ival> DOLSHARP DO LOCAL HASHBRACK NOAMP
 
-%type <ival> prog decl format remember startsub
+%type <ival> prog decl format remember startsub '&'
 %type <opval> block lineseq line loop cond nexpr else argexpr
 %type <opval> expr term scalar ary hsh arylen star amper sideff
 %type <opval> listexpr listexprcom indirob
-%type <opval> texpr listop method
+%type <opval> texpr listop method proto
 %type <pval> label
 %type <opval> cont
 
 %left <ival> OROP
 %left ANDOP
-%left NOTOP
+%right NOTOP
 %nonassoc <ival> LSTOP
 %left ','
 %right <ival> ASSIGNOP
@@ -147,7 +148,8 @@ else        :       /* NULL */
        |       ELSIF '(' expr ')' block else
                        { copline = $1;
                            $$ = newSTATEOP(0, 0,
-                               newCONDOP(0, $3, scope($5), $6)); }
+                               newCONDOP(0, $3, scope($5), $6));
+                           hints |= HINT_BLOCK_SCOPE; }
        ;
 
 cond   :       IF '(' expr ')' block else
@@ -244,12 +246,17 @@ format    :       FORMAT startsub WORD block
                        { newFORM($2, Nullop, $3); }
        ;
 
-subrout        :       SUB startsub WORD block
-                       { newSUB($2, $3, $4); }
-       |       SUB startsub WORD ';'
-                       { newSUB($2, $3, Nullop); expect = XSTATE; }
+subrout        :       SUB startsub WORD proto block
+                       { newSUB($2, $3, $4, $5); }
+       |       SUB startsub WORD proto ';'
+                       { newSUB($2, $3, $4, Nullop); expect = XSTATE; }
        ;
 
+proto  :       /* NULL */
+                       { $$ = Nullop; }
+       |       THING
+       ;
+               
 startsub:      /* NULL */      /* start a subroutine scope */
                        { $$ = start_subparse(); }
        ;
@@ -260,16 +267,14 @@ package : PACKAGE WORD ';'
                        { package(Nullop); }
        ;
 
-use    :       USE WORD listexpr ';'
-                       { utilize($1, $2, $3); }
+use    :       USE startsub WORD WORD listexpr ';'
+                       { utilize($1, $2, $3, $4, $5); }
        ;
 
 expr   :       expr ANDOP expr
                        { $$ = newLOGOP(OP_AND, 0, $1, $3); }
        |       expr OROP expr
                        { $$ = newLOGOP($2, 0, $1, $3); }
-       |       NOTOP expr
-                       { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
        |       argexpr
        ;
 
@@ -287,24 +292,29 @@ listop    :       LSTOP indirob argexpr
                        { $$ = convert($1, OPf_STACKED,
                                prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); }
        |       term ARROW method '(' listexprcom ')'
-                       { $$ = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL,
+                       { $$ = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
-                                   prepend_elem(OP_LIST, $1, list($5)),
+                                   prepend_elem(OP_LIST, $1, $5),
                                    newUNOP(OP_METHOD, 0, $3))); }
        |       METHOD indirob listexpr
-                       { $$ = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL,
+                       { $$ = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
-                                   prepend_elem(OP_LIST, $2, list($3)),
+                                   prepend_elem(OP_LIST, $2, $3),
                                    newUNOP(OP_METHOD, 0, $1))); }
        |       FUNCMETH indirob '(' listexprcom ')'
-                       { $$ = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL,
+                       { $$ = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
-                                   prepend_elem(OP_LIST, $2, list($4)),
+                                   prepend_elem(OP_LIST, $2, $4),
                                    newUNOP(OP_METHOD, 0, $1))); }
        |       LSTOP listexpr
                        { $$ = convert($1, 0, $2); }
        |       FUNC '(' listexprcom ')'
                        { $$ = convert($1, 0, $3); }
+       |       LSTOPSUB startsub block listexpr        %prec LSTOP
+                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
+                           append_elem(OP_LIST,
+                             prepend_elem(OP_LIST, newANONSUB($2, 0, $3), $4),
+                             $1)); }
        ;
 
 method :       METHOD
@@ -378,10 +388,12 @@ term      :       term ASSIGNOP term
                        { $$ = newANONHASH($2); }
        |       HASHBRACK ';' '}'                               %prec '('
                        { $$ = newANONHASH(Nullop); }
-       |       ANONSUB startsub block                          %prec '('
-                       { $$ = newANONSUB($2, $3); }
+       |       ANONSUB startsub proto block                    %prec '('
+                       { $$ = newANONSUB($2, $3, $4); }
        |       scalar  %prec '('
                        { $$ = $1; }
+       |       star '{' expr ';' '}'
+                       { $$ = newBINOP(OP_GELEM, 0, newGVREF(0,$1), $3); }
        |       star    %prec '('
                        { $$ = $1; }
        |       scalar '[' expr ']'     %prec '('
@@ -433,54 +445,68 @@ term      :       term ASSIGNOP term
        |       THING   %prec '('
                        { $$ = $1; }
        |       amper
-                       { $$ = newUNOP(OP_ENTERSUB, 0,
-                               scalar($1)); }
+                       { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
        |       amper '(' ')'
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
        |       amper '(' expr ')'
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                           list(append_elem(OP_LIST, $3, scalar($1)))); }
+                           append_elem(OP_LIST, $3, scalar($1))); }
        |       NOAMP WORD listexpr
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                           list(append_elem(OP_LIST,
-                               $3, newCVREF(scalar($2))))); }
+                           append_elem(OP_LIST, $3, scalar($2))); }
        |       DO term %prec UNIOP
                        { $$ = newUNOP(OP_DOFILE, 0, scalar($2)); }
        |       DO block        %prec '('
                        { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
        |       DO WORD '(' ')'
-                       { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
-                           list(prepend_elem(OP_LIST,
-                               scalar(newCVREF(scalar($2))), Nullop))); dep();}
+                       { $$ = newUNOP(OP_ENTERSUB,
+                           OPf_SPECIAL|OPf_STACKED,
+                           prepend_elem(OP_LIST,
+                               scalar(newCVREF(
+                                   (OPpENTERSUB_AMPER<<8),
+                                   scalar($2)
+                               )),Nullop)); dep();}
        |       DO WORD '(' expr ')'
-                       { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
-                           list(append_elem(OP_LIST,
+                       { $$ = newUNOP(OP_ENTERSUB,
+                           OPf_SPECIAL|OPf_STACKED,
+                           append_elem(OP_LIST,
                                $4,
-                               scalar(newCVREF(scalar($2)))))); dep();}
+                               scalar(newCVREF(
+                                   (OPpENTERSUB_AMPER<<8),
+                                   scalar($2)
+                               )))); dep();}
        |       DO scalar '(' ')'
                        { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
-                           list(prepend_elem(OP_LIST,
-                               scalar(newCVREF(scalar($2))), Nullop))); dep();}
+                           prepend_elem(OP_LIST,
+                               scalar(newCVREF(0,scalar($2))), Nullop)); dep();}
        |       DO scalar '(' expr ')'
                        { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
-                           list(prepend_elem(OP_LIST,
+                           prepend_elem(OP_LIST,
                                $4,
-                               scalar(newCVREF(scalar($2)))))); dep();}
+                               scalar(newCVREF(0,scalar($2))))); dep();}
        |       LOOPEX
                        { $$ = newOP($1, OPf_SPECIAL);
                            hints |= HINT_BLOCK_SCOPE; }
        |       LOOPEX term
                        { $$ = newLOOPEX($1,$2); }
+       |       NOTOP argexpr
+                       { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
        |       UNIOP
                        { $$ = newOP($1, 0); }
        |       UNIOP block
                        { $$ = newUNOP($1, 0, $2); }
        |       UNIOP term
                        { $$ = newUNOP($1, 0, $2); }
+       |       UNIOPSUB term
+                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
+                           append_elem(OP_LIST, $2, scalar($1))); }
        |       FUNC0
                        { $$ = newOP($1, 0); }
        |       FUNC0 '(' ')'
                        { $$ = newOP($1, 0); }
+       |       FUNC0SUB
+                       { $$ = newUNOP(OP_ENTERSUB, 0,
+                               scalar($1)); }
        |       FUNC1 '(' ')'
                        { $$ = newOP($1, OPf_SPECIAL); }
        |       FUNC1 '(' expr ')'
@@ -508,7 +534,7 @@ listexprcom:        /* NULL */
        ;
 
 amper  :       '&' indirob
-                       { $$ = newCVREF($2); }
+                       { $$ = newCVREF($1,$2); }
        ;
 
 scalar :       '$' indirob