Problem Description
Evaluate a string representing a Lisp-like expression that may include integers, variable names, and three types of expressions: let, add, and mult. The expression can contain nested scopes, and variables follow lexical scoping rules.
Key Insights
- Recursively parse the expression token by token.
- Use a map (or hash table) to maintain variable bindings and manage scope.
- For let expressions, process variable assignments sequentially; later assignments can shadow earlier ones.
- Ensure that look-up checks the innermost scope first.
- Parsing requires careful handling of parentheses and white space separation.
Space and Time Complexity
Time Complexity: O(n), where n is the number of tokens in the expression since each token is processed once. Space Complexity: O(n), due to the recursion stack and storage for variable scopes.
Solution
We solve the problem by designing a recursive parser that processes each token. The parser distinguishes between numbers, variable names, and compound expressions that start with a left parenthesis. For compound expressions:
- If the expression begins with "let", we sequentially assign variables to evaluated expressions, storing these in a map for the current scope.
- If the expression begins with "add" or "mult", we evaluate the two inner expressions and return their sum or product, respectively. A key trick is to maintain a scoped mapping of variable values. When entering a new let expression, we begin with the current scope and add new bindings. When the inner expression is evaluated, bindings that were added in the let block are discarded on returning to the outer scope.