#!/usr/bin/perl
use strict;
use warnings;
#use Data::Dumper;

die "No File as input!" if (!$ARGV[0] or !-f $ARGV[0]);
die "Incorrect input string" if ($ARGV[1] and $ARGV[1] !~ /^\s*\w+\s*$/ );

my %table;
my %states;
my $maxStates = 100;
my $sr;     # The State Register
my $tape="_________";   # The Tape
my $head;   # The Head;
my $curVal;
my $newVal;
my $dir;

$tape = $ARGV[1] if ($ARGV[1]);

initTable();
$tape = '_'. $tape;
$head=1;

while(1)
{
 $curVal=substr($tape,$head,1);
 ($sr, $newVal, $dir) = @{$table{$sr}{$curVal}} if ($table{$sr}{$curVal}) or
 ( $tape =~ s/^_*(.*)$/$1/ and $tape =~ s/^(\w*?)_*$/$1/ and print
$tape."\n" and exit);
 substr($tape,$head,1,$newVal);
 $head += 1 if ($dir eq 'R');
 appendRight() if (! substr($tape,$head,1));
 $head -= 1 if ($dir eq 'L');
 appendLeft() if ($head <= 0);
}

sub initTable
{

 open(FH, "<$ARGV[0]") or die "Could not open tm file $ARGV[0] : $!";
 my @lines = <FH>;
 close (FH) or die "Could not close tm file $ARGV[0] : $!";
 my $stateCnt = 1;

 for (@lines)
 {
   chomp $_;
   (print "skipped $_ \n" && next) if (/^\s*$/ || /^\s*#.*/ );
   die "Incorrect file format: line $_"
         if (! /^\s*(\w+)\s+(\w)\s+(\w+)\s+(\w)\s+([LR])\s*.*$/i);
   $states{$1} = $stateCnt++ if (!$states{$1});
   $sr=$states{$1}  unless($sr);
   $states{$3} = $stateCnt++ if (!$states{$3});
   $table{$states{$1}}{$2} = [$states{$3},$4,uc($5)] if (!
$table{$states{$1}}{$2}) or
           die "More than 1 rule for same state/input" ;
 }
#print Dumper(\%table);
}

sub appendLeft
{
$tape="_" x 10 . $tape;
$head += 10;
}

sub appendRight
{
$tape .= "_" x 10;
}
