#! /usr/bin/perl use warnings; use strict; use Getopt::Std; our ($opt_g, $opt_v); getopts('gv'); undef $/; my $program = <>; $program =~ s/#.*$//g; # remove comments $program =~ s/\s//g; # remove whitespace $program =~ /^([acdftv]*)([bix])([01]*)/ or die "Syntax error"; my $cq = $1; my $mode = $2; my $dq = $3; my @cq = split //, $cq; my @dq = map 0+$_, split //, $dq; undef $cq; undef $dq; my %commands = ( 'ai' => sub { exit 0 unless scalar @dq; $mode = 0+shift(@dq) ? 'x' : 'b'; }, 'ci' => sub { $mode = 'x'; }, 'db' => sub { $mode = 'i'; }, 'dx' => sub { $mode = 'i'; }, 'fb' => sub {}, 'fx' => sub { push @dq, 0; }, 'tb' => sub {}, 'tx' => sub { push @dq, 1; }, 'vb' => sub {}, 'vx' => sub { @dq = map 1 - $_, @dq; } ); for (;;) { $opt_v || ($opt_g && $mode eq 'i') and print @cq, " ", $mode, " ", @dq, "\n"; my $c = shift @cq; my $cmd = $commands{$c.$mode}; unless ($cmd) { print STDERR "Invalid command '$c' in mode '$mode'\n"; exit 1; } $cmd->(); push @cq, $c; }