{"id":77,"date":"2008-03-12T15:06:51","date_gmt":"2008-03-12T15:06:51","guid":{"rendered":"http:\/\/byteblog.internetallee.de\/?p=77"},"modified":"2008-03-12T15:06:51","modified_gmt":"2008-03-12T15:06:51","slug":"einfacher-interpreter-einer-einfachen-sprache","status":"publish","type":"post","link":"https:\/\/blogs.internetallee.de\/byteblog\/2008\/03\/12\/einfacher-interpreter-einer-einfachen-sprache\/","title":{"rendered":"Einfacher Interpreter einer einfachen Sprache"},"content":{"rendered":"<p>Nachdem J\u00f6rg mir ein paar Perl-B\u00fccher  geliehen hatte und schon seit l\u00e4ngerer Zeit das &#8222;Hello World!&#8220; Plakat  auf unserem stillen \u00d6rtchen h\u00e4ngt, musste ich mich einfach an einen  Brainfuck Interpreter versuchen.<\/p>\n<p>Und hier ist das Ergebnis:<\/p>\n<pre class=\"brush: perl;\">#!\/usr\/bin\/perl\n{\n  package BF;\n  use strict;\n  use warnings;\n\n  my @REGISTERS=('PP', 'MP', 'LOOP');\n  my %OPERATORS=(\n      '+' =&gt; sub {\n          my ($self) = @_;\n          return if $self-&gt;{_registers}{'LOOP'} &lt; 0;\n          $self-&gt;{_memory}[$self-&gt;{_registers}{'MP'}]++;\n          $self-&gt;{_registers}{'PP'}++;\n      },\n      '-' =&gt; sub {\n          my ($self) = @_;\n          return if $self-&gt;{_registers}{'LOOP'} &lt; 0;\n          $self-&gt;{_memory}[$self-&gt;{_registers}{'MP'}]--;\n          $self-&gt;{_registers}{'PP'}++;\n      },\n      '.' =&gt; sub {\n          my ($self) = @_;\n          return if $self-&gt;{_registers}{'LOOP'} &lt; 0;\n          push @{ $self-&gt;{_output} }, $self-&gt;{_memory}[$self-&gt;{_registers}{'MP'}];\n          $self-&gt;{_registers}{'PP'}++;\n      },\n      '&gt;' =&gt; sub {\n          my ($self) = @_;\n          return if $self-&gt;{_registers}{'LOOP'} &lt; 0;\n          $self-&gt;{_registers}{'MP'}++;\n          $self-&gt;{_registers}{'PP'}++;\n      },\n      '&lt;' =&gt; sub {\n          my ($self) = @_;\n          return if $self-&gt;{_registers}{'LOOP'} &lt; 0;\n          $self-&gt;{_registers}{'MP'}--;\n          $self-&gt;{_registers}{'PP'}++;\n      },\n      '[' =&gt; sub {\n          my ($self) = @_;\n          if ($self-&gt;{_memory}[$self-&gt;{_registers}{'MP'}] &gt; 0) {\n              push @{ $self-&gt;{_stack} }, $self-&gt;{_registers}{'PP'};\n          } else {\n              $self-&gt;{_registers}{'LOOP'}--;\n          }\n          $self-&gt;{_registers}{'PP'}++;\n          return;\n      },\n      ']' =&gt; sub {\n          my ($self) = @_;\n          my $loop_stacktart = pop @{ $self-&gt;{_stack} };\n          if ($self-&gt;{_memory}[$self-&gt;{_registers}{'MP'}]) {\n              $self-&gt;{_registers}{'PP'} = $loop_stacktart;\n          } else {\n              $self-&gt;{_registers}{'PP'}++;\n          }\n          $self-&gt;{_registers}{'LOOP'}++;\n      },\n  );\n\n  sub new {\n      my $class = shift;\n      my $data = {\n          _registers =&gt; { map { $_ =&gt; 0 } @REGISTERS },\n          _memory =&gt; [],\n          _stack =&gt; [],\n          _output =&gt; [],\n      };\n      bless $data, $class;\n  };\n\n  sub run {\n      my $self = shift;\n      while ($self-&gt;{_registers}{PP} &lt; $self-&gt;{_max_program_size}) {\n          my $op_char = $self-&gt;{_program}[$self-&gt;{_registers}{PP}];\n          my $op = $OPERATORS{$op_char};\n          $op-&gt;($self);\n      }\n  }\n\n  sub set_memory {\n      my ($self, $memory) = @_;\n      $self-&gt;{_program} = [ split \/\/, $memory ];\n      $self-&gt;{_max_program_size} = @{ $self-&gt;{_program} };\n  }\n\n  sub output {\n      my $self = shift;\n      return join ',', @{ $self-&gt;{_output} };\n  }\n\n  sub char_output {\n      my $self = shift;\n      return join '', map { chr($_) } @{ $self-&gt;{_output} };\n  }\n}\n\npackage main;\nuse strict;\nuse warnings;\n\nuse Test::More qw(no_plan);\n\nmy %test_data = (\n    '++.' =&gt; '2',\n    '++-.' =&gt; '1',\n    '++.&gt;+.&lt;+.' =&gt; '2,1,3',\n    '+++.[-.].' =&gt; '3,2,1,0,0',\n    '++.[-&gt;++[.-]&lt;]' =&gt; '2,2,1,2,1',\n    '++++++++++[&gt;+++++++&gt;++++++++++&gt;+++&gt;+&lt;&lt;&lt;&lt;-]&gt;++.&gt;+.+++++++..+++.&gt;++.&lt;&lt;+++++++++++++++.&gt;.+++.------.--------.&gt;+.&gt;.' =&gt; '72,101,108,108,111,32,87,111,114,108,100,33,10',\n);\nwhile (my ($prog, $exptected_output) = each %test_data) {\n    my $bf = BF-&gt;new();\n    $bf-&gt;set_memory($prog);\n    $bf-&gt;run();\n    is($bf-&gt;output(), $exptected_output, $prog);\n}\n\nmy $bf = BF-&gt;new();\n$bf-&gt;set_memory('++++++++++[&gt;+++++++&gt;++++++++++&gt;+++&gt;+&lt;&lt;&lt;&lt;-]&gt;++.&gt;+.+++++++..+++.&gt;++.&lt;&lt;+++++++++++++++.&gt;.+++.------.--------.&gt;+.&gt;.');\n$bf-&gt;run();\nis(\"Hello World!n\", $bf-&gt;char_output(), \"Hello World!\");\n<\/pre>\n<p>Eine tolle sinnlose Besch\u00e4ftigung.<\/p>\n<p>Und wen es interessiert: Das <a href=\"http:\/\/www.lob.de\/pdf\/helloworld.pdf\" target=\"_blank\">Plakat zum Programm<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nachdem J\u00f6rg mir ein paar Perl-B\u00fccher geliehen hatte und schon seit l\u00e4ngerer Zeit das &#8222;Hello World!&#8220; Plakat auf unserem stillen \u00d6rtchen h\u00e4ngt, musste ich mich einfach an einen Brainfuck Interpreter versuchen. Und hier ist das Ergebnis: #!\/usr\/bin\/perl { package BF; use strict; use warnings; my @REGISTERS=(&#8218;PP&#8216;, &#8218;MP&#8216;, &#8218;LOOP&#8216;); my %OPERATORS=( &#8218;+&#8216; =&gt; sub { my [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[34,27],"class_list":["post-77","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-perl","tag-sprachen"],"_links":{"self":[{"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/posts\/77","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/comments?post=77"}],"version-history":[{"count":0,"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/posts\/77\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/media?parent=77"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/categories?post=77"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.internetallee.de\/byteblog\/wp-json\/wp\/v2\/tags?post=77"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}