Author: kjs
Date: Sun Mar 25 07:06:10 2007
New Revision: 17722

Modified:
   trunk/compilers/pirc/src/pirlexer.c
   trunk/compilers/pirc/src/pirlexer.h
   trunk/compilers/pirc/src/pirmain.c
   trunk/compilers/pirc/src/pirparser.c

Log:
compilers/pirc:
* added unary operators
* fixed and completed binary operators
* fixed param flags/get_results instr.pir
* fixed some pod errors/completed docs.

Modified: trunk/compilers/pirc/src/pirlexer.c
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.c (original)
+++ trunk/compilers/pirc/src/pirlexer.c Sun Mar 25 07:06:10 2007
@@ -22,7 +22,7 @@
 #define ERROR_CONTEXT_SIZE  30  /* number of characters being displayed in 
syntax errors */
 
 
-/* 
+/*
 
 =head1 KEYWORDS
 
@@ -38,22 +38,26 @@
 is not null"), so you don't have to look into a section
 that is not of interest. (not implemented right now)
 
- goto  
- if   
- int    
- n_operators    
+ goto
+ if
+ int
+ n_operators
  null
- num   
- pmc  
- string 
+ num
+ pmc
+ string
  unless
- 
- 
+
+
 =head1 DIRECTIVES
 
+The following are PIR directives.
+
+XXX TODO
 
 =head1 FLAGS
 
+The following are flags for subroutines and parameters/arguments.
 
 =cut
 
@@ -131,15 +135,16 @@
     "*",                        /* T_MULTIPLY,              */
     ".",                        /* T_CONCAT,                */
     "..",                       /* T_DOTDOT,                */
+    "!",                        /* T_NOT                    */
     "&",                        /* T_BAND,                  */
     "&&",                       /* T_AND,                   */
     "|",                        /* T_BOR,                   */
     "||",                       /* T_OR,                    */
-    "~",                        /* T_XOR,                   */
-    "~~",                       /* T_HUH,                   */
+    "~",                        /* T_BXOR,                  */
+    "~~",                       /* T_XOR,                   */
     ">>",                       /* T_RSHIFT,                */
     "<<",                       /* T_LSHIFT,                */
-    ">>>",                      /* T_RRSHIFT,               */
+    ">>>",                      /* T_LOG_RSHIFT,            */
     ">",                        /* T_GT,                    */
     "<",                        /* T_LT,                    */
     ">=",                       /* T_GE,                    */
@@ -156,7 +161,7 @@
     "]",                        /* T_RBRACKET               */
     "end of file",              /* T_EOF                    */
     "not found",                /* T_NOT_FOUND              */
-    "PASM PREG",                /* T_PASM_PREG              */             
+    "PASM PREG",                /* T_PASM_PREG              */
     "PASM NREG",                /* T_PASM_NREG              */
     "PASM_IREG",                /* T_PASM_IREG,             */
     "PASM_SREG",                /* T_PASM_SREG,             */
@@ -187,10 +192,12 @@
     "'register'",               /* T_REGISTER,              */
     "/=",                       /* T_DIVIDE_ASSIGN,         */
     "%=",                       /* T_MODULO_ASSIGN,         */
+    "~=",                       /* T_BXOR_ASSIGN,           */
     "&=",                       /* T_BAND_ASSIGN,           */
     "|=",                       /* T_BOR_ASSIGN,            */
-    ">>=",                      /* T_RRSHIFT_ASSIGN,        */
-    ">>>=",                     /* T_RSHIFT_ASSIGN,         */
+    ">>=",                      /* T_RSHIFT_ASSIGN,         */
+    ">>>=",                     /* T_LOG_RSHIFT_ASSIGN,     */
+    "<<=",                      /* T_LSHIFT_ASSIGN,         */
     "heredoc id",               /* T_HEREDOC_ID,            */
     "heredoc string",           /* T_HEREDOC_STRING,        */
     "parrot op",                /* T_PARROT_OP              */
@@ -200,7 +207,7 @@
 
 
 
