Author: kjs
Date: Sat Feb 23 05:00:01 2008
New Revision: 26019

Modified:
   trunk/languages/c99/src/builtins/say.pir
   trunk/languages/c99/src/parser/actions.pm
   trunk/languages/c99/src/parser/grammar.pg

Log:
[c99]
- add is pirop traits to basic operators
- add postfix inc/dec operators
- add several other actions, refactoring the grammar a bit
- add initial version for for loops.

Modified: trunk/languages/c99/src/builtins/say.pir
==============================================================================
--- trunk/languages/c99/src/builtins/say.pir    (original)
+++ trunk/languages/c99/src/builtins/say.pir    Sat Feb 23 05:00:01 2008
@@ -39,6 +39,26 @@
     print "\n"
 .end
 
+.sub 'infix:<'
+    .param pmc a
+    .param pmc b
+    islt $I0, a, b
+    .return ($I0)
+.end
+
+.sub 'postfix:++'
+    .param pmc arg
+    $P0 = clone arg
+    inc $P0
+    .return (arg)
+.end
+
+.sub 'postfix:--'
+    .param pmc arg
+    $P0 = clone arg
+    dec $P0
+    .return (arg)
+.end
 
 
 # Local Variables:

Modified: trunk/languages/c99/src/parser/actions.pm
==============================================================================
--- trunk/languages/c99/src/parser/actions.pm   (original)
+++ trunk/languages/c99/src/parser/actions.pm   Sat Feb 23 05:00:01 2008
@@ -52,17 +52,91 @@
 }
 
 method direct_declarator($/) {
-    make $( $<declarator_prefix> );
+    my $past := $( $<declarator_prefix> );
+    #my $past := $( $<declarator_suffix>[0] );
+    #$past.name($pref.name());
+    make $past;
 }
 
 method declarator_prefix($/, $key) {
     make $( $/{$key} );
 }
 
+method declarator_suffix($/, $key) {
+    make $( $/{$key} );
+}
+
+method parameter_type_list($/) {
+    my $past := $( $<parameter_list> );
+    if $<vararg> {
+        $past.push( PAST::Var.new( :name('@vararg'), :slurpy(1), 
:scope('parameter'), :node($/) ) );
+    }
+    make $past;
+}
+
+method parameter_list($/) {
+    ## create the function block here already; it's needed to store the 
parameters
+    my $past := PAST::Block.new( :blocktype('declaration'), :node($/) );
+    for $<parameter_declaration> {
+        $past.push( $( $_ ) );
+    }
+    make $past;
+}
+
+method parameter_declaration($/, $key) {
+    make $( $/{$key} );
+}
+
 method statement($/, $key) {
     make $( $/{$key} );
 }
 
+method jump_statement($/, $key) {
+    if $key eq 'return' {
+        my $past := PAST::Op.new( :pirop('return'), :node($/) );
+        if $<expression> {
+            $past.push( $( $<expression>[0] ) );
+        }
+        make $past;
+    }
+    else {
+        $/.panic("$key is not implemented!");
+    }
+}
+
+method for1_statement($/) {
+    my $past := PAST::Stmts.new( :node($/) );
+    my $body := $( $<statement> );
+    my $cond;
+    if $<cond> {
+        $cond := $( $<cond>[0] );
+    }
+    else { # a missing condition is true
+        $cond := PAST::Val.new( :returns('Integer'), :value('1'), :node($/) );
+    }
+
+
+
+    if $<init> {
+        my $init := $( $<init>[0] );
+        $past.unshift($init);
+    }
+
+
+    if $<step> {
+        my $step := $( $<step>[0] );
+        $body := PAST::Stmts.new( $body, $step, :node($/) );
+    }
+    my $loop := PAST::Op.new( $cond, $body, :pasttype('while'), :node($/) );
+    $past.push($loop);
+
+    make $past;
+}
+
+method for2_statement($/) {
+
+}
+
 method expression($/) {
     make $( $<assignment_expression>[0] );
 }
@@ -135,6 +209,30 @@
     make $( $/{$key} );
 }
 
+method index($/) {
+    my $expr := $( $<expression> );
+    ## XXX
+    make PAST::Op.new( $expr, :name('xxx_index'), :pasttype('call'), :node($/) 
);
+}
+
+method direct_field($/) {
+    my $field := $( $<identifier> );
+    ## XXX
+    make PAST::Op.new( $field, :name('xxx_get_field'), :pasttype('call'), 
:node($/) );
+}
+
+method indirect_field($/) {
+    my $field := $( $<identifier> );
+    ## XXX
+    make PAST::Op.new( $field, :name('xxx_get_indirect'), :pasttype('call'), 
:node($/) );
+}
+
+method inc_or_dec($/) {
+    my $opname := 'postfix:' ~ ~$<op>;
+    my $past := PAST::Op.new( :name($opname), :pasttype('call'), :node($/) );
+    make $past;
+}
+
 method arguments($/) {
     if $<argument_expression_list> {
         make $( $<argument_expression_list>[0] );
@@ -187,7 +285,8 @@
 
 method identifier($/) {
     ## XXX fix scopes
-    make PAST::Var.new( :name( ~$/ ), :scope('package'), :node($/) );
+    ## XXX fix declarations so that :viviself can be removed
+    make PAST::Var.new( :name( ~$/ ), :scope('package'), :viviself('Integer'), 
:node($/) );
 }
 
 method cast_expression($/) {

Modified: trunk/languages/c99/src/parser/grammar.pg
==============================================================================
--- trunk/languages/c99/src/parser/grammar.pg   (original)
+++ trunk/languages/c99/src/parser/grammar.pg   Sat Feb 23 05:00:01 2008
@@ -75,6 +75,13 @@
 }
 
 rule type_specifier {
+    | <builtin_type>
+    | <struct_or_union_specifier>
+    | <enum_specifier>
+    | <typedef_name>
+}
+
+rule builtin_type {
     | 'void'
     | 'char'
     | 'short'
@@ -87,13 +94,10 @@
     | '_Bool'
     | '_Complex'
     | '_Imaginary'
-    | <struct_or_union_specifier>
-    | <enum_specifier>
-    | <typedef_name>
 }
 
 rule struct_or_union_specifier {
-    ['struct'|'union']
+    $<type>=['struct'|'union']
     [
     | <struct_or_union_definition>
     | <pre_declaration>
@@ -142,9 +146,7 @@
 }
 
 rule type_qualifier {
-    | 'const'
-    | 'restrict'
-    | 'volatile'
+    $<qualifier>=['const'|'restrict'|'volatile']
 }
 
 rule declarator {
@@ -164,8 +166,8 @@
 }
 
 rule declarator_suffix {
-    | '(' <identifier_list>? ')'
-    | '(' <parameter_type_list> ')'
+    | '(' <identifier_list>? ')' ###{*}       #= identifier_list ## old-style 
C parameter declarations
+    | '(' <parameter_type_list> ')' {*}    #= parameter_type_list
     | '[' <assignment_expression>? ']'
     | '[' '*' ']'
 }
@@ -175,18 +177,20 @@
 }
 
 rule parameter_type_list {
-    <parameter_list> [',' '...']?
+    <parameter_list>  [$<vararg>=[',' '...']]?
+    {*}
 }
 
 rule parameter_list {
     <parameter_declaration> [',' <parameter_declaration>]*
+    {*}
 }
 
 rule parameter_declaration {
     <declaration_specifiers>
     [
-    | <declarator>
-    | <abstract_declarator>?
+    | <declarator> {*}               #= declarator
+    | <abstract_declarator>? {*}     #= abstract_declarator
     ]
 }
 
@@ -264,9 +268,9 @@
     | <switch_statement>
     | <while_statement> {*}           #= while_statement
     | <do_while_statement> {*}        #= do_while_statement
-    | <for1_statement>
+    | <for1_statement> {*}            #= for1_statement
     | <for2_statement>
-    | <jump_statement>
+    | <jump_statement> {*}            #= jump_statement
 }
 
 rule labeled_statement {
@@ -310,18 +314,21 @@
 }
 
 rule for1_statement {
-    'for' '(' <expression>? ';' <expression>? ';' <expression>? ')' <statement>
+    'for' '(' [$<init>=<expression>]? ';' [$<cond>=<expression>]? ';' 
[$<step>=<expression>]? ')'
+    <statement>
+    {*}
 }
 
 rule for2_statement {
     'for' '(' <declaration> <expression>? ';' <expression>? ')' <statement>
+    {*}
 }
 
 rule jump_statement {
-    | 'goto' <identifier> ';'
-    | 'continue' ';'
-    | 'break' ';'
-    | 'return' <expression>? ';'
+    | 'goto' <identifier> ';' {*}         #= goto
+    | 'continue' ';' {*}                  #= continue
+    | 'break' ';' {*}                     #= break
+    | 'return' <expression>? ';' {*}      #= return
 }
 
 
@@ -550,19 +557,19 @@
 proto 'infix:<<' is tighter('infix:==') { ... }
 proto 'infix:>>' is equal('infix:<<') { ... }
 
-proto 'infix:+' is tighter('infix:<<') { ... }
-proto 'infix:-' is equal('infix:+') { ... }
+proto 'infix:+' is tighter('infix:<<') is pirop('n_add') { ... }
+proto 'infix:-' is equal('infix:+') is pirop('n_sub') { ... }
 
-proto 'infix:*' is tighter('infix:+') { ... }
-proto 'infix:/' is equal('infix:*') { ... }
-proto 'infix:%' is equal('infix:*') { ... }
+proto 'infix:*' is tighter('infix:+') is pirop('n_mul') { ... }
+proto 'infix:/' is equal('infix:*') is pirop('n_div') { ... }
+proto 'infix:%' is equal('infix:*') is pirop('n_mod') { ... }
 
 proto 'term:' is tighter('infix:*')
               is parsed(&cast_expression) { ... }
 
 
 rule postfix_expression_prefix {
-    | <primary_expression> {*}                                 #= 
primary_expression
+    | <primary_expression> {*}                                  #= 
primary_expression
     | '(' <type_name> ')' '{' <initializer_list> [',']? '}' {*} #= type_name
 }
 
@@ -573,12 +580,31 @@
 }
 
 rule postfix_expression_suffix {
-    | '[' <expression> ']'
+    | <index> {*}                           #= index
     | <arguments>  {*}                      #= arguments
-    | '.' <identifier>
-    | '->' <identifier>
-    | '++'
-    | '--'
+    | <direct_field> {*}                    #= direct_field
+    | <indirect_field> {*}                  #= indirect_field
+    | <inc_or_dec> {*}                      #= inc_or_dec
+}
+
+rule inc_or_dec {
+    $<op>=['++'|'--']
+    {*}
+}
+
+rule index {
+    '[' <expression> ']'
+    {*}
+}
+
+rule direct_field {
+    '.' <identifier>
+    {*}
+}
+
+rule indirect_field {
+    '->' <identifier>
+    {*}
 }
 
 rule arguments {

Reply via email to