#
# Compiler.pm
#
# Copyright (C) 2002-2005, The Perl Foundation.
# This program is free software. It is subject to the same license
# as the Parrot interpreter.
#
# $Id: Compiler.pm 16255 2006-12-25 22:20:28Z paultcochrane $
#
use strict;
use warnings;
package Jako::Compiler;
use Carp;
use FileHandle;
use base qw(Jako::Processor);
#
# block_label()
#
sub block_label {
my $self = shift;
my ($kind) = @_;
return sprintf( "_%s_%d", uc $kind, ++$self->{BLOCK_COUNT} );
}
#
# temp_reg()
#
sub temp_reg {
my $self = shift;
my ($type) = @_;
$type = shift->code if ref $type;
return '$' . $type . $self->{REG_COUNT}{$type}++;
}
sub temp_int { return shift->temp_reg('I'); }
sub temp_num { return shift->temp_reg('N'); }
sub temp_pmc { return shift->temp_reg('P'); }
sub temp_str { return shift->temp_reg('S'); }
#
# anon_lbl()
#
my $anon_lbl_count = 0;
sub anon_lbl {
my $self = shift;
return '_ANON_LABEL_' . ++$self->{ANON_LBL_COUNT};
}
#
# invert_relop()
#
my %inverted_ops = (
'==' => '!=',
'!=' => '==',
'<=' => '>',
'<' => '>=',
'>=' => '<',
'>' => '<='
);
sub invert_relop {
my $self = shift;
my $op = shift;
confess "Undefined op!" unless defined $op;
my $new_op = $inverted_ops{$op};
confess "Unrecognized op '$op'!" unless defined $new_op;
return $new_op;
}
#
# new()
#
sub new {
my $class = shift;
return bless {
FILE => undef,
LINE => undef,
LABELS => [],
COMMENTS => [],
LAST_OP => 'noop',
INDENT => 0,
REG_COUNT => { 'I' => 0, 'N' => 0, 'P' => 0, 'S' => 0 },
ANON_LBL_COUNT => 0,
BLOCK_COUNT => 0
}, $class;
}
#
# indent()
#
sub indent {
my $self = shift;
$self->{INDENT} += 4;
}
#
# outdent()
#
sub outdent {
my $self = shift;
$self->{INDENT} -= 4;
confess "Unbalanced indent/outdent!" if $self->{INDENT} < 0;
}
#
# emit()
#
sub emit {
my $self = shift;
unshift( @_, " " x $self->{INDENT} );
my $fh = $self->{FH};
print $fh @_, "\n";
}
#
# compile()
#
sub compile {
my $self = shift;
my ( $root, $fh ) = @_;
$fh = FileHandle->new(">-") unless defined $fh;
$self->{FH} = $fh;
$root->compile($self);
}
1;
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4:
syntax highlighted by Code2HTML, v. 0.9.1