4 # Copyright (C) 2002-2005, The Perl Foundation.
5 # This program is free software. It is subject to the same license
6 # as the Parrot interpreter.
14 package Jako
::Construct
::Statement
::Call
;
18 use base
qw(Jako::Construct::Statement);
22 my ( $block, $ident, @args ) = @_;
24 confess
( "Block (" . ref($block) . ") is not!" )
25 unless UNIVERSAL
::isa
( $block, 'Jako::Construct::Block' );
26 confess
( "Ident (" . ref($ident) . ") is not!" )
27 unless UNIVERSAL
::isa
( $ident, 'Jako::Construct::Expression::Value::Identifier' );
29 my $name = $ident->value;
42 $block->push_content($self);
47 sub name
{ return shift->{NAME
}; }
48 sub args
{ return @
{ shift->{ARGS
} }; }
58 my $name = $self->name;
60 # $self->DEBUG(0, "Searching for symbol '$name'...");
62 my $sym = $self->block->find_symbol($name);
64 $self->SYNTAX_ERROR( "Call to unknown sub '%s'.", $name ) unless $sym;
66 my %props = $sym->props;
68 my @args = $self->args;
70 my @formal_args = $sym->args;
72 $self->SYNTAX_ERROR( "Wrong number of arguments (expected %d, got %d) in call to '%s'.",
73 scalar(@formal_args), scalar(@args), $name )
74 unless @formal_args == @args;
76 for ( my $i = 0 ; $i < @args ; $i++ ) {
77 my ( $formal_arg_type, $formal_arg_name ) = @
{ $formal_args[$i] };
80 if ( UNIVERSAL
::isa
( $args[$i], 'Jako::Construct::Expression::Value::Identifier' ) ) {
81 my $arg_sym = $self->block->find_symbol( $args[$i]->value );
82 $self->SYNTAX_ERROR( "Undefined identifier '%s'.", $args[$i]->value ) unless $arg_sym;
83 $actual_arg_type = $arg_sym->type;
86 $actual_arg_type = $args[$i]->type;
89 $self->INTERNAL_ERROR( "Can't determine type of formal argument (%s)!", $formal_arg_name )
90 unless defined $formal_arg_type;
92 $self->INTERNAL_ERROR( "Can't determine type of actual argument (%s)!", ref $args[$i] )
93 unless defined $actual_arg_type;
95 if ( $formal_arg_type->name ne $actual_arg_type->name ) {
96 my $temp = $compiler->temp_reg($formal_arg_type);
97 my $value = $args[$i]->compile($compiler);
98 $compiler->emit(" $temp = $value");
102 $args[$i] = $args[$i]->compile($compiler);
106 if ( exists $props{op
} ) {
109 # $self->DEBUG(0, "Calling %s%s...", $name, ($op ? ' (op $op)' : ' as op'));
113 $name =~ s/(^"|"$)//g;
116 $name =~ s/^.*:://; # Strip namespaces off ops.
118 $compiler->emit( " $name ", join( ", ", @args ) );
122 # $self->DEBUG(0, "Calling '%s' as regular or NCI sub (props = %s)...", $name, join(", ", %props));
126 if ( exists $props{fn
} or exists $props{fnlib
} ) {
130 $compiler->emit( " _${name}(" . join( ", ", @args ) . ")" );
144 $handler->start_element( { Name
=> 'call', Attributes
=> { name
=> $self->name } } );
145 $_->sax($handler) foreach $self->args;
146 $handler->end_element( { Name
=> 'call' } );
153 # cperl-indent-level: 4
156 # vim: expandtab shiftwidth=4: