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
::Expression
::Call
;
18 use base
qw(Jako::Construct::Expression);
22 my ( $block, $dest, $ident, @args ) = @_;
24 confess
( "Dest (" . ref($block) . ") not Identifer!" )
25 unless UNIVERSAL
::isa
( $dest, 'Jako::Construct::Expression::Value::Identifier' );
26 confess
( "Ident (" . ref($block) . ") not Identifer!" )
27 unless UNIVERSAL
::isa
( $ident, 'Jako::Construct::Expression::Value::Identifier' );
28 confess
( "Block (" . ref($block) . ") not!" )
29 unless UNIVERSAL
::isa
( $block, 'Jako::Construct::Block' );
43 $block->push_content($self);
48 sub dest
{ return shift->{DEST
}; }
49 sub name
{ return shift->{NAME
}; }
50 sub args
{ return @
{ shift->{ARGS
} }; }
60 my $dest_ident = $self->dest;
62 my $dest = $self->dest->value;
63 my $name = $self->name->value;
65 # $self->DEBUG(0, "Searching for symbol '$name'...");
67 my $sym = $self->block->find_symbol($name);
71 # $self->block->dump_symbols;
72 $self->SYNTAX_ERROR( "Call to unknown sub '%s'.", $name );
75 my %props = $sym->props;
77 my @args = $self->args;
79 my @formal_args = $sym->args;
81 $self->SYNTAX_ERROR( "Wrong number of arguments (expected %d, got %d) in call to '%s'.",
82 scalar(@formal_args), scalar(@args), $name )
83 unless @formal_args == @args;
85 for ( my $i = 0 ; $i < @args ; $i++ ) {
86 my ( $formal_arg_type, $formal_arg_name ) = @
{ $formal_args[$i] };
89 if ( UNIVERSAL
::isa
( $args[$i], 'Jako::Construct::Expression::Value::Identifier' ) ) {
90 my $arg_sym = $self->block->find_symbol( $args[$i]->value );
91 $self->SYNTAX_ERROR( "Undefined identifier '%s'.", $args[$i]->value ) unless $arg_sym;
92 $actual_arg_type = $arg_sym->type;
95 $actual_arg_type = $args[$i]->type;
98 $self->INTERNAL_ERROR( "Can't determine type of formal argument (%s)!", $formal_arg_name )
99 unless defined $formal_arg_type;
101 $self->INTERNAL_ERROR( "Can't determine type of actual argument (%s)!", ref $args[$i] )
102 unless defined $actual_arg_type;
104 if ( $formal_arg_type->name ne $actual_arg_type->name ) {
105 my $temp = $compiler->temp_reg($formal_arg_type);
106 my $value = $args[$i]->compile($compiler);
107 $compiler->emit(" $temp = $value");
111 $args[$i] = $args[$i]->compile($compiler);
115 if ( ( $dest_ident->kind eq 'var' ) and ( $dest_ident->scope eq 'global' ) ) {
116 $dest = $dest_ident->compile($compiler);
120 # For built-in subs (ops):
123 if ( exists $props{op
} ) {
126 # $self->DEBUG(0, "Calling %s%s...", $name, ($op ? ' (op $op)' : ' as op'));
128 $name = $op->value if defined $op;
129 $name =~ s/(^")|("$)//g; # Delete leading and trailing quotes;
131 $name =~ s/^.*:://; # Delete namespaces from ops
133 $compiler->emit( " $name ", join( ", ", $dest, @args ) );
137 # For regular (user-defined) and NCI (Native Call Interface) subs:
142 # $self->DEBUG(0, "Calling '%s' as regular sub (props = %s)...", $name, join(", ", %props));
146 if ( exists $props{fn
} or exists $props{fnlib
} ) {
150 $compiler->emit( " $dest = _${name}(" . join( ", ", @args ) . ")" );
153 if ( ( $dest_ident->kind eq 'var' ) and ( $dest_ident->scope eq 'global' ) ) {
154 my $pmc_type = $dest_ident->type->imcc_pmc();
155 my $temp_pmc = $compiler->temp_pmc();
157 $compiler->emit(" $temp_pmc = new '$pmc_type'");
158 $compiler->emit(" $temp_pmc = $dest");
160 my $dest_name = $dest_ident->value;
161 $compiler->emit(" global \"$dest_name\" = $temp_pmc");
175 $handler->start_element( { Name
=> 'assign' } );
176 $self->dest->sax($handler);
178 $handler->start_element( { Name
=> 'call', Attributes
=> { name
=> $self->name->value } } );
179 $_->sax($handler) foreach $self->args;
180 $handler->end_element( { Name
=> 'call' } );
182 $handler->end_element( { Name
=> 'assign' } );
189 # cperl-indent-level: 4
192 # vim: expandtab shiftwidth=4: