Detect cyclic references to prevent infinite recursion

Alternate implementation to #12. Uses fields on the printer type to track recursion depth and visited pointers.

If you think this is cleaner and you're happy with it, I'll squash to 1 commit.