What you don't see here is that you're using your psql process's available open file handles as a stack, and when you hit that limit psql will fail. If you remove that limit, then you get a bit further before psql segfaults on you. I think I got ~2700 files deep before that happened. Your stackage may vary.
I'm not saying this is a good solution, quite the contrary. I think the sane solution is right around the corner in Version 11.
Now if we just had a way of passing parameters into DO blocks...
I hope so there will be schema (temporal) variables:
create temp variable foo int default 10;
do $$
begin
for i in 1..foo loop
raise notice '%', i;
end loop;
end; $$;
That would be nice too.
A while back, somebody explained why implementing parameters in a DO block was so hard, but I don't recall why, and the search terms "do" and "parameter" don't really narrow things down.