-/* 
+/*
 
 =head2 file_buffer structure
 
@@ -226,7 +233,7 @@
 
 } file_buffer;
 
-/* 
+/*
 
 =head2 lexer_state structure
 
@@ -247,7 +254,7 @@
 } lexer_state;
 
 
-/* 
+/*
 
 =head1 ACCESSOR FUNCTIONS
 
@@ -273,7 +280,7 @@
     }
 }
 
-/* 
+/*
 
 =item get_current_token()
 
@@ -287,7 +294,7 @@
     return s->token_chars;
 }
 
-/* 
+/*
 
 =item get_current_file()
 
@@ -301,7 +308,7 @@
     return s->curfile->filename;
 }
 
-/* 
+/*
 
 =item get_current_line()
 
@@ -316,7 +323,7 @@
 }
 
 
-/* 
+/*
 
 =item print_error_context()
 
@@ -363,7 +370,7 @@
     *lexer->charptr++ = c;
 }
 
-/* 
+/*
 
 =item read_char()
 
@@ -387,7 +394,7 @@
 
 }
 
-/* 
+/*
 
 =item unread_char()
 
@@ -404,7 +411,7 @@
    --buf->linepos;
 }
 
-/* 
+/*
 
 =item print_buffer()
 
@@ -421,7 +428,7 @@
 }
 
 
-/* 
+/*
 
 =item clear_buffer()
 
@@ -440,7 +447,7 @@
     lexer->charptr = lexer->token_chars;
 }
 
-/* 
+/*
 
 =item clone_string()
 
@@ -461,7 +468,7 @@
     return ptr;
 }
 
-/* 
+/*
 
 =item read_file()
 
@@ -522,7 +529,7 @@
     return filebuff;
 }
 
-/* 
+/*
 
 =item destroy_buffer()
 
@@ -539,7 +546,7 @@
 
 
 
-/* 
+/*
 
 =item do_include_file()
 
@@ -558,7 +565,7 @@
 }
 
 
-/* 
+/*
 
 =item is_op()
 
@@ -578,7 +585,7 @@
 }
 
 
-/* 
+/*
 
 =item is_start_of_line()
 
@@ -597,7 +604,7 @@
 }
 
 
-/* 
+/*
 
 =item check_dictionary()
 
@@ -621,7 +628,7 @@
 }
 
 
-/* 
+/*
 
 =item switch_buffer()
 
@@ -649,7 +656,7 @@
 }
 
 
-/* 
+/*
 
 =item read_digits()
 
@@ -672,7 +679,7 @@
     return count;
 }
 
-/* 
+/*
 
 =item update_line()
 
@@ -690,7 +697,7 @@
 
 }
 
-/* 
+/*
 
 =item read_token()
 
@@ -731,20 +738,20 @@
 
 
         /* skip comments */
