Snippets
Created by
avalak
last modified
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #!/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)
You can clone a snippet to your computer for local editing. Learn more.