Tsonnet #29 - Making inner references work
Source: Dev.to

Welcome to the Tsonnet series!
If you’re not following along, check out how it all started in the first post of the series.
In the previous post, I added ppx_deriving.show to help debug the AST and centralized configuration.
Tsonnet #29 – Making inner references work
What we’re building
Here’s the sample file we need to handle:
// samples/tutorials/inner-reference.jsonnet
{
Martini: {
local drink = self,
ingredients: [
{ kind: "Farmer's Gin", qty: 1 },
{
kind: 'Dry White Vermouth',
qty: drink.ingredients[0].qty,
},
],
garnish: 'Olive',
served: 'Straight Up',
},
}
The tricky bit is the local drink = self inside the Martini object. The variable drink holds a reference to the object itself, and we then use it to access drink.ingredients[0].qty. This is a self‑reference through an intermediate variable.
The expected output (as a cram test) is:
diff --git a/test/cram/tutorials.t b/test/cram/tutorials.t
index b9c1f6f..9fe544c 100644
--- a/test/cram/tutorials.t
+++ b/test/cram/tutorials.t
@@ -79,3 +79,15 @@
"served": "Tall"
}
}
+
+ $ tsonnet ../../samples/tutorials/inner-reference.jsonnet
+ {
+ "Martini": {
+ "garnish": "Olive",
+ "ingredients": [
+ { "kind": "Farmer's Gin", "qty": 1 },
+ { "kind": "Dry White Vermouth", "qty": 1 }
+ ],
+ "served": "Straight Up"
+ }
+ }
Extending the AST with variable references
We already have Self and TopLevel for object scopes. Now we need a way to reference objects through variables:
@@ -76,6 +76,7 @@ and object_entry =
and object_scope =
| Self
| TopLevel
| ObjVarRef of string
[@@deriving show]
let dummy_expr = Unit
Objects also need their own environment. Before, we were storing just an… (the article continues with the implementation details).