-        
+
 /*
- 
+
 =pod
 
 =head2 Comments
 
 Comments start with the pound sign ('#') and continue up to the end of the 
line.
 
-POD comments are not yet supported.   
-  
-=cut  
+POD comments are not yet supported.
+
+=cut
 
-*/        
+*/
         if (c == '#') {
             /* eat comments up to but not including newline */
             do {
@@ -767,17 +774,17 @@
 is indicated explicitly.
 
   PASM-REG        -> PASM-PREG | PASM-SREG | PASM-NREG | PASM-IREG
-                  
+
   PASM-PREG       -> 'P' DIGIT+
-                  
+
   PASM-SREG       -> 'S' DIGIT+
-                  
+
   PASM-NREG       -> 'N' DIGIT+
-                  
+
   PASM-IREG       -> 'I' DIGIT+
-  
+
 =cut
-  
+
 */
         /* now start checking for real tokens */
         switch(c) {
@@ -804,29 +811,29 @@
 =pod
 
   IDENT           -> [a-zA-Z_][a-zA-Z_0-9]*
-                  
+
   LABEL           -> IDENT ':'
-                  
+
   INVOCANT-IDENT  -> IDENT '.'
-                  
+
   PARROT-OP       -> IDENT
-                  
+
   MACRO-IDENT     -> '.' IDENT
-  
-  MACRO-LABEL     -> '$' IDENT ':'                   
-                  
+
+  MACRO-LABEL     -> '$' IDENT ':'
+
   PIR-REGISTER    -> '$' PASM-REG
-                  
+
   HEREDOC-IDENT   -> << STRINGC
-  
+
   STRING-CONSTANT -> ' <characters> ' | " <characters> "
-  
+
   INT-CONSTANT    -> DIGIT+
-  
+
   NUM-CONSTANT    -> DIGIT+ '.' DIGIT*
-  
-  DIGIT           -> [0-9]       
-  
+
+  DIGIT           -> [0-9]
+
 
 =cut
 
@@ -964,7 +971,7 @@
 
 =head2 Special tokens
 
-  ( ) [ ] , ; 
+  ( ) [ ] , ;
 
 =cut
 
@@ -979,7 +986,7 @@
             default:
                 break; /* continue below */
         }
-        
+
 /*
 
 =pod
@@ -990,27 +997,27 @@
 
 =head3 Unary operators
 
-    - 
+    -   !   ~
 
 =head3 Binary operators
 
-    **  *  %  /  //  +  -  >>  >>>  <<  &  &&  |  ||  .
-    
-=head3 Augmentive operators
-    
-    **=   *=    %=   /=   +=   -=   >>=  >>>=   <<=  &=   |=                   
    
+    **  *  %  /  //  +  -  >>  >>>  <<  ~   ~~   &  &&  |  ||  .
+
+=head3 Augmented operators
+
+    **=   *=    %=   /=   +=   -=   >>=  >>>=   <<=  &=   |=   ~=
+
+=head3 Conditional operators
 
-=head Conditional operators                                    
-   
     <    >   ==   <=   >=  !=
-    
+
 =head3 Miscellaneous operators
 
     ->   =>   ..
-    
+
 =cut
 
-*/        
+*/
 
         /* check for possible multi-character special tokens */
         if (c == '*') {
@@ -1069,11 +1076,11 @@
         else if (c == '!') {
             c = read_char(lexer->curfile);
             switch(c) {
-                case '=': return T_NE;
+                case '=': return T_NE;              /* != */
                 case EOF_MARKER: return T_EOF;
-                default:
+                default:                            /* ! */
                     unread_char(lexer->curfile, c);
-                    return T_ERROR;
+                    return T_NOT;
             }
         }
         else if (c == '=') {
@@ -1095,11 +1102,11 @@
                     if (c == '>') { /* >>> */
                         c = read_char(lexer->curfile);
                         if (c == '=') { /* >>>= */
-                            return T_RRSHIFT_ASSIGN;
+                            return T_LOG_RSHIFT_ASSIGN;
                         }
                         else { /* >>> */
                             unread_char(lexer->curfile, c);
-                            return T_RRSHIFT;
+                            return T_LOG_RSHIFT;
                         }
                     }
                     else if (c == '=') { /* >>= */
@@ -1131,9 +1138,14 @@
                         }
                         return T_HEREDOC_ID;
                     }
-                    else { /* no heredoc but '<<' */
-                        unread_char(lexer->curfile, c);
-                        return T_LSHIFT;
+                    else { /* no heredoc */
+                        if (c == '=') {                 /* <<= */
+                            return T_LSHIFT_ASSIGN;   
+                        }
+                        else {                          /* << */
+                            unread_char(lexer->curfile, c);
+                            return T_LSHIFT;
+                        }
                     }
                     break;
                 case EOF_MARKER: return T_EOF;
@@ -1142,6 +1154,17 @@
                     return T_LT;
             }
         }
+        else if (c == '~') {
+            c = read_char(lexer->curfile);
+            switch(c) {
+                case '~': return T_XOR;             /* ~~ */
+                case '=': return T_BXOR_ASSIGN;     /* ~= */
+                case EOF_MARKER: return T_EOF;
+                default:
+                    unread_char(lexer->curfile, c); /* ~ */
+                    return T_BXOR;
+            }
+        }
         else if (c == '&') {
             c = read_char(lexer->curfile);
             switch(c) {
@@ -1153,14 +1176,14 @@
                     return T_BAND;
             }
         }
-        else if (c == '|') {
+        else if (c == '|') {                        
             c = read_char(lexer->curfile);
             switch(c) {
-                case '|': return T_OR;
-                case '=': return T_BOR_ASSIGN;
+                case '|': return T_OR;              /* || */
+                case '=': return T_BOR_ASSIGN;      /* |= */
                 case EOF_MARKER: return T_EOF;
                 default:
-                    unread_char(lexer->curfile, c);
+                    unread_char(lexer->curfile, c); /* | */
                     return T_BOR;
             }
         }
@@ -1251,9 +1274,9 @@
 }
 
 
-/* 
+/*
+
 
-=back
 
 =head1 LEXER API
 
@@ -1311,7 +1334,7 @@
 }
 
 
-/* 
+/*
 
 =item read_macro()
 
@@ -1331,7 +1354,7 @@
     return t; /* return either T_ENDM or T_EOF */
 }
 
-/* 
+/*
 
 =item new_lexer()
 
@@ -1383,7 +1406,7 @@
     free(lexer);
 }
 
-/* 
+/*
 
 =item include_file()
 
@@ -1409,7 +1432,7 @@
     do_include_file(lexer, filename);
 }
 
-/* 
+/*
 
 =item close_file()
 
@@ -1430,7 +1453,7 @@
 }
 
 
-/* 
+/*
 
 =item next_token()
 

Modified: trunk/compilers/pirc/src/pirlexer.h
==============================================================================
--- trunk/compilers/pirc/src/pirlexer.h (original)
+++ trunk/compilers/pirc/src/pirlexer.h Sun Mar 25 07:06:10 2007
@@ -74,15 +74,16 @@
         T_MULTIPLY,                         /* "*",                       */
         T_CONCAT,                           /* ".",                       */
         T_DOTDOT,                           /* "..",                      */
+        T_NOT,                              /* "!",                       */
         T_BAND,                             /* "&",                       */
         T_AND,                              /* "&&",                      */
         T_BOR,                              /* "|",                       */
         T_OR,                               /* "||",                      */
-        T_XOR,                              /* "~",                       */
-        T_HUH,                              /* "~~",                      */
+        T_BXOR,                             /* "~",                       */
+        T_XOR,                              /* "~~",                      */
         T_RSHIFT,                           /* ">>",                      */
         T_LSHIFT,                           /* "<<",                      */
-        T_RRSHIFT,                          /* ">>>",                     */
+        T_LOG_RSHIFT,                       /* ">>>",                     */
         T_GT,                               /* ">",                       */
         T_LT,                               /* "<",                       */
         T_GE,                               /* ">=",                      */
@@ -130,10 +131,12 @@
         T_REGISTER,                         /* "'register'",              */
         T_DIVIDE_ASSIGN,                    /* "/=",                      */
         T_MODULO_ASSIGN,                    /* "%=",                      */
+        T_BXOR_ASSIGN,                      /* "~=",                      */
         T_BAND_ASSIGN,                      /* "&=",                      */
         T_BOR_ASSIGN,                       /* "|=",                      */
-        T_RRSHIFT_ASSIGN,                   /* ">>=",                     */
-        T_RSHIFT_ASSIGN,                    /* ">>>=",                    */
+        T_RSHIFT_ASSIGN,                    /* ">>=",                     */
+        T_LOG_RSHIFT_ASSIGN,                /* ">>>=",                    */
+        T_LSHIFT_ASSIGN,                    /* "<<=",                     */
         T_HEREDOC_ID,                       /* "heredoc id",              */
         T_HEREDOC_STRING,                   /* "heredoc string",          */
         T_PARROT_OP                         /* "parrot op",               */

Modified: trunk/compilers/pirc/src/pirmain.c
==============================================================================
--- trunk/compilers/pirc/src/pirmain.c  (original)
+++ trunk/compilers/pirc/src/pirmain.c  Sun Mar 25 07:06:10 2007
@@ -26,7 +26,9 @@
 
     /* check for errors */
     if (get_parse_errors(p)) 
-        fprintf(stderr, "There were %d errors.\n", get_parse_errors(p));    
+        fprintf(stderr, "\nThere were %d errors.\n", get_parse_errors(p));    
+    else
+        fprintf(stderr, "\nparsed successfully.\n");        
 
     /* clean up and exit */
     exit_parser(p);

Modified: trunk/compilers/pirc/src/pirparser.c
==============================================================================
--- trunk/compilers/pirc/src/pirparser.c        (original)
+++ trunk/compilers/pirc/src/pirparser.c        Sun Mar 25 07:06:10 2007
@@ -2,7 +2,7 @@
 
 =head1 NAME
 
-pirparser.c - parser for Parrot Intermediate Representation 
+pirparser.c - parser for Parrot Intermediate Representation
 
 =cut
 
@@ -17,9 +17,9 @@
 #include <stdarg.h>
 #include <string.h>
 
-/* 
+/*
 
-parser_state structure holds the current token, a pointer to the lexer, 
+parser_state structure holds the current token, a pointer to the lexer,
 and keeps track of the number of errors.
 
 */
@@ -35,14 +35,14 @@
 
 
 /* quit after 10 errors to prevent too many errors */
-#define MAX_ERRORS  10  
+#define MAX_ERRORS  10
 
 
 /* call next() to get the next token from the lexer */ /* NOTE: it's calling 
pirout() */
 #define next(P) do { pirout(P); P->curtoken = next_token(P->lexer); } while(0)
 
 
-/* 
+/*
 
 =head1 HELPER FUNCTIONS
 
@@ -62,7 +62,7 @@
     exit(0);
 }
 
-/* 
+/*
 
 =item get_parse_errors()
 
@@ -76,13 +76,14 @@
     return p->parse_errors;
 }
 
-/* 
+/*
 
 =item new_parser()
 
 constructor for a parser_state object.
 
 =cut
+
 */
 parser_state *
 new_parser(char const * filename) {
@@ -100,7 +101,7 @@
 }
 
 
-/* 
+/*
 
 =item static void syntax_error()
 
@@ -141,7 +142,7 @@
     }
 }
 
-/* 
+/*
 
 =item static void match()
 
@@ -155,7 +156,7 @@
 */
 static void
 match(parser_state *p, token expected) {
-    if (p->curtoken == expected) { /* if all is fine, get next token */        
               
+    if (p->curtoken == expected) { /* if all is fine, get next token */
         next(p);
     }
     else {
@@ -163,7 +164,7 @@
             syntax_error(p, 3 , "expected ", find_keyword(expected), " but got 
end of file");
             exit_parser(p);     /* no use to continue when having read end of 
file */
         }
-        else { /* 'normal' error; not end of file yet */            
+        else { /* 'normal' error; not end of file yet */
             syntax_error(p, 4, "expected ", find_keyword(expected), " but got: 
", find_keyword(p->curtoken));
 
             /* Try to reduce errors; skip tokens up to ".end" and
@@ -182,7 +183,7 @@
     }
 }
 
-/* 
+/*
 
 =item struct lexer_state const *get_lexer()
 
@@ -196,7 +197,7 @@
     return p->lexer;
 }
 
-/* 
+/*
 
 =item token get_token()
 
@@ -206,12 +207,12 @@
 
 */
 token get_token(parser_state *p) {
-    return p->curtoken;   
+    return p->curtoken;
 }
 
 
 
-/* 
+/*
 
 =back
 
@@ -229,7 +230,7 @@
 
 */
 static token
-expression(parser_state *p) {   
+expression(parser_state *p) {
     token exprtok = T_ERROR;
     switch(p->curtoken) {
         case T_IDENTIFIER:
@@ -257,8 +258,8 @@
 
   target -> REGISTER | IDENTIFIER
 
-=cut 
-    
+=cut
+
 */
 static void
 target(parser_state *p) {
@@ -274,7 +275,7 @@
     }
 }
 
-/* 
+/*
 
 =item type()
 
@@ -284,7 +285,7 @@
 
 */
 static void
-type(parser_state *p) {    
+type(parser_state *p) {
     switch(p->curtoken) {
         case T_INT:
         case T_NUM:
@@ -302,8 +303,8 @@
 
 =item key()
 
-  key -> '..' expr 
-  key -> expr [ '..' [ expr ] ] 
+  key -> '..' expr
+  key -> expr [ '..' [ expr ] ]
 
 =cut
 
@@ -325,12 +326,12 @@
 }
 
 
-/* 
+/*
 
 =item keylist()
 
   keylist -> '[' key { (';'|',') key } ']'
-  
+
 =cut
 
 */
@@ -351,7 +352,7 @@
 =item argument()
 
   argument -> HEREDOCID | expr | STRINGC '='> expr
-    
+
 =cut
 
 */
@@ -379,7 +380,7 @@
 =item argument_list()
 
   argument_list -> argument { ',' argument }
-  
+
 =cut
 
 */
@@ -398,8 +399,8 @@
 
 =item global_definition()
 
-  global_definition -> '.global' IDENT 
-  
+  global_definition -> '.global' IDENT
+
 =cut
 
 */
@@ -411,7 +412,7 @@
 }
 
 
-/* 
+/*
 
 =item arguments()
 
@@ -421,7 +422,7 @@
 
 */
 static void
-arguments(parser_state *p) {    
+arguments(parser_state *p) {
     match(p, T_LPAREN);
     if (p->curtoken != T_RPAREN) argument_list(p);
     match(p, T_RPAREN);
@@ -447,7 +448,7 @@
     }
 }
 
-/* 
+/*
 
 =item arith_expression()
 
@@ -455,24 +456,31 @@
 together with its right operand is parsed. If no operator,
 just return.
 
-  arith_expr -> [binop expr]
+  arith_expr -> [ binop expression ]
+
+  binop      -> '+' | '-' | '*' | '/' | '%' | '~~' | '~' | '&&' | '&' | '||' | 
'|' | '<<' | '>>' | '>>>' | '.'
 
 =cut
 
 */
 static void
-arith_expression(parser_state *p) {    
+arith_expression(parser_state *p) {
     switch(p->curtoken) {
         case T_PLUS:
         case T_MINUS:
         case T_DIVIDE:
         case T_MULTIPLY:
         case T_MODULO:
+        case T_XOR:
+        case T_BXOR:
         case T_OR:
         case T_BOR:
         case T_AND:
         case T_BAND:
-        case T_CONCAT: /* yeah I know, it's not arithmatic */
+        case T_RSHIFT:
+        case T_LOG_RSHIFT:
+        case T_LSHIFT:
+        case T_CONCAT: /* yeah I know, it's not arithmetic */
             next(p);
             expression(p);
             break;
@@ -486,16 +494,24 @@
 
 =item assignment()
 
-  assignment -> '=' (expr [binop expr] | target (keylist|arguments) | 
heredocstring ) '\n'
-  
+  assignment -> '=' ( unop expr | expr [binop expr] | target 
(keylist|arguments) | heredocstring ) '\n'
+
+  unop       -> '-' | '!' | '~'
+
 =cut
 
 */
 static void
-assignment(parser_state *p) {    
+assignment(parser_state *p) {
     match(p, T_ASSIGN);
 
     switch(p->curtoken) {
+        case T_NOT:
+        case T_MINUS:
+        case T_BXOR:  /* '~' used as binary 'not' op */
+            next(p);
+            expression(p);
+            break;
         case T_IDENTIFIER:
         case T_PREG:
         case T_PASM_PREG:
@@ -511,7 +527,7 @@
                 default: /* expression with a PMC target/id as first operand */
                     arith_expression(p);
                     break;
-            }            
+            }
             break;
 
         case T_HEREDOC_ID: { /* parse heredoc string */
@@ -519,12 +535,12 @@
             /* read_heredoc() returns a special token */
             p->curtoken = read_heredoc(p->lexer, heredocid);
             match(p, T_HEREDOC_STRING);
-            free(heredocid); /* clean up */            
+            free(heredocid); /* clean up */
             break;
         }
         default: /* general case for 'expr binop expr' */
             expression(p);
-            arith_expression(p);            
+            arith_expression(p);
             break;
     }
     match(p, T_NEWLINE);
@@ -540,7 +556,7 @@
 
 */
 static void
-goto_statement(parser_state *p) {    
+goto_statement(parser_state *p) {
     match(p, T_GOTO);
     match(p, T_IDENTIFIER);
     match(p, T_NEWLINE);
@@ -551,12 +567,12 @@
 =item return_statement()
 
   return_statement -> '.return' (arguments|tailcall) '\n'
-  
+
 =cut
 
 */
 static void
-return_statement(parser_state *p) {    
+return_statement(parser_state *p) {
     match(p, T_RETURN);
     if (p->curtoken == T_LPAREN) { /* arguments */
         arguments(p);
@@ -573,12 +589,12 @@
 =item yield_statement()
 
   yield_statement -> '.yield' arguments '\n'
-  
+
 =cut
 
 */
 static void
-yield_statement(parser_state *p) {    
+yield_statement(parser_state *p) {
     match(p, T_YIELD);
     arguments(p);
     match(p, T_NEWLINE);
@@ -591,10 +607,10 @@
   close_ns -> '.endnamespace' IDENT '\n'
 
 =cut
-  
+
 */
 static void
-close_ns(parser_state *p) {   
+close_ns(parser_state *p) {
     match(p, T_ENDNAMESPACE);
     match(p, T_IDENTIFIER);
     match(p, T_NEWLINE);
@@ -605,12 +621,12 @@
 =item open_ns()
 
   open_ns -> '.namespace' IDENT '\n'
-  
+
 =cut
 
 */
 static void
-open_ns(parser_state *p) {    
+open_ns(parser_state *p) {
     match(p, T_NAMESPACE);
     match(p, T_IDENTIFIER);
     match(p, T_NEWLINE);
@@ -626,7 +642,7 @@
 
 */
 static void
-local_id_list(parser_state *p) {   
+local_id_list(parser_state *p) {
     match(p, T_IDENTIFIER);
     if (p->curtoken == T_UNIQUE_REG_FLAG) next(p);
 
@@ -642,14 +658,14 @@
 
 =item declaration_list()
 
- declaration_list -> type local_id_list '\n' 
- 
+ declaration_list -> type local_id_list '\n'
+
 =cut
 
 */
 
 static void
-declaration_list(parser_state *p) {    
+declaration_list(parser_state *p) {
     type(p);
     local_id_list(p);
     match(p, T_NEWLINE);
@@ -660,13 +676,13 @@
 =item sym_declaration()
 
   sym_declaration -> '.sym' declaration_list
- 
+
 =cut
 
 */
 static void
 sym_declaration(parser_state *p) {
-    
+
     match(p, T_SYM);
     declaration_list(p);
 }
@@ -676,12 +692,12 @@
 =item local_declaration()
 
   local_declaration -> '.local' declaration_list
-  
+
 =cut
 
 */
 static void
-local_declaration(parser_state *p) {    
+local_declaration(parser_state *p) {
     match(p, T_LOCAL);
     declaration_list(p);
 }
@@ -692,13 +708,13 @@
 =item stringconstant()
 
   strinconstant -> DOUBLE_QUOTED_STRING | SINGLE_QUOTED_STRING
-  
+
 =cut
 
 */
 static void
 stringconstant(parser_state *p) {
-    
+
     if (p->curtoken == T_DOUBLE_QUOTED_STRING
         || p->curtoken == T_SINGLE_QUOTED_STRING) {
         next(p);
@@ -712,13 +728,13 @@
 
 =item lex_declaration()
 
-  lex_declaration -> '.lex' STRINGC ',' target '\n' 
+  lex_declaration -> '.lex' STRINGC ',' target '\n'
 
 =cut
 
 */
 static void
-lex_declaration(parser_state *p) {    
+lex_declaration(parser_state *p) {
     match(p, T_LEX);
     stringconstant(p);
     match(p, T_COMMA);
@@ -732,17 +748,17 @@
 
 =item condition_expression()
 
-  conditional_expression -> expression [ ('>'|'>='|'<'|'<='|'=='|'!=') 
expression] 
+  conditional_expression -> expression [ ('>'|'>='|'<'|'<='|'=='|'!=') 
expression]
 
 =cut
 
 */
 static void
-conditional_expression(parser_state *p) {    
+conditional_expression(parser_state *p) {
     expression(p);
 
     switch(p->curtoken) { /* optional */
-        case T_GE: case T_GT: case T_EQ: 
+        case T_GE: case T_GT: case T_EQ:
         case T_NE: case T_LT: case T_LE:
             next(p); /* skip comparison op */
             expression(p);
@@ -756,7 +772,7 @@
 
 =item unless_statement()
 
-  unless_statement -> 'unless' ('null' expression|conditional_epxression) 
'goto' IDENT '\n' 
+  unless_statement -> 'unless' ('null' expression|conditional_epxression) 
'goto' IDENT '\n'
 
 =cut
 
@@ -787,7 +803,7 @@
 
 */
 static void
-if_statement(parser_state *p) {    
+if_statement(parser_state *p) {
     match(p, T_IF);
     if (p->curtoken == T_NULL) { /* if null expr goto LABEL */
         next(p);
@@ -811,7 +827,7 @@
 
 */
 static void
-const_definition(parser_state *p) {    
+const_definition(parser_state *p) {
     switch(p->curtoken) {
         case T_INT:
             next(p);
@@ -826,7 +842,7 @@
             match(p, T_NUMBER_CONSTANT);
             break;
         case T_STRING: /* both string and PMC have strings as constants */
-        case T_PMC:                    
+        case T_PMC:
             next(p);
             match(p, T_IDENTIFIER);
             match(p, T_ASSIGN);
@@ -850,7 +866,7 @@
 
 */
 static void
-methodcall(parser_state *p) {    
+methodcall(parser_state *p) {
     match(p, T_INVOCANT_IDENT);
     if (p->curtoken == T_IDENTIFIER) next(p);
     else stringconstant(p);
@@ -864,15 +880,15 @@
 
 =item long_return_statement()
 
-  long_return_statement -> '.pcc_begin_return' '\n' 
+  long_return_statement -> '.pcc_begin_return' '\n'
                            { '.return' expression '\n' }
                            '.pcc_end_return' '\n'
-  
+
 =cut
 
 */
 static void
-long_return_statement(parser_state *p) {    
+long_return_statement(parser_state *p) {
     match(p, T_PCC_BEGIN_RETURN);
     match(p, T_NEWLINE);
 
@@ -918,21 +934,22 @@
 
 /*
 
-=item param_flag()
+=item param_flags()
+
+  param_flags -> ':slurpy'
+               | ':named'['(' string ')']
+               | ':unique_reg'
+               | ':optional'
+               | ':opt_flag'
 
-  param_flag -> ':slurpy' 
-              | ':named'['(' string ')'] 
-              | ':unique_reg'
-              | ':optional' 
-              | ':opt_flag' 
-              
 =cut
 
 */
 static void
-param_flags(parser_state *p) {    
+param_flags(parser_state *p) {
     int ok = 1;
     while (ok) {
+        /* if the current token is a flag, parse it */
         switch(p->curtoken) {
             case T_SLURPY_FLAG:
             case T_UNIQUE_REG_FLAG:
@@ -948,11 +965,14 @@
                     match(p, T_RPAREN);
                 }
                 break;
-            case T_NEWLINE:
+            /* however, if the current token is a comma or ')', then quit 
parsing flags */
+            case T_COMMA:
+            case T_RPAREN:
                 ok = 0; /* stop loop */
                 break;
+            /* if none of the above, error! */
             default:
-                syntax_error(p, 1, "syntax error: parameter flag or newline 
expected");
+                syntax_error(p, 2, "syntax error: parameter flag or newline 
expected, but got ", find_keyword(p->curtoken));
                 ok = 0; /* stop loop */
                 break;
         }
@@ -966,7 +986,7 @@
   long-invocation -> '.pcc_begin' '\n'
                      { '.arg' expression arg_flags }
                      ('.pcc_call'|'.nci_call'|'.meth_call')
-                     { (local_declaration| '.result' target '\n') } 
+                     { (local_declaration| '.result' target '\n') }
                      '.pcc_end' '\n'
 
 =cut
@@ -1038,15 +1058,15 @@
 
 =item long_yield_statement()
 
-  long_yield_statement -> '.pcc_begin_yield' '\n' 
+  long_yield_statement -> '.pcc_begin_yield' '\n'
                           { '.yield' expr '\n' }
-                          '.pcc_end_yield' '\n' 
+                          '.pcc_end_yield' '\n'
 
 =cut
 
 */
 static void
-long_yield_statement(parser_state *p) {   
+long_yield_statement(parser_state *p) {
     match(p, T_PCC_BEGIN_YIELD);
     match(p, T_NEWLINE);
 
@@ -1064,9 +1084,12 @@
 =item target_statement()
 
   target_statement -> target '=' assignment
-                    | target ('+='|'-='|etc.) expression
-                    | target keylist '=' expression
-                    |
+                    | target augmented_op expression '\n'
+                    | target keylist '=' expression '\n'
+                    | target '->' (stringconstant|IDENT) arguments '\n'
+                    | target arguments '\n'
+
+  augmented_op    -> '+=' | '-=' | '%=' | '/=' | '*=' | '~=' | '&=' | '|=' | 
'**=' | '<<=' | '>>=' | '>>>='
 
 =cut
 
@@ -1085,6 +1108,12 @@
         case T_DIVIDE_ASSIGN:
         case T_POWER_ASSIGN:
         case T_MULTIPLY_ASSIGN:
+        case T_BXOR_ASSIGN:
+        case T_BAND_ASSIGN:
+        case T_BOR_ASSIGN:
+        case T_LSHIFT_ASSIGN:
+        case T_RSHIFT_ASSIGN:
+        case T_LOG_RSHIFT_ASSIGN:
             next(p);
             expression(p);
             match(p, T_NEWLINE);
@@ -1122,7 +1151,7 @@
 
 */
 static void
-target_list(parser_state *p) {    
+target_list(parser_state *p) {
     match(p, T_LPAREN);
     target(p);
     while(p->curtoken == T_COMMA) {
@@ -1138,13 +1167,13 @@
 
 =item multi_result_invocation()
 
-  multi-result-invocation -> target_list '=' (subcall | methodcall) 
+  multi-result-invocation -> target_list '=' (subcall | methodcall)
 
 =cut
 
 */
 static void
-multi_result_invocation(parser_state *p) {    
+multi_result_invocation(parser_state *p) {
     target_list(p);
     match(p, T_ASSIGN);
 
@@ -1170,10 +1199,10 @@
 =item macro_expansion()
 
   macro_expansion -> ??
-  
+
 TODO: create a parse tree for each macro definition, then on macro expansion
 the parse tree can be populated with the actual values (macro parameters).
- 
+
 =cut
 
 */
@@ -1220,7 +1249,7 @@
 */
 static void
 get_results_instruction(parser_state *p) {
-    
+
     match(p, T_GET_RESULTS);
     target_list(p);
     match(p, T_NEWLINE);
@@ -1232,7 +1261,7 @@
 =item instructions()
 
   instruction -> {LABEL '\n'} instr
-  
+
   instr -> if_statement
          | unless_statement
          | local_declaration
@@ -1365,18 +1394,18 @@
 =item multi_type_list()
 
   multi-type-list -> '(' [multi-type {',' multi-type } ] ')'
-  
+
   multi-type -> IDENT | STRINGC | keylist | type
 
 =cut
 
 */
 static void
-multi_type_list(parser_state *p) {    
+multi_type_list(parser_state *p) {
     int wantmore = 1;
 
     match(p, T_LPAREN);
-    while (wantmore) {        
+    while (wantmore) {
         switch (p->curtoken) {
             case T_IDENTIFIER:
             case T_SINGLE_QUOTED_STRING:
@@ -1412,7 +1441,7 @@
 =item sub_flags()
 
   sub_flags -> [sub_flag { [','] sub_flag } ]
-  
+
   sub_flag  -> ':anon'
              | ':init'
              | ':load'
@@ -1422,7 +1451,7 @@
              | ':vtable' '(' stringconstant ')'
              | ':multi' multi-type-list
              | ':postcomp'
-             | ':immediate'             
+             | ':immediate'
 
 =cut
 
@@ -1501,7 +1530,7 @@
 
 */
 static void
-parameters(parser_state *p) {    
+parameters(parser_state *p) {
     while (p->curtoken == T_PARAM) {
         next(p); /* skip '.param */
         if (p->curtoken == T_REGISTER) { /* parameter -> '.param' register */
@@ -1526,7 +1555,7 @@
 
 */
 static void
-sub_definition(parser_state *p) {    
+sub_definition(parser_state *p) {
     match(p, T_SUB);
 
     if (p->curtoken == T_IDENTIFIER) match(p, T_IDENTIFIER);
@@ -1550,10 +1579,10 @@
 
 */
 static void
-emit_block(parser_state *p) {    
+emit_block(parser_state *p) {
     match(p, T_EMIT);
     match(p, T_NEWLINE);
-    
+
     while (p->curtoken == T_PARROT_OP) {
         next(p);
         while (p->curtoken != T_NEWLINE) {
@@ -1564,7 +1593,7 @@
         match(p, T_NEWLINE);
     }
     if (p->curtoken == T_NEWLINE) next(p);
-    
+
     match(p, T_EOM);
 }
 
@@ -1578,7 +1607,7 @@
 
 */
 static void
-macro_parameters(parser_state *p) {    
+macro_parameters(parser_state *p) {
     if (p->curtoken == T_LPAREN) next(p);
     else return; /* no parameters apparently */
 
@@ -1602,7 +1631,7 @@
 
 */
 static void
-macro_definition(parser_state *p) {    
+macro_definition(parser_state *p) {
     match(p, T_MACRO);
     match(p, T_IDENTIFIER);
     macro_parameters(p);
@@ -1628,9 +1657,9 @@
 by calling the next token.
 
   include -> '.include' stringconstant
- 
+
 =cut
- 
+
 */
 static void
 include(parser_state *p) {
@@ -1644,10 +1673,10 @@
         /* read the file to be included and get first token of the included 
file */
         open_include_file(p->lexer);
         next(p);
-                
+
         TOP(p); /* go parse it */
         /* switch back to other file that included the one above */
-        close_include_file(p->lexer);       
+        close_include_file(p->lexer);
         next(p); /* get next token from this file */
     }
 
@@ -1664,7 +1693,7 @@
 */
 
 static void
-pragma(parser_state *p) {    
+pragma(parser_state *p) {
     match(p, T_PRAGMA);
     match(p, T_N_OPERATORS);
     match(p, T_INTEGER_CONSTANT);
@@ -1675,12 +1704,12 @@
 =item hll_specifier()
 
   hll_specifier -> '.HLL' stringconstant ',' stringconstant
-  
+
 =cut
 
 */
 static void
-hll_specifier(parser_state *p) {    
+hll_specifier(parser_state *p) {
     match(p, T_HLL);
     stringconstant(p);
     match(p, T_COMMA);
@@ -1692,12 +1721,12 @@
 =item hll_mapping()
 
   hll_mapping -> '.HLL_map' INTC ',' INTC
-  
+
 =cut
 
 */
 static void
-hll_mapping(parser_state *p) {    
+hll_mapping(parser_state *p) {
     match(p, T_HLL_MAP);
     match(p, T_INTEGER_CONSTANT);
     match(p, T_COMMA);
@@ -1714,7 +1743,7 @@
 
 */
 static void
-namespace_declaration(parser_state *p) {    
+namespace_declaration(parser_state *p) {
     match(p, T_NAMESPACE);
     if (p->curtoken == T_LBRACKET) {
         next(p); /* skip '[' */
@@ -1738,7 +1767,7 @@
 
 */
 static void
-loadlib(parser_state *p) {    
+loadlib(parser_state *p) {
     match(p, T_LOADLIB);
     stringconstant(p);
 }
@@ -1816,7 +1845,7 @@
 
 */
 static void
-program(parser_state *p) {    
+program(parser_state *p) {
     /* the file may have some initial newlines; eat them */
     if (p->curtoken == T_NEWLINE) next(p);
 
@@ -1835,7 +1864,7 @@
 Entry point of the parser
 
   TOP -> program EOF
-  
+
 =cut
 
 */
@@ -1846,10 +1875,15 @@
 
     /* do NOT match T_EOF; match() tries to read the next token instead, do a 
manual check. */
     if (p->curtoken != T_EOF) {
-        syntax_error(p, 3, "end of file expected in file '", 
get_current_file(p->lexer), "'\n");    
-    }    
+        syntax_error(p, 3, "end of file expected in file '", 
get_current_file(p->lexer), "'\n");
+    }
 }
 
 
+/*
 
+=back
 
+=cut
+
+*/

Reply via email to