Author: kjs
Date: Sun Aug 24 04:43:39 2008
New Revision: 30507

Modified:
   trunk/compilers/pirc/new/pir.y

Log:
[pirc/new] add documentation to pir.y
+ add function documentation
+ add some comments here and there
+ add doc. about impl of constant folding and instr. select.

Modified: trunk/compilers/pirc/new/pir.y
==============================================================================
--- trunk/compilers/pirc/new/pir.y      (original)
+++ trunk/compilers/pirc/new/pir.y      Sun Aug 24 04:43:39 2008
@@ -163,7 +163,7 @@
 #endif
 
 
-
+/* the parser aborts if there are more than 10 errors */
 #define MAX_NUM_ERRORS  10
 
 
@@ -455,9 +455,6 @@
                             { set_hll_map($2, $4); }
                   ;
 
-
-/* Namespaces */
-
 namespace_decl    : ".namespace" '[' opt_namespace ']'
                             { set_namespace(lexer, $3); }
                   ;
@@ -478,9 +475,6 @@
                             { $$ = expr_from_const(new_const(STRING_TYPE, 
$1)); }
                   ;
 
-
-/* Sub definition */
-
 sub_def           : sub_head sub_flags "\n"
                     parameters
                     instructions
@@ -565,6 +559,7 @@
                   | instructions instruction
                   ;
 
+/* helper rule to create a new instruction node before the instruction is 
parsed */
 instruction       : { new_instr(lexer); }
                     instr
                   ;
@@ -644,10 +639,10 @@
 
 keyaccess         : target keylist
                          {
-                           if ($1->type != PMC_TYPE)
-                               yyerror(yyscanner, lexer, "indexed object is 
not of type PMC");
-                           else
+                           if ($1->type == PMC_TYPE) /* only PMCs can be 
indexed */
                               set_target_key($1, $2);
+                           else
+                              yyerror(yyscanner, lexer, "indexed object is not 
of type PMC");
 
                            $$ = $1;
                          }
@@ -667,6 +662,47 @@
 assignment_stat   : assignment "\n"
                   ;
 
+/*
+
+=head2 Constant folding and Instruction Selection
+
+Constant folding is implemented in the parser. This is done by writing
+many specific alternatives, instead of using C<general> rules that
+would match all input. This way, the parser's matching mechanism is
+used to select specific cases, for instance adding 2 integer numbers.
+
+Based on the values of the terminals, some instructions can be optimized
+by selecting more efficient equivalent instructions.
+
+The table below specifies how this is done. Terminals are numbered and
+referenced using YACC syntax ($1 for the first terminal, $2 for the
+second, etc.).
+
+
+ rule                                   | instruction         | condition
+ 
=================================================================================
+ target '=' {integer, number}           | set $1, $3          | $3 != 0
+                                        | null $1             | $3 == 0
+                                        |                     |
+ target '=' target                      | set $1, $3          | $1 != $3
+                                        | noop                | $1 == $3
+                                        |                     |
+ target '=' target binop {integer,      | $4 $1, $3, $5       | $1 != $3
+                          number}       | inc/dec $1          | $1 == $3, $5 
== 1, $4 == {'+', '-'}
+                                        | noop                | $1 == $3, $5 
== 0, $4 == {'+', '-'}
+                                        | null $1             | $1 == $3, $5 
== 0, $4 == {'*'}
+                                        | error: divide by 0  | $1 == $3, $5 
== 0, $4 == {'/', '//'}
+                                        | $4 $1, $5           | $1 == $3, $5 
!= {0, 1}
+                                        |                     |
+ target '=' target binop {string,       | $4 $1, $5           | $1 == $3
+                          target}       | $4 $1, $3, $5       | $1 != $3
+                                        |                     |
+
+
+=cut
+
+*/
+
 assignment        : set_instruction
                   | target '=' TK_INTC
                          {
@@ -819,7 +855,7 @@
                          { set_instrf(lexer, "set", "%C", fold_n_i(yyscanner, 
$1, $2, $3)); }
                   ;
 
-
+/* all variants of the "set" opcode */
 set_instruction   : "set" target ',' keyaccess
                         { set_instrf(lexer, "set", "%T%T", $2, $4); }
                   | "set" keyaccess ',' expression
@@ -1210,9 +1246,9 @@
 local_var_name    : identifier
                         { $$ = $1; }
                   | TK_SYMBOL
-                        {
+                        { /* if a symbol was found, that means it was already 
declared */
                           yyerror(yyscanner, lexer, "local symbol already 
declared!");
-                          $$ = $1->name;
+                          $$ = $1->name; /* always return something to prevent 
seg. faults. */
                         }
                   ;
 
@@ -1222,7 +1258,7 @@
 
 lex_decl          : ".lex" TK_STRINGC ',' target "\n"
                         {
-                          if ($4->type == PMC_TYPE)
+                          if ($4->type == PMC_TYPE) /* only PMCs can be stored 
as lexicals */
                               set_lex_flag($4, $2);
                           else
                               yyerror(yyscanner, lexer,
@@ -1686,7 +1722,7 @@
 
 /*
 
-=head1 Constant folding routines.
+=head1 FUNCTIONS
 
 =over 4
 
@@ -2092,16 +2128,49 @@
     return NULL;
 }
 
+/*
+
+=item C<static int
+evaluate_i_i(int a, pir_rel_operator op, double b)>
+
+Compare C<a> with C<b> according to the relational operator C<op>.
+Wrapper for C<evaluate_n_n>, which takes arguments of type double.
+
+=cut
+
+*/
 static int
 evaluate_i_i(int a, pir_rel_operator op, int b) {
     return evaluate_n_n(a, op, b);
 }
 
+/*
+
+=item C<static int
+evaluate_n_i(int a, pir_rel_operator op, double b)>
+
+Compare C<a> with C<b> according to the relational operator C<op>.
+Wrapper for C<evaluate_n_n>, which takes arguments of type double.
+
+=cut
+
+*/
 static int
 evaluate_n_i(double a, pir_rel_operator op, int b) {
     return evaluate_n_n(a, op, b);
 }
 
+/*
+
+=item C<static int
+evaluate_i_n(int a, pir_rel_operator op, double b)>
+
+Compare C<a> with C<b> according to the relational operator C<op>.
+Wrapper for C<evaluate_n_n>, which takes arguments of type double.
+
+=cut
+
+*/
 static int
 evaluate_i_n(int a, pir_rel_operator op, double b) {
     return evaluate_n_n(a, op, b);
@@ -2138,6 +2207,19 @@
     }
 }
 
+/*
+
+=item C<static int
+evaluate_s_s(char *a, pir_rel_operator op, char *b)>
+
+Compare string C<a> with string C<b> using the operator C<op>.
+The function uses C's C<strcmp> function. Based on that result,
+which can be -1 (smaller), 0 (equal) or 1 (larger), a boolean
+result is returned.
+
+=cut
+
+*/
 static int
 evaluate_s_s(char *a, pir_rel_operator op, char *b) {
     int result = strcmp(a, b);

Reply via email to