Without macros you could implement eval still but your internal lisp implementation could only work on quoted s-expressions, there would be no way to get back to the base unquoted level of lisp code (assuming you can't use the primitive eval, since you're trying to implement lisp in lisp).
Another use case is implementing a shortcutting boolean and function. You can't do the shortcutting without macros because all of the arguments get eval'd before passing to your and function.
eval
Runs at runtime.
Takes a data structure (usually a list) and evaluates it as Lisp code.
Example: (eval '(+ 1 2)) ; => 3
Use case: Dynamically construct and run code while the program is running.
Macros
Runs at compile time (or macro-expansion time).
Transform Lisp code before it's evaluated. They return new code (a Lisp form) to be compiled/evaluated later.
Example: (defmacro my-unless (condition body) `(if (not ,condition) ,body))
(my-unless (= 1 2) (print "Not equal")) ; expands to (if (not (= 1 2)) (print ...))
Use case: Extend the language by defining new syntactic constructs. Enables powerful DSLs and optimizations.
When a macro is used for any given purpose, what happens is a bit more general because it first "does something with" its argument (rather than necessarily straight-up evaluating it). Then the result of that is evaluated.
Macros are really only instructions for the compiler, how to compile things faster.
The syntax improvement aspect is minuscule, because Lisp has no actual syntax perse.
If you look at McCarthy's first paper [1] it becomes clear (after a long while) that eval does not have to support macros.
The ideas in Common Lisp on macros and evaluation (eval) are (conceptually "far away" from McCarthy's paper, perhaps more developed):
1. Read-time with "#." and #'set-dispatch-macro-character
2. Macroexpansion-time with #'macroexpand and #'defmacro and (macrolet …)-forms and (symbol-macrolet …)-forms
3. Compile-time (optional for evaluators) with #'compile and #'define-compiler-macro
4. Load-time with (load-time-value …)-forms
5. Run-time with #'funcall and #'eval (conceptually) and #'defun and (lambda …)-forms (conceptually)
The trick is that eval is called recursively and depth-first along the abstract syntax tree (AST). Function evaluation is depth-first left-to-right. Macros and special-forms are for not depth-forst and left-to-right. Loops need to evaluate (incf i) or "i++" possibly more than once, exactly once, or not at all. "If" only evaluates either its second or its third argument, but never both.
Note, how #'set-dispatch-macro-character, #'macroexpand, #'compile, #'load-time-value, and #'eval are all functions. They are "executed at (their own) run-time."
The difference bewteen compile-time and load-time becomes obvious in parenscript. In parenscript compile time has symbolic-expressions (s-expressions) and parenscript-forms a.k.a. "valid parenscript in parentheses" while load-time already has JavaScript code. In Lisp all of this stiff just happens to be Lisp objects. Strings at read-time (symbolic-expression), lists for macroexpansion (macros are like user-defined special forms) [macroexpansion turns them into valid common lisp a.k.a. Common Lisp forms], and internal Lisp objects like compiled functions for the compiler, "loader", and run-time.
Note, that the issue of having two namespaces, that of values and that of functions, is a separate issue. Here is where macros and functions look the same, because their names are at the beginning of a "form", e.g. (with-open-file …). With-open-file never directly evaluates its first argument: the list of arguments for function open.
A "form" is a list that is meant to be evaluated. If it is valid Common Lisp code, then it is a lisp form. If it user-defined, then it better be a function call or a macro call. And the macro call has to translate it into either the call of a user-defined function or valid Common Lisp code.
Macros define "new syntax" kind of like special forms deviate from function evaluation. (if a b c) is a special form, that is a non-function-call defined by Lisp, just like Haskell leverages lazy evaluation to define "if" without eager function evaluation.