snuspi.pl 1.5 KB

1234567891011121314151617181920212223242526272829303132333435
  1. #!/usr/bin/perl
  2. # A Modular SNUSP Interpreter
  3. # Copyright (C) 2004 Rick Klement
  4. use strict;
  5. my ($dy, $p, $dir, $run, $code, @data, @stack, $op) = (1, 0, 1, 1, '', 0);
  6. $code .= $_, $dy < 2 + length and $dy = 2 + length while <STDIN>;
  7. $code =~ s/^.*/$& . ' ' x ($dy - 2 - length $&) . "\n"/gem;
  8. my $ip = index $code, '$'; # find first $ or first char
  9. $ip = 0 if $ip < 0;
  10. my %instructions = (
  11. '>' => sub { ++$p }, # RIGHT
  12. '<' => sub { $run-- if --$p < 0 }, # LEFT
  13. '+' => sub { ++$data[$p] }, # INCR
  14. '-' => sub { --$data[$p] }, # DECR
  15. ',' => sub { $data[$p] = ord shift @ARGV }, # READ
  16. '.' => sub { print chr $data[$p], "\n" }, # WRITE
  17. '/' => sub { $dir = abs $dir == 1 ? -$dy * $dir : $dir / -$dy}, # RULD
  18. '\\' => sub { $dir = abs $dir == 1 ? $dy * $dir : $dir / $dy}, # LURD
  19. '!' => sub { $ip += $dir }, # SKIP
  20. '?' => sub { $ip += $dir unless $data[$p] }, # SKIPZ
  21. '@' => sub { push @stack, [ $ip + $dir, $dir ] }, # ENTER
  22. '#' => sub { @stack ? ($ip, $dir) = @{pop @stack} : $run-- }, # LEAVE
  23. "\n" => sub { $run-- }); # STOP
  24. while($run and $ip >= 0 and $ip < length $code)
  25. {
  26. $op = $instructions{my $ch = substr $code, $ip, 1} and &$op;
  27. #print "op: $ch (@data)[$p]\n"; # uncomment for trace
  28. $ip += $dir;
  29. }
  30. exit $data[$p];