Snippets

avalak Lua Brainfuck

Created by avalak last modified

Пишем интерпретатор Brainfuck на Lua


Source code for

Пишем интерпретатор Brainfuck на Lua

#!/usr/bin/env lua5.3
-- Lua Brainfuck Interpreter
-- sudo apt install -y lua5.3

Brainfuck = {
  -- validate source
  -- Return 1 if closing bracket(s) missing.
  -- Return 2 if opening bracket(s) missing.
  -- Return 0 otherwise.
  validate = function (self, source)
    local i, errorCode, l = 0, 0, 0

    for i = 1, string.len(source), 1 do
        -- [ 91
        if string.byte(source, i) == 91 then
            l = l + 1
            -- ] 93
        elseif string.byte(source, i) == 93 then
            l = l - 1
            if l < 0 then return 2 end
        end
    end

    if l > 0 then
        return 1
    elseif l < 0 then
        return 2
    else
        return 0
    end
  end,


  -- debug function
  showError = function (self, errorCode)
    if errorCode == 1 then
        print("Error: Closing bracket(s) missing.")
    elseif errorCode == 2 then
        print("Error: Opening bracket(s) missing.")
    elseif errorCode == 3 then
        print("Error: No source file.")
    else
        print("Error: Unknown error code.")
    end
  end,

  -- brainfuck function
  brainfuck = function (self, source)
    -- memSize: Brainfuck memory size (30k)
    -- maxVal: Max memory value (255) byte
    -- mem: Memory table (array)
    -- pointer: default 0
    -- l: default 0. braket level counter
      local memSize, maxVal, mem, pointer, l = 30000, 255, {}, 0, 0

      -- clear memory
      for i = 0, memSize, 1 do mem[i] = 0 end

      -- execute program
      i = 0
      while i <= string.len(source) do
        i = i + 1
        -- + 43 C eqv ++(*p);
        if string.byte(source, i) == 43 then
          if mem[pointer] < maxVal then
              mem[pointer] = mem[pointer] + 1
          end

        -- - 45 C eqv --(*p);
        elseif string.byte(source, i) == 45 then
          if mem[pointer] > 0 then
              mem[pointer] = mem[pointer] - 1
          end

          -- , 44 C eqv *p = getchar();
        elseif string.byte(source, i) == 44 then
          mem[pointer] = string.byte(io.stdin:read('*l'), 1)

        -- . 46 C eqv putchar(*p);
        elseif string.byte(source, i) == 46 then
            io.write(string.char(mem[pointer]))

        -- < 60 C eqv --p;
        elseif string.byte(source, i) == 60 then
            pointer = pointer - 1
            if pointer < 0 then pointer = 0 end

        -- > 62 C eqv ++p;
        elseif string.byte(source, i) == 62 then
          pointer = pointer + 1
          if pointer > memSize then pointer = memSize end

        -- [ 91 C eqv while (*p) {
        elseif string.byte(source, i) == 91 then
          if mem[pointer] == 0 then
            while (string.byte(source, i) ~= 93) or (l > 0) do
              i = i + 1
              if string.byte(source, i) == 91 then l = l + 1 end
              if string.byte(source, i) == 93 then l = l - 1 end
            end
        end

        -- ] 93 C eqv }
        elseif string.byte(source, i) == 93 then
          if mem[pointer] ~= 0 then
            while (string.byte(source, i) ~= 91) or (l > 0) do
              i = i - 1
              if string.byte(source, i) == 91 then l = l - 1 end
              if string.byte(source, i) == 93 then l = l + 1 end
            end
          end
        else
          -- print("Unknown symbol")
          -- return
        end
        -- print("Debug: l="..l.." cmd="..string.char(string.byte(source, i)))
    end

  end,
}


-- start here
if arg[1] then
  -- read source from file in arg[1]
  source = io.input(arg[1]):read("*a")
  -- get error code (0 == no error)
  errorCode = Brainfuck:validate(source)
  -- if no error run source else show error
  if errorCode == 0 then
      Brainfuck:brainfuck(source)
  else
      Brainfuck:showError(errorCode)
  end
else
  print("Usage: ./brainfuck.lua script")
  Brainfuck:showError(3)
end
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.