Repository navigation
Visualizer: mode «Baum» (feature tree), and why a call stays a box - #53
Merged
Merged
Conversation
«Baum» shows an expression as its syntax tree while it is evaluated: one step opens the tree, then exactly the substitution mode's steps, each a subtree becoming its value, then one step closes it. Inline calls are replaced by their return expression's tree, other calls hang their box below the tree. A tree is laid out where it opens or grows, with room for every later value, so reductions move nothing; reduced subtrees fly up and fade (animations on, no reduced motion). Off by default (capability tree, embed features=tree). In «Ersetzung» and «Baum», the outermost box now says why the call isn't replaced (the call-enter step's boxReason). Checks: test:tree (steps, texts as the chain, stable positions, on runtime traces), check-runtime-box-reasons.py, and «Baum» cases in test:console. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
P34 A: the visualizer's third mode «Baum», plus a note at every call that «Ersetzung» or «Baum» keeps as a box.
1. Mode «Baum» (capability
tree, embedfeatures=tree)Off by default and not part of «everything». Without
treethere is no third button, and a stored or presetvisualizer=treeshows «Ersetzung».Steps for an expression
e: this applies to an expression statement, the value of an assignment orreturn, and anif's orwhile's condition. A bare name or literal gets no tree.eby its tree, in a box ate's place in the line.-x) becomes its value together with its last child.x = 2 + 3 * 4x = (2 + 3) * 4y = quadrat(2 + 1)notenschnitt([4, 5, 4.5])(local variables)How it shows:
return <expression>is replaced by that expression's tree, with the parameters' values filled in. Any other call stays a node, and its box from «Kasten» hangs below the tree; inside the box, each line gets its own tree.+,quadrat,[ ],.replace,roundwith andigits=child. A name is a leaf.(2 + 3) * 4and2 + 3 * 4differ only in shape.noten→[4, 5, 4.5]).prefers-reduced-motion.2 + 12.Code:
src/treeMode.ts(new):treeModeSteps,buildExpressionTree,episodeTreeLayout.Framesplices the tree into its line the way it splices a box.TreeViewcan take a precomputed layout and animates changes.layoutTreecan reserve room per node.2. Why a call stays a box («Ersetzung» and «Baum»)
The outermost box now says at its top why the call isn't replaced. The mode button stays pressable. The runtime gives the reason on the call's step (
boxReason), andvisualizerBoxReasonwords it in German and English:notenschnitthat lokale Variablen – der Aufruf wird als Kasten gezeigt.if/matchfakwählt mit if, was ausgeführt wird – …fhat mehrere Anweisungen – …return <Ausdruck>fgibt keinen Ausdruck mit return zurück – …fgibt einen Ausdruck zurück, der sich nicht mit Werten ausschreiben lässt – …This replaces «Der Kasten zeigt, welches return ausgeführt wird.», which stays as the fallback without a reason.
Checks
npm run test:tree(new, in CI): runs on traces of the real runtime under CPython. It checks the four sketch examples, a recursion and[x, -x, 2]:+(2, *(3, 4))against*(+(2, 3), 4));check-runtime-box-reasons.py(new, intest:runtime): each reason, and none for the short form.test:console, new «Baum» cases:tree, only «Kasten» and «Ersetzung» show;windowHeight=900);notenschnittbox in «Ersetzung» and in «Baum».test:runtime,test:protocol,test:hints,test:layout, and all oftest:console.Going live
features=…,treeexcept the box note in «Ersetzung», which every course sees.treeon.treeon. It gets the box note in «Ersetzung» with the next bump.Manual tests
Desktop (Chrome, Safari, Firefox), on an embed with
features=visualize,tree:x = 2 + 3 * 4in «Baum»: open,3 * 4 → 12,2 + 12 → 14, close, assign. The+,2and12nodes don't move.x = (2 + 3) * 4: same steps, different shape, no parentheses.quadrat(2 + 1):quadrat→3, then the call becomes the tree3 * 3, then9.notenschnitt([4, 5, 4.5])(local variables): the box hangs below the tree with «notenschnitt hat lokale Variablen …», and its lines have their own trees. Switch to «Ersetzung»: same note.fak(2)(recursion withif): nested trees and boxes; note «wählt mit if …».c = (a + 1) / bwithb = 0: the/node is red, with the message and hint below the line.tree: two buttons, as before.iPad (landscape, portrait, rotation), with an external keyboard:
x = 1 + 2 * 3 - 4 * 5 + 6 * 7 - 8 * 9) at 420 px starts with its root in the middle and shows the hint at the edges.Follow-ups (not done)
forloop's iterable, anassertor adel.(2 * 3) + 4) isn't read out. The chain keeps it.🤖 Generated with Claude Code