Interpreter
Interpreter represents a small grammar as expression objects and gives each grammar rule an evaluation operation. Keep the grammar limited and explicit; a full programming language needs stronger parsing and execution machinery.
What you’ll understand
- Interpreter represents a small grammar as expression objects and gives each grammar rule an evaluation operation. Keep the grammar limited and explicit; a full programming language needs stronger parsing and execution machinery.
- Variable and binary-expression nodes evaluate themselves recursively against a supplied context.
- Evaluate the tradeoff: One class or branch per grammar rule is manageable for a tiny language, but grammars with precedence, errors, or many operators need a proper parser and diagnostics.
Useful first: Classes and Objects
The idea and when to recognize it
Interpreter represents a small grammar as expression objects and gives each grammar rule an evaluation operation. Keep the grammar limited and explicit; a full programming language needs stronger parsing and execution machinery.
- Requirement: Access rules combine named Boolean variables with AND and OR.
- Change to anticipate: Evaluate a nested expression according to its tree structure instead of flattening all variables into one conjunction.
- Design goal: Variable and binary-expression nodes evaluate themselves recursively against a supplied context.
Start with the concrete problem
Access rules combine named Boolean variables with AND and OR.
Evaluate a nested expression according to its tree structure instead of flattening all variables into one conjunction.
| Direct implementation | Revised design |
|---|---|
| Ignoring the operator at each node changes OR into AND and rejects valid rules. | Variable and binary-expression nodes evaluate themselves recursively against a supplied context. |
| The baseline case can hide the problem. Compare the extension and boundary fixtures before accepting this design. | One class or branch per grammar rule is manageable for a tiny language, but grammars with precedence, errors, or many operators need a proper parser and diagnostics. |
Responsibilities and contracts
Variable and binary-expression nodes evaluate themselves recursively against a supplied context.
- Expression: Defines evaluation. Public operations: evaluate(context)
- Variable: Reads one context value. Public operations: evaluate(context)
- BinaryExpression: Combines two subexpressions. Public operations: operator, evaluate(context)
Read the design
Select a participant to inspect its responsibility and public operations. Follow the labeled relationships; an arrow indicates direction, while the legend distinguishes ownership, substitution, and temporary use.
Preparing the design walkthrough…
Follow the interaction
Choose a supplied workload and compare the direct and revised implementations. Step through the same operation in both languages. Object values are recorded after each highlighted statement; previous steps remain unchanged.
Preparing the design walkthrough…
Implementation and expected output
Read the complete example alongside its input and expected output. The implementation selector changes the displayed program; the language selector preserves your current scenario and playback position.
Preparing the design walkthrough…
Try the idea in another setting
A small search filter language can interpret nested tag conditions without exposing arbitrary code execution.
- Name the new client contract before adapting the example.
- Identify which state belongs to each object and who controls its lifetime.
- Write one normal case and one boundary case before extending the design.
Tradeoffs and interview takeaways
One class or branch per grammar rule is manageable for a tiny language, but grammars with precedence, errors, or many operators need a proper parser and diagnostics.
Common mistake: Ignoring the operator at each node changes OR into AND and rejects valid rules.
- Explain the choice: Variable and binary-expression nodes evaluate themselves recursively against a supplied context.
- Challenge your choice: One class or branch per grammar rule is manageable for a tiny language, but grammars with precedence, errors, or many operators need a proper parser and diagnostics.
- Describe a requirement that would make the simpler implementation sufficient.
Design challenge and knowledge check
Preparing the design walkthrough…