https://blog.ccbhj.com/posts/part-three-implement-an-expression-interpreter-for-building-DSL/