A collection of various things from the Asterisk server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
3.9 KiB

local look_for_closing_brace = function(context, idx)
if context.matching_indices[idx] ~= nil then
return context.matching_indices[idx]
end
local orig_idx = idx
local layer = 1
while layer ~= 0 do
idx = idx + 1
if context.program[idx] == nil then
return -1
end
if context.program[idx] == 7 then
layer = layer + 1
end
if context.program[idx] == 8 then
layer = layer - 1
end
end
context.matching_indices[orig_idx] = idx
return idx
end
local init_tape_at_head = function(context)
if context.tape[context.head_pos] == nil then
context.tape[context.head_pos] = context.initial_tape_func(context.head_pos)
end
end
local loop_jump = function(context)
init_tape_at_head(context)
if context.tape[context.head_pos] ~= 0 then
context.ip = context.jumpstack_left[#context.jumpstack_left] + 1
else
local idx = #context.jumpstack_left
context.jumpstack_left[idx] = nil
context.jumpstack_right[idx] = nil
context.ip = context.ip + 1
end
end
local do_open_bracket = function(context)
context.jumpstack_left[#context.jumpstack_left + 1] = context.ip
context.jumpstack_right[#context.jumpstack_left] = look_for_closing_brace(context, context.ip)
context.ip = context.jumpstack_right[#context.jumpstack_left]
loop_jump(context)
end
local do_close_bracket = function(context)
if context.jumpstack_right[#context.jumpstack_left] == context.ip then
loop_jump(context)
else
context.retval = {kind = "error", value = "unexpected right bracket"}
end
end
local instr_table =
{
[1] = function(context)
context.head_pos = context.head_pos - 1
context.ip = context.ip + 1
end,
[2] = function(context)
context.head_pos = context.head_pos + 1
context.ip = context.ip + 1
end,
[3] = function(context)
init_tape_at_head(context)
context.tape[context.head_pos] = context.tape[context.head_pos] + 1
context.ip = context.ip + 1
end,
[4] = function(context)
init_tape_at_head(context)
context.tape[context.head_pos] = context.tape[context.head_pos] - 1
context.ip = context.ip + 1
end,
[5] = function(context)
init_tape_at_head(context)
context.write(context.tape[context.head_pos])
context.ip = context.ip + 1
end,
[6] = function(context)
context.tape[context.head_pos] = context.read()
context.ip = context.ip + 1
end,
[7] = do_open_bracket,
[8] = do_close_bracket,
[9] = function(context)
context.debugfn(context.head_pos, context.ip, context.tape)
context.ip = context.ip + 1
end,
}
local step = function(context, app)
local f = instr_table[context.program[context.ip]]
if f == nil then
context.retval = {kind = "return", value = "success"}
else
f(context)
end
end
function new_brainfuck_context(log, program, write, read, debugfn, initial_tape_func)
local context =
{
program = program,
write = write,
read = read,
debugfn = debugfn,
log = log,
initial_tape_func = initial_tape_func,
head_pos = 0,
tape = {},
ip = 1,
jumpstack_left = {},
jumpstack_right = {},
matching_indices = {},
retval = nil,
}
context.step = step
return context
end
return { new_brainfuck_context = new_brainfuck_context }
--[[
--str = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."
--str = "+[-]..."
--str = ".+.>.+.<.-.>.-."
str = "+[+]"
char_table =
{
[">"] = 1,
["<"] = 2,
["+"] = 3,
["-"] = 4,
["."] = 5,
[","] = 6,
["["] = 7,
["]"] = 8,
}
prog = {}
for i = 1,#str do
prog[#prog + 1] = char_table[string.sub(str, i, i)]
end
out = ""
unmangled = ""
context = new_brainfuck_context(prog, function(v)
out = out .. " " .. tostring(v)
unmangled = unmangled .. string.char(v)
end, function() return 0 end, function() return 0 end)
count = 0
while context.retval == nil and count < 1000000 do
context:step()
count = count + 1
end
tab = context.retval
if tab.kind == "return" then
print(out)
print(unmangled)
elseif tab.kind == "error" then
print("error: " .. tab.value)
end
--]]