What it basically does is print the complete memory stack, by checking that they are "valid" printable characters. Though that may be wrong because it just checks that the number is above 32 and not if the number is under a value, so if you try to print numbers above 255 you'll probably have errors.

One thing I consider you do wrong is filling the table at startup, that is not something you need, a 0 even though is 0 uses 64bits of memory so loading thousands of those inside a table for nothing is really a waste. As an example you could do:

To icrement a cell, this allows the cell to be nil which doesn't consume memory like a 0 does.

Anyway, the program looks really nice, and can be easily extended which is cool, I would implement the dot though since that is what you expect brainfuck to do, I wrote programs to use two or three cells to write whole sentences which I can display with this interpreter.

Also you should delete all print statements that are simply for debugging, since those are confusing to the user running your interpreter

That is great! I'm glad I could help, I downloaded the new file and had a look again and it was much better, so I decided to have some fun with it, first I must note that all the changes I made are TOTALLY UNNECESSARY! but if you find something you deem useful you can feel free to use it in your program.

So what did I do:

Made the output a string instead of directly printing to the console

I sandboxed the program, now it environment only contains string.char that is the only lua function the program needs.

Made the program return the output string at the end so that you can print it or something (you could access it from the environment too but it is easier this way)

Made a run function that runs the program with a hook that errors when the program is in an infinite loop, this is pretty useful for Brainfuck programs that have many loops and some of them may never return. The quota (number of instructions) can be passed as an argument to run if 10000 is too little.

The returned function pcalls the run function so that the error doesn't propagate to the main program

When a char is not recognized in the compilation step, instead of ignoring it I add a new line, this way errors, which commonly point to the line where the Lua error is, can be used to know what character in the Brainfuck program has the error, since Lua line == Brainfuck character

In your program if you try to print a cell with a value of 1000 it completely crashes I fixed this so cells can only contain numbers up to 255 and if that value is exceeded they wrap to 0, this could be changed with some more work in the dot (making sure that the cell is a printable character or something like that).

I removed some unused variables like BfString and utf8, and took the compile function outside of interpret so that it isn't generated every time interpret is called

The next step would be to implement input command (,) but that may be harder, anyway have fun!