swapfuck/Implementation

From Esolang
Jump to navigation Jump to search
Back to swapfuck

Here is a rough implementation of swapfuck in Lua. The "while zero" loop described in the main article has been included in this interpreter as {}.

return {
	run = function (wc, tape)
		local wc = wc:gsub("[^%@%<%>%[%]%{%}%.]", "")
		
		local tape = tape or {}
		local cell = 1
		local stack = {}
		
		local buffer = 0
		local buffersize = 0
		
		local i = 1
		while i <= #wc do
			local char = wc:sub(i, i)
			
			-- Basics
			if char == "@" then
				tape[cell], tape[cell + 1] = tape[cell + 1], tape[cell]
			elseif char == "<" then
				cell = cell - 1
			elseif char == ">" then
				cell = cell + 1
			
			-- While
			elseif char == "[" or char == "{" then
				if (char == "{") ~= (tape[cell] ~= nil and tape[cell] ~= 0) then
					table.insert(stack, {type = "while", ip = i})
				else
					local depth = 1

					i = i + 1
					while depth > 0 do
						local char = wc:sub(i, i)
						if char == "[" then depth = depth + 1
						elseif char == "]" then depth = depth - 1 end

						i = i + 1
					end
					i = i - 1
				end
			elseif char == "]" or char == "}" then
				if (char == "}") ~= (tape[cell] ~= nil and tape[cell] ~= 0) then
					i = stack[#stack].ip
				else
					table.remove(stack)
				end
			
			-- Output
			elseif char == "." then
				buffer = buffer * 2 + ((tape[cell] and tape[cell] ~= 0) and 1 or 0)
				buffersize = buffersize + 1
				
				if buffersize == 8 then
					io.write(string.char(buffer))
					buffer, buffersize = 0, 0
				end
			end

			i = i + 1
		end

		return tape
	end
}