Search

Affichage des articles dont le libellé est fetch. Afficher tous les articles
Affichage des articles dont le libellé est fetch. Afficher tous les articles

mercredi 8 février 2017

Self-interpreter: inactive and direction flags (8)

Context

As a reminder, here is the final memory map
0 0 0 {instrs} 0 inst_ptr 0 0 0 inactive_flag direction_flag memory_ptr  0 0 0 0 0 {mem}
Let's now see how to handle inactive_flag and direction_flag
  • Inactive_flag: when not null, execution of instructions should be suspended, only '[' and ']' will taken into account.
  • While will increase the inactive_flag and if null update direction_flag.
  • Loop will decrease the inactive_flag

Initial state

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

Process

  • Set else bit
  • If inactive flag is not null
    • Reset else bit  
    • Check if instruction is ]
      • Decrease inactive flag
    • If not, check if it is [
      • Increase inactive flag
      • If inactive flag is null, reset direction flag
    • If not, ignore instruction
  • If not null: process instruction normally 
Update instruction pointer: instead of  moving to next instruction, we need to check if direction_flag is not null (go back) or not (go forward). An easier way to do that is to go back to steps back if direction flag is not null, and then go one step forward in all cases.

Code snippet for inactive case

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
  +>>-
]
<[-<]
+<
[
 
and continue

Code snippet for instruction pointer update

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

Self-interpreter: fetch instructions (3)

Context

Now that our instructions are read correctly, let's implement a fetch loop.
Given an instruction pointer, the fetch is an operation that gives us the operation to implement.
This is globally similar to a random access in array, but the fetch loop should be executed again and again. Then, it's simpler to ave a one-based index: we can loop on fetch pointer in this case.
And access an element in this case is not complex either, the pointer value just need to be decreased by a given offset

Initial state

  • Memory: 0, 0, 0, instructions, 0, IP
  • Cursor: on instruction pointer (initially 0)
  • Input: any

Process

  • Set pointer to 1
  • While pointer is not null
    • Decrease pointer
    • Copy pointer
    • Use pointer copy to get instruction
    • Copy current instruction outside array - the instruction copy will be placed just beside the instruction pointer cell
    • If instruction is not null
      • For test purposes: rebuild original value and print it. This part will be later replaced by instruction processing, of course
      • Increase pointer back to original value
      • Increase pointer (move to next instruction)
    • Otherwise, break the loop

    Code 

    fetch loop
    +[
      get current instruction
      -[->+>+<<]>>[-<<+>>]<[-<<<[<]>[-<<+>>]>[>]>>]<<<[<]>[-<+<+>>]<[->>[>]>>+<<<[<]<]<[->>+<<]<[[->>+<<]<]>>>[>]>>

      parse current instruction
      >+<[>-<
        rebuild and print (test)
        >+++++[-<+++++++>]<.[-]
        increment instruction counter
        <++>
      ]>[-<<[-]>>]<
    <]

    Code (minified)

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

    Final state

    • Memory: 0,instructions, 0, IP
    • Cursor: on IP
    • Input: unchanged
    • Output: unchanged (except for test purposes)
    Note: when direction_flag will be available, the <++> line will be replaced by
        increment or decrement based on direction_flag

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

    Example

    Live 'Instruction reader / fetcher / printer' example, that reads code to execute until it reaches separator, then display the code using the fetch loop.

    Back to previous step
    Go to next step