#! perl # Copyright (C) 2003-2007, The Perl Foundation. # $Id: compile.pl 21531 2007-09-24 16:48:27Z colink $ # Remember, this is BAD PERL later to be translated to PASM # First tokenize the input stream into: # @tokens and @tokdsc # Then compile. use Getopt::Std; use vars qw( @tokens @tokdsc); use vars qw(%code %options @basic %common); use vars qw( @syms @type ); use vars qw( %labels $runtime_jump $debug $sourceline); use COMP_toker; use COMP_parser; use COMP_assignments; use COMP_expressions; our @basic = (); $SIG{__DIE__} = sub { print "At BASIC source line $main::sourceline:\n"; $_ = $_[0]; s/^(.{1,50})(\S+)\s+(.*)/\t$1$2\n\t$3/; print; exit 1; }; getopts( 'd', \%options ); $debug = 1 if $options{d}; if (@ARGV) { open( D, '<', $ARGV[0] ) || die; @basic = ; chomp(@basic); seek D, 0, 0 or warn "Cannot reseek: $!"; } else { open( D, "<&", "DATA" ) || die; } shift(@ARGV); tokenize(); #push(@ARGV); parse(@ARGV); open( CODE, ">", "TARG_test.pir" ) || die; foreach my $seg ( "_main", "_basicmain", keys %code ) { next unless exists $code{$seg}; my @debdecl = (); my @init = (); print CODE ".sub $seg\n"; if ( exists $code{$seg}->{declarations} ) { print CODE <<'END_PIR'; .local pmc _GLOBALS .local string JUMPLABEL JUMPLABEL='' END_PIR foreach my $var ( sort keys %{ $code{$seg}->{declarations} } ) { if ( $var =~ /_string$/ ) { print CODE "\t.local string $var\n"; push @init, qq{\t\t$var=""\n}; push @debdecl, "\t\t\$P1[\"$var\"]=$var\n"; } else { print CODE "\t.local num $var\n"; push @init, qq{\t\t$var=0.0\n}; push @debdecl, "\t\t\$S0=$var\n\t\t\$P1[\"$var\"]= \$S0\n"; } } } #print CODE<{declarations} } ) { if ( exists $main::common{$var} ) { push( @saves, $var ); } } if (@saves) { print CODE qq{\t\t# Grab "COMMON" variables from global stash\n}; print CODE qq{\t\tfind_global _GLOBALS, "COMMON"\n}; foreach (@saves) { print CODE qq{\t\t$_=_GLOBALS["$_"]\n}; } } # Emit the code for the segment foreach ( @{ $code{$seg}->{code} } ) { s/#RTJ// if $runtime_jump; if (/#SAVECOMMON/) { @saves = (); $edit = ""; foreach my $var ( keys %{ $code{$seg}->{declarations} } ) { if ( exists $main::common{$var} ) { push( @saves, $var ); } } if (@saves) { $edit .= qq{\tfind_global _GLOBALS, "COMMON"\n}; foreach (@saves) { $edit .= qq{\t_GLOBALS["$_"]=$_\n}; } $edit .= qq{\tstore_global "COMMON", _GLOBALS\n}; } s/#SAVECOMMON/$edit/; } if (/#RESTORECOMMON/) { @saves = (); $edit = ""; foreach my $var ( keys %{ $code{$seg}->{declarations} } ) { if ( exists $main::common{$var} ) { push( @saves, $var ); } } if (@saves) { $edit .= qq{\tfind_global _GLOBALS, "COMMON"\n}; foreach (@saves) { $edit .= qq{\t$_=_GLOBALS["$_"]\n}; } } s/#RESTORECOMMON/$edit/; } s/^/\t/gm; print CODE; } # Put back all of the globals we've used in this sub @saves = (); foreach my $var ( keys %{ $code{$seg}->{declarations} } ) { if ( exists $main::common{$var} ) { push( @saves, $var ); } } if (@saves) { print CODE qq{\t\tfind_global _GLOBALS, "COMMON"\n}; foreach (@saves) { print CODE qq{\t_GLOBALS["$_"]=$_\n}; } print CODE qq{\t\tstore_global "COMMON", _GLOBALS\n\t}; } delete $code{$seg}; if ( !$debug ) { print CODE ".end\t# outer segment\n"; next; } print CODE<