develooper Front page | perl.perl6.internals | Postings from December 2001

First cut of pyc2pasm

From:
Simon Cozens
Date:
December 16, 2001 04:12
Subject:
First cut of pyc2pasm
Message ID:
20011216121401.GA7469@netthink.co.uk
I've started on this, but I don't really have much time to work on
it any further. If anyone wants to take over, have fun. It translates
Python bytecode into Parrot assembler.

#!/usr/bin/perl

use Python::Bytecode;
my @p_registers = ("topstack");
my @free_list;

open IN, shift or die "Can't open file\n";
my $bytecode = Python::Bytecode->new(\*IN);

my $topstack = undef;
for ($bytecode->disassemble) {
    my $nameop = Python::Bytecode::opname($_->[1]);
    print "#\t\t\t\t$_->[0]\n";
    &{"emit_$nameop"}($_);
    print "\n";
}

sub emit_SET_LINENO { print "\tset I31, $_[0]->[2]" }
sub emit_LOAD_CONST {
    # OK, what's the constant?
    my $const_index = $_[0]->[2];
    my $constant = $bytecode->constants->[$const_index];
    my $type = ref $constant;
    $constant = $$constant;
    $type =~ s/Python::Bytecode::/Python/;
    $constant = "'$constant'" if $type eq "PythonString";
    my $reg = topstack($type);
    print "\tset P$reg, $constant" unless $type eq "PythonUndef";
}

sub emit_STORE_NAME {
    my $name_index = $_[0]->[2];
    my $name = $bytecode->names->[$name_index];
    my $register = symtab_entry($name);
    print "\tset P$register, P",topstack();
}

sub emit_LOAD_NAME {
    my $name_index = $_[0]->[2];
    my $name = $bytecode->names->[$name_index];
    my $register = symtab_entry($name);
    print "\tset P",topstack(),", P$register";
}

sub emit_PRINT_ITEM { print "\tprint P",topstack() }
sub emit_PRINT_NEWLINE { print "\tprint '\\n'" }
sub emit_RETURN_VALUE { print "\tend"; }

sub topstack {
    my $type = shift;
    if (not defined $topstack or ($type and $topstack->[1] ne $type)) {
        $topstack = [reg_alloc($type), $type];
    }
    return $topstack->[0];
}

sub reg_alloc {
    my $type = shift;
    if (@free_list) {
        return pop @free_list
    }
    my $reg = ++$#p_registers;
    die "Register allocation error\n" if $reg > 32;
    print "\tnew P$reg, $type\n";
    return $reg;
}

sub reg_free {
    push @free_list, shift;
}

my %sym_tab;

sub symtab_entry {
    my $name = shift;
    if (not exists $sym_tab{$name}) {
        my $register = reg_alloc("PythonInteger"); # XXX Wrong
        $sym_tab{$name} = $register;
        $p_registers[$register] = $name;
        return $register;
    }
    return $sym_tab{$name};
}

-- 
teco < /dev/audio
    - Ignatios Souvatzis



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About