They are all separate parts, and you can do them in any order you want.
I like to think of the language as two parts - syntax and features. How do I want the language to look and what features do I want the language to have? The parser and lexer handle the syntax, and the AST handles the features.
This way, I can play around with the syntax of the language a little later.
I would start with a really simple language:
- add expressions, proper infix support for arithmetic
- variables
- if / else / else if
- scoping / functions
- loops if you don't want to just use recursion
then, you can get more advanced:
- lambda expressions / first class functions / closures
- namespaces or types
- macros. if you can make nice looking lisp-style macros for an infix language i would love you
write it as an interpreter, add an llvm backend.
It should be fun. do a little at a time.