allows you to skip the often tedious parsing step by using the host’s read
READ mostly gives a tree of tokens. This makes it a form of a tokenizer. After we call READ we don’t know what the tokens mean: is FOO a variable, a macro, a function, a built-in special form, a type, … This can only be determined by interpreting/compiling the token tree.
You might want to check the indentation of your code. It looks not right. Do you use TAB characters in your editor? Don’t!
One problem could be, that your code is not working, because you have a bug in your EVAL form. Did you actually try to run it?
Because then there is no name clash with symbols written by the macro user. If you would intern gensyms, where would you intern it? In which package Your variant does not say, whatever the current package is the symbol will be interned. If the user has a symbol there, one may get random (hard to debug) name clashes.
EVAL is not ‘evil’. It’s just most of the time not needed and you need to understand what it does. EVAL evaluates the code always in the global environment. EVAL also may not compile the code, so it may run interpreted, depending on the Common Lisp implementation.