Search

mercredi 8 février 2017

Self-interpreter: completed (9)

Context

We now have all our pieces in place. Let's run our interpreter !

Initial state

  • Memory: empty
  • Cursor: on first cell
  • Input: code to execute#input of interpreted program

Code (minified - only 1137 instructions)

>>>,[>+++++[-<------->]+<[>,>]>[[-]>]<<]>+[-[->+>+<<]>>[-<<+
>>]<[-<<<[<]>[-<<+>>]>[>]>>]<<<[<]>[-<+<+>>]<[->>[>]>>+<<<[<
]<]<[->>+<<]<[[->>+<<]<]>>>[>]>>>+<[>->+>[<<++++++++[-<-----
-->]+<[--[>-<[-]]>[->>-<<]<]>[->>+[<-]<[>>[-]<<-<]>+<]<+>>-]
<[-<]+<[--------[-[-[-[>+[-<------->]+<[--[>+++[-<------->]+
<-[--[>-<[-]]>[->>>>[->+>+<<]>>[-<<+>>]<+[->>>>[>>]+>>[-]>[-
<<+>>]<<<[<<]<<]>>>>[>>]<[->>+<<]>>[-<<+<[<<]<<+>>>>[>>]>]<<
<[[->>+<<]>[->>+<<]<<<]<<[[-]<<<->[-]+>>]<<<<<]<]>[->>>>[->+
>+<<]>>[-<<+>>]<+[->>>>[>>]+>>[-]>[-<<+>>]<<<[<<]<<]>>>>[>>]
<[->>+<<]>>[-<<+<[<<]<<+>>>>[>>]>]<<<[[->>+<<]>[->>+<<]<<<]<
+<[>-<[-]]>[-<<<<+>>>>]<<<<<<]<]>[->>>>+<<<<]<]>[->>>>-<<<<]
<]>[->>>>[->+>+<<]>>[-<<+>>]<+[->>>>[>>]+>>[-]>[-<<+>>]<<<[<
<]<<]>>>>[>>]<.<[[->>+<<]>[->>+<<]<<<]<<<<<<<]<]>[->>>>[->+>
+<<]>>[-<<+>>]<+[->>>>[>>]+>>[-]>[-<<+>>]<<<[<<]<<]>>>>[>>]<
-<[[->>+<<]>[->>+<<]<<<]<<<<<<<]<]>[->>>>[->+>+<<]>>[-<<+>>]
<+[->>>>[>>]+>>[-]>[-<<+>>]<<<[<<]<<]>>>>[>>]<,<[[->>+<<]>[-
>>+<<]<<<]<<<<<<<]<]>[->>>>[->+>+<<]>>[-<<+>>]<+[->>>>[>>]+>
>[-]>[-<<+>>]<<<[<<]<<]>>>>[>>]<+<[[->>+<<]>[->>+<<]<<<]<<<<
<<<]>>>[-<<+<<<-->>>>>]<<[->>+<<]<<<++>]]>[[-]<<[-]>>]<<]

Code - with comments, character codes and memory map

separator 35/0
inc 43/8
read 44/9
dec 45/10
print 46/11
left 60/25
right 62/27
while 91/56
loop 93/58


0 0 0 {instructions} 0 IP current bit_else 0 inactive_flag direction_flag memory_pointer MPcopy/read_value 0 0 0 0 0 {memory}

>>>,[>+++++[-<------->]+<[>,>]>[[-]>]<<]>
+[
  -[->+>+<<]>>[-<<+>>]<[-<<<[<]>[-<<+>>]>[>]>>]<<<[<]>[-<+<+>>]<[->>[>]>>+<<<[<]<]<[->>+<<]<[[->>+<<]<]>>>[>]>>

  parse current instruction
  >+<[>->+>
  [
    check if instruction is while (increase flag) or loop (decrease flag)
    <<++++++++[-<------->]+<
    [
      --
      [>-<
        clear instruction read
        [-]
      ]>[-
        instruction: loop
        decrease inactive_flag
        >>-<<
      ]<
    ]>[-
      instruction: while
      increase inactive_flag
      >>+
   
      if inactive_flag = 0 then reset direction_flag
      [<-]<[>>[-]<<-<]>+
      <
    ]<
    set instruction read to 1 to consider it as a non instruction
    +>>-
  ]
  <[-<]
  +<
  [
    --------
    [
      -
      [
        -
        [
          -
          [
            >+[-<------->]+<
            [
              --
              [
                >+++[-<------->]+<-
                [
                  --
                  [
                    not an instruction
                    >-<[-]
                  ]>[-
                    instruction: loop
                  duplicate memory pointer and move to copy
                  >>>>[->+>+<<]>>[-<<+>>]<+
                  [
                    -
                    go to next memory cell
                    >>>>[>>]+>>
                    (re)init/copy memory indicator
                    [-]>[-<<+>>]<<<[<<]<<
                  ]
                  go to current memory cell and copy value
                  >>>>[>>]<[->>+<<]>>[-<<+<[<<]<<+>>>>[>>]>]<<
                  move array back to initial position
                  <[[->>+<<]>[->>+<<]<<<]
                  <<
                  check current memory value: do nothing if null and move to corresponding while otherwise
                  [
                    if not null (current position: next to memory_pointer)
                    reset value
                    [-]
                    decrease inactive_flag and change direction_flag
                    <<<->[-]+>>
                  ]
                  <<<<<
                  ]<
                ]>[-
                  instruction: while
                  duplicate memory pointer and move to copy
                  >>>>[->+>+<<]>>[-<<+>>]<+
                  [
                    -
                    go to next memory cell
                    >>>>[>>]+>>
                    (re)init/copy memory indicator
                    [-]>[-<<+>>]<<<[<<]<<
                  ]
                  go to current memory cell and copy value
                  >>>>[>>]<[->>+<<]>>[-<<+<[<<]<<+>>>>[>>]>]<<
                  move array back to initial position
                  <[[->>+<<]>[->>+<<]<<<]
                  check current memory value: do nothing if not null and move to corresponding loop otherwise
                  <+<[>-<[-]]>[-<
                    if null (current position: next to memory_pointer)
                    increase inactive_flag
                    <<<+>>>
                  >]<
                  <<<<<
                ]<
              ]>[-
                instruction: right
                >>>>+<<<<
              ]<
            ]>[-
              instruction: left
              >>>>-<<<<
            ]<
          ]>[-
            instruction: print
            duplicate memory pointer and move to copy
            >>>>[->+>+<<]>>[-<<+>>]<+
            [
              -
              go to next memory cell
              >>>>[>>]+>>
              (re)init/copy memory indicator
              [-]>[-<<+>>]<<<[<<]<<
            ]
            go to current memory cell and print value
            >>>>[>>]<.
            move array back to initial position
            <[[->>+<<]>[->>+<<]<<<]
            <<<<<<<
          ]<
        ]>[-
          instruction: dec
          duplicate memory pointer and move to copy
          >>>>[->+>+<<]>>[-<<+>>]<+
          [
            -
            go to next memory cell
            >>>>[>>]+>>
            (re)init/copy memory indicator
            [-]>[-<<+>>]<<<[<<]<<
          ]
          go to current memory cell and decrease value
          >>>>[>>]<-
          move array back to initial position
          <[[->>+<<]>[->>+<<]<<<]
          <<<<<<<
        ]<
      ]>[-
        instruction: read

        duplicate memory pointer and move to copy
        >>>>[->+>+<<]>>[-<<+>>]<+
        [
          -
          go to next memory cell
          >>>>[>>]+>>
          (re)init/copy memory indicator
          [-]>[-<<+>>]<<<[<<]<<
        ]
        go to current memory cell and read value
        >>>>[>>]<,
        move array back to initial position
        <[[->>+<<]>[->>+<<]<<<]
        <<<<<<<
      ]<
    ]>[-
      instruction: inc
      duplicate memory pointer and move to copy
      >>>>[->+>+<<]>>[-<<+>>]<+
      [
        -
        go to next memory cell
        >>>>[>>]+>>
        (re)init/copy memory indicator
        [-]>[-<<+>>]<<<[<<]<<
      ]
      go to current memory cell and increase value
      >>>>[>>]<+
      move array back to initial position
      <[[->>+<<]>[->>+<<]<<<]
      <<<<<<<
    ]<
    increase or decrease instruction counter based on direction_flag
    >>>>[-<<+<<<-->>>>>]<<[->>+<<]<<<++>
  ]]>[[-]<<[-]>>]<
<]

Final state

  • Memory: see above
  • Cursor: on instruction, next to inst_ptr
  • Input: unchanged
  • Output: unchanged

Example

Live BF Interpreter.
Be careful not to execute too long code: one single BrainFuck operation to interpret is rather long (parsing, processing, ...)
Here is a quick code sample. With an input H, it prints HELLO WORLD. You can use this code to test interpreter. input will be:
,.---.>+++[-<++>]<+..+++.>++++[->++[->++++<]<]>>.<<<[->+>+<<]++[->++++<]>.>.+++.<<++[->-----<]>-.<++[->----<]>.#H
Note: the code above can be executed directly through less than 850 operations (849 exactly).
The interpreted version can be executed in 65.622.379 operations !!!
This gives an average ratio of 77.924 operations to execute one instruction.
This ratio is definitely not accurate, as operations are also used to read program, or in inactive mode, ... but it's still a good indicator of execution complexity.


Back to previous step
Go to next step (next step ? really ? I said it works, didn't I?)

Aucun commentaire:

Enregistrer un commentaire