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 {