stole a bunch of ideas from Lua