Usually you need to create character tables and check the type. For some langauges you can do it on the fly; for others, I think it’s pretty much for name resolution and type checking in the first place, or you won’t be able to interpret it correctly (C ++ comes to mind).
After creating the symbol tables, you can write an interpreter by going through the tree in exeuction order and do what the operators say. Basic arithmetic is quite simple. Managing strings and dynamic storages is more complicated; you’ll find out how you are going to handle the distribution of storage and the dellocatoid, and for the langauages ​​that manage the storage, you will have to implement some sort of garbage collector. At this point, life becomes complicated.
You will most likely find your langauage related features that you did not take into account. Exception Handling? Multiple appointments? Local areas? Lambda? Shutters? You will learn quite quickly how many modern languages ​​that make them useful.
When you start writing more complex programs, you will need a debugger. Control points? The only step? Variable inspection? Refresh? Start at random places? Read-eval-print loop?
You still need to bind the language to external libraries; most people want to talk to consoles and files; Do you need buffered files, or are you ok with 1 character at a time, and the corresponding performance? You can argue with characater representations (7 bit ascii? 8 bit? UTF8 with asymmetric wide characters? Full Unicode?) And standard support libraries (string concatenation, search, number conversion [including exact floating point conversions in both directions], large arithmetic numbers, floating point traps, ... The list of problems is quite long if you want to use a useful programming language.
The core of the interpreter is likely to be quite small. You will find other material, possibly burning one or two orders of magnitude more effort. Somewhere here, if you want someone to use langauge, you need to document all the choices you made. And heaven helps you if you change the interpreter a little after someone gets a great application.
Then someone will complain about performance. Now you can customize your implementation and begin to reconcile that instead of an interpreter you wrote an interpreter.
Enjoy. If you have AST, you barely scratched the surface. If you do this, you will learn to truly appreciate what modern languages ​​provide out of the box, and how much effort was required to provide it.