package Language::Zcode::Translator::Generic; use strict; use warnings; =head1 NAME Language::Zcode::Translator::Generic =head1 DESCRIPTION Abstract class that's the parent of all language-specific translators. A translator has methods to translate Z-code into a given other language. =head2 Methods (Implement all of these to have a valid language translator.) =head3 program_start Returns a string that should be at the beginning of the output program. (Empty by default) =head3 program_end Returns a string that should be at the end of the output program. (Empty by default) =cut sub program_start { "" } sub program_end { "" } =head3 routine_start Returns a string that should be at the beginning of each output subroutine. Might have side effects (e.g., tell translator to start indenting). Input: Name of sub, array of initial local variable values (all 0 for v5+) =head3 translate_command(command_hashref) This is the translation workhorse. Translate a command (a reference to a hash returned by a LZ::Parser::parse routine) to the destination language. =head3 routine_end Returns a string that should be at the end of each output subroutine. Might have side effects (e.g., tell translator to stop indenting). =head3 packed_address_str(address, type_of_address) String representing a version-dependent packed address. (Note packing is different for routines and strings in V6/7.) Calculate actual address if $address is a number. Create a language-dependent multiplication string by calling language-dependent mult_add_str otherwise. =cut sub library { "" } sub packed_address_str { my ($self, $address, $key) = @_; my %c = %Language::Zcode::Util::Constants; my $mult = $c{packed_multiplier}; my $add; # (Add will be zero for versions not 6 or 7) if ($key eq "routine") { $add = 8 * $c{routines_offset}; } elsif ($key eq "packed_address_of_string") { $add = 8 * $c{strings_offset}; } else { die "Unknown key $key to packed_address_str" } # Now actually create the string. Only do calculation for true number if ($address =~ /^\d+$/) { # if ($address =~ /^(sp|local\d+|g[a-f\d]{2})$/) { return $mult * $address + $add; } else { return $self->mult_add_str($address, $mult, $add); } } =head3 mult_add_str(thing, multiplier, adder) Create a language-dependent multiplication/addition string thing*multiplier + adder =cut sub mult_add_str { my ($self, $thing, $mult, $add) = @_; # works for Perl, C, BASIC, java... return $add ? "$thing * $mult + $add" : "$thing * $mult"; } sub AUTOLOAD { die "Tried to call $Plotz::Translator::Generic::AUTOLOAD for abstract class!"} sub DESTROY {1} # make AUTOLOAD happy # end package Plotz::Translator::Generic 1;