Author: kjs Date: Sat Jan 26 09:52:08 2008 New Revision: 25257 Modified: trunk/languages/ecmascript/src/parser/actions.pm trunk/languages/ecmascript/src/parser/grammar.pg
Log: [ecmascript] various updates to actions.pm. Modified: trunk/languages/ecmascript/src/parser/actions.pm ============================================================================== --- trunk/languages/ecmascript/src/parser/actions.pm (original) +++ trunk/languages/ecmascript/src/parser/actions.pm Sat Jan 26 09:52:08 2008 @@ -301,28 +301,26 @@ } method primary_expression($/, $key) { - # XXX handle "this" - #if $key eq 'this' { - #} - #else { - make $( $/{$key} ); - #} + make $( $/{$key} ); } +method this($/) { + make PAST::Op.new( :inline(' %r = self'), :node($/) ); +} method call_expression($/) { my $invocant := $( $<member_expression> ); - my $past := PAST::Op.new( :pasttype('call'), :node($/) ); - $past.push($invocant); - my @args := $<arguments><assignment_expression>; - for @args { - $past.push( $($_) ); - } + # the $<arguments> rule already creates a :pasttype('call') node. + my $past := $( $<arguments> ); + $past.unshift($invocant); for $<post_call_expr> { my $postexpr := $( $_ ); - # XXX apply postexpr on $past + # the $invocant of this $postexpr is $past + $postexpr.unshift($past); + # make it work in a chain, like foo()()()() + $past := $postexpr; } make $past; @@ -393,6 +391,16 @@ make $past; } +method arguments($/) { + # an arguments node always implies a function call; + # create it here; unshift the invocant later if it's available. + my $past := PAST::Op.new( :pasttype('call'), :node($/) ); + for $<assignment_expression> { + $past.push( $($_) ); + } + make $past; +} + method expression($/) { my $past := PAST::Stmts.new( :node($/) ); for $<assignment_expression> { @@ -401,7 +409,6 @@ make $past; } -####### method lhs_expression($/, $key) { make $( $/{$key} ); } @@ -410,11 +417,14 @@ my $member := $( $<member> ); if $<arguments> { # $<member> is the invocant - my $past := PAST::Op.new( $member, :pasttype('call'), :node($/) ); - my @args := $<arguments><assignment_expression>; - for @args { - $past.push( $($_) ); - } + ##my $past := PAST::Op.new( $member, :pasttype('call'), :node($/) ); + ##my @args := $<arguments><assignment_expression>; + ##for @args { + ## $past.push( $($_) ); + ##} + my $past := $( $<arguments> ); + # set $member as the first child which implies it's the invocant. + $past.unshift($member); make $past; } else { @@ -422,8 +432,6 @@ } } - - method member($/) { my $past; if $<primary_expression> { @@ -434,8 +442,10 @@ } for $<index> { + # XXX check this. my $idx := $( $_ ); - # XXX apply index on current $past + $idx.unshift($past); + $past := $idx; } make $past; @@ -446,7 +456,11 @@ } method new_expression($/) { - make $( $<member_expression> ); + my $past := $( $<member_expression> ); + for $<sym> { + $past := PAST::Op.new( $past, :name('new'), :pasttype('call'), :node($/) ); + } + make $past; } method identifier($/) { Modified: trunk/languages/ecmascript/src/parser/grammar.pg ============================================================================== --- trunk/languages/ecmascript/src/parser/grammar.pg (original) +++ trunk/languages/ecmascript/src/parser/grammar.pg Sat Jan 26 09:52:08 2008 @@ -216,10 +216,11 @@ rule arguments { '(' [ <assignment_expression> [',' <assignment_expression>]* ]? ')' + {*} } rule primary_expression { - #| 'this' {*} #= this + | <this> {*} #= this | <literal> {*} #= literal | <array_literal> {*} #= array_literal | <identifier> {*} #= identifier @@ -227,6 +228,7 @@ | '(' <expression> ')' {*} #= expression } +token this { 'this' {*} } rule array_literal { '[' @@ -501,18 +503,18 @@ } rule lhs_expression { - | <new_expression> {*} #= new_expression | <call_expression> {*} #= call_expression + | <new_expression> {*} #= new_expression } rule new_expression { - [new]* <member_expression> + [$<sym>='new']* <member_expression> {*} } rule member_expression { - [ <member> {*} - | 'new' <member> <arguments> + [ 'new' <member> <arguments> + | <member> ] {*} }