-
Notifications
You must be signed in to change notification settings - Fork 259
Expand file tree
/
Copy pathbf.lua
More file actions
109 lines (95 loc) · 2.21 KB
/
bf.lua
File metadata and controls
109 lines (95 loc) · 2.21 KB
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
local INC = 0
local MOVE = 1
local PRINT = 3
local LOOP = 4
local function Tape()
local pos = 1;
local data = {0};
local get = function()
return data[pos];
end
local inc = function(x)
data[pos] = data[pos] + x;
end
local move = function(x)
local length = #data;
pos = pos + x;
for i = length + 1, pos do
data[i] = 0;
end
end
return {
get = get;
inc = inc;
move = move;
};
end
local function Brainfuck(text)
local function parse(source, i)
local res = {};
while i <= source:len() do
local c = source:sub(i, i);
if c == "+" then
table.insert(res, {INC, 1});
elseif c == "-" then
table.insert(res, {INC, -1});
elseif c == ">" then
table.insert(res, {MOVE, 1});
elseif c == "<" then
table.insert(res, {MOVE, -1});
elseif c == "." then
table.insert(res, {PRINT});
elseif c == "[" then
local loop_code;
loop_code, i = parse(source, i+1);
table.insert(res, {LOOP, loop_code});
elseif c == "]" then
break;
end
i = i + 1;
end
return res, i;
end
local function _run(program, tape)
for i = 1, #program do
local op = program[i];
local operator = op[1];
if operator == INC then
tape.inc(op[2]);
elseif operator == MOVE then
tape.move(op[2]);
elseif operator == LOOP then
while tape.get() > 0 do
_run(op[2], tape);
end
elseif operator == PRINT then
io.write(string.char(tape.get()));
io.flush();
end
end
end
local function run()
_run(parse(text, 1), Tape())
end
return {
run = run;
};
end
local function notify(msg)
local socket = require "socket"
socket.protect(function()
local c = socket.try(socket.connect("localhost", 9001))
local try = socket.newtry(function() c:close() end)
try(c:send(msg))
c:close()
end)()
end
local f = io.open(arg[1])
local text = f:read("*a")
f:close()
local compiler = type(jit) == 'table' and "LuaJIT" or "Lua"
local getpid = require 'posix.unistd'.getpid
notify(string.format("%s\t%d", compiler, getpid()))
local brainfuck = Brainfuck(text)
brainfuck.run()
notify("stop")