Interpreter Walkthrough
Curious about what happens after you click save? This optional chapter follows a file through the interpreter so you can peek behind the curtain. Skip it if you just want to cut; read on if you enjoy understanding how the studio thinks.
If you have ever wondered how a handful of lines like P1 64 angle 42.8 depth 0.18 become a fully fledged stone, this chapter is for you. It follows an FSL file through the interpreter so you know where information lives and why the diagnostics are so precise.
1. Reading the text
The interpreter starts by turning characters into tokens: words (gear, P1), numbers, string literals, punctuation, and comments. Each token remembers its line and column, which is why error messages can highlight the exact spot that needs attention.
2. Understanding the structure
Next, the parser groups tokens into meaningful statements and expressions. Think of it as building a tree:
- Assignments store values (e.g.,
x = 5) or update settings (e.g.gear = 96). - Facet commands bundle tier, side, angle, depth or point, symmetry, and optional notes.
- Functions capture reusable logic.
This tree is called the Abstract Syntax Tree (AST). It mirrors the shape of your file and is the blueprint for evaluation.
3. Evaluating step by step
With the AST ready, the evaluator walks through it from top to bottom:
- Sets up built-in helpers (trig/log functions,
GEAR, point resolvers likemp(),gp(),gpl(),cp(),ep(),fred(),prz()). - Applies each assignment so later statements see the updated values.
- Every facet command updates the virtual faceting machine, cuts a facet into the gemstone model, and records a log entry.
- Diagnostics (warnings, errors, notes) are collected as they happen.
When the pass finishes, you get a package containing the gemstone geometry, printable-ready cut log, and any messages produced along the way.
Function calls without surprises
Functions are evaluated when called. When you invoke myFunc(), the interpreter:
- Evaluates the arguments.
- Creates a new scope for the function body.
- Binds the arguments to the parameter names.
- Executes the function body, returning the last expression.
Because functions use the same expression evaluation logic, they behave consistently whether built-in or user-defined.
Why errors feel specific
Each major stage—tokenizing, parsing, evaluating—adds context to its messages. A type mismatch knows which expression triggered it. A missing parenthesis reports the line and even suggests what was expected. When the web studio displays an error, it uses this information straight from the interpreter.
When you might dive deeper
- You want to add a new statement or built-in function.
- You are debugging a function that behaves differently than expected.
- You are curious about how the cut log feeds the geometry engine.
In those cases, browse the corresponding Rust files in src/interpreter/ and update the language chapters so the surface documentation stays aligned. Otherwise, feel free to treat the interpreter as a black box that simply does the right thing.