Search

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

mercredi 1 mars 2017

Calc tool

Context

Let's implement a calculation tool. Inputs will be operations as [operand 1][operator][operand 2] and output will be the operation with its result

Initial state

  • Memory: empty
  • Cursor: first cell
  • Input: an operation [operand][operator][operand] where operatands are numbers in base 10, and operator one of + - * /

Process

  • Read input - memory after reading should be operand operator_flag operand 0 0 0 0 ....
    • Print char (faster than rebuilding it afterwards)
    • Use a switch/case
      • If it's a *, set operator flag to 0 (do nothing) and start reading a new integer
      • Same for +, - and * but set operator flag to 1, 2 or 3
      • Otherwise, it's a digit: build integer
        • multiply previously read integer by 10
        • add the new digit
  • Move operator to have operand 0 operand operator flag switch_flag
  • Set switch_flag to 1 and use another switch/case
    • Flag is 0: multiply numbers and store result in second cell
    • Flag is 1 or 2: same, but sums up or subtract numbers
    • Flag is 3: move operand 2, then perform division
  • Display = symbol
  • Display result
    • If it's 0, then display '0'
    • Otherwise, display the computed integer

Code - try it

Codes:
Multpily 42
Add 43
Subtract 45
Divide 47

>,[
  print char
  .
  subtract 42
  >++++++[-<------->]+<
  [
    not a multiplication
    -
    [
      not an addition
      --
      [
        not a subtraction
        --
        [
          not a division
          this is a digit
          build number
          ->++++++++[-<<[->+>>+<<<]>>>[-<<<+>>>]<]<[-<+>]
        ]>[-
          this is a division
          set operation flag to 3 and start new number
          <+++>>>
        ]<
      ]>[-
        this is a subtraction
        set operation flag to 2 and start new number
        <++>>>
      ]<
    ]>[-
      this is an addition
      set operation flag to 2 and start new number
      <+>>>
    ]<
  ]>[-
    this is a multiplication
    start new number
    >>
  ]
  read next char
  <,
]
move operator
<<[->>+<<]>>
>+<[
  not a multiplication
  -
  [
    not an addition
    -
    [->-<
      division
      move operand 2
      <[->>+<<]
      divide
      <<[->+>>+>-[<-]<[->>+<<<<[->>>+<<<]>]<<]
      clear and move result
      >[-]>>>[-]>[-<<<<+>>>>]<<
    ]>[-
      subtraction
      <<<<[->+<]>>[-<->]>>
    ]<
  ]>[-
    addition
    <<[-<+>]<<[->+<]>>>>
  ]<
]>[-
  multiplication
  <<<<[->>[-<+>>+<]>[-<+>]<<<]
  clean operands
  >>[-]>>
]

print =
+++++++++[-<+++++++>]<--.[-]

<+<[>-<
  print result if not 0
  [>>>>++++++++++<<<<[->+>>+>-[<-]<[->>+<<<<[->>>+<<<]>]<<]>+[-<+>]>>>[-]>[-<<<<+>>>>]<<<<]<[>++++++[<++++++++>-]<-.[-]<]
]>[
  or print 0
  +++++++[-<++++++>]<.[-]
]

Final state

  • Memory: empty
  • Cursor: second cell
  • Input: empty
  • Output: the operation followed by equal sign and its result
Note: of course, this is a calc tool valid in the Z/256Z group, meaning that all inputs and results are taken modulo 256. Moreover, the division is actually an euclidean division, so result is not displayed completely (only the quotient is)

mercredi 8 février 2017

Self-interpreter: switch on instruction code (4)

Context

Implementing a switch in BrainFuck is not that complex: case values should be sorted (a bit easier to implement), and then
  1. Set else bit to 1
  2. Decrease the switch condition by first case value
    1. If not null, continue with other values
    2. If null, go to else bit, reset and process
  3. Finally, go to else bit and process the default case

Initial state

  • Memory: 0, 0, 0, instructions, 0, IP, instruction
  • Cursor: on instruction
  • Input: any

Process

  • Set else bit to 1
  • Execute the switch
    • Decrease current condition with total decrease (since beginning) equals to the current case
    • Value is not null: process next case
    • Value is null: process current case, reset else bit
The global syntax looks like
[
  set else bit
  >+<
  decrease condition
  [
    next case : decrease condition
    ...
  ]>[- reset else bit
    current case implementation
  ]<
]

Note: for test purposes, the current instruction processing will be a simple display on output of the current instruction, and reset. Non-instruction characters will be simply ignored

Code 

  parse current instruction
  [
    >+<--------
    [
      -
      [
        -
        [
          -
          [
            >+[-<------->]+<
            [
              --
              [
                >+++[-<------->]+<-
                [
                  --
                  [
                    not an instruction
                    >-<[-]
                  ]>[-
                    instruction: loop
                    +++++++++[-<++++++++++>]<+++.[-]>
                  ]<
                ]>[-
                  instruction: while
                  +++++++++[-<++++++++++>]<+.[-]>
                ]<
              ]>[-
                instruction: right
                ++++++++[-<++++++++>]<--.[-]>
              ]<
            ]>[-
              instruction: left
              ++++++++[-<++++++++>]<----.[-]>
            ]<
          ]>[-
            instruction: print
            ++++++[-<+++++++>]<++++.[-]>
          ]<
        ]>[-
          instruction: dec
          ++++++[-<+++++++>]<+++.[-]>
        ]<
      ]>[-
        instruction: read
        ++++++[-<+++++++>]<++.[-]>
      ]<
    ]>[-
      instruction: inc
      ++++++[-<+++++++>]<+.[-]>
    ]<

Code (minified)

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

Final state

  • Memory: 0,instructions, 0, IP, 0
  • Cursor: on last 0
  • Input: unchanged
  • Output: unchanged (except for test purposes)
Note: the root switch will be modified in the future, to take incative_flag into account

Example

Live 'Instruction read / fetch / switch / print' example, that reads code to execute until it reaches separator, then use the fetch loop to get instructions, switch on different instructions, then display instructions using fetch loop. By the way, it's also a nice 'BrainFuck code minifier' - implemented in BrainFuck!

Back to previous step
Go to next step