From 43b26260b9ef954e53315c10c8e67c608442a7ec Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Tue, 14 Jul 2026 09:36:18 -0700 Subject: [PATCH] =?UTF-8?q?kidlisp:=20a=20note=20is=20a=20literal=20?= =?UTF-8?q?=E2=80=94=20(bell=20e5),=20not=20(bell=20"e5")?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `c4`, `f#3`, `bb5` now evaluate to themselves, the way a number does. Without this the voices were unusable: every bare note resolved as an undefined variable and threw "Unknown KidLisp word: e4". Only when nothing else has claimed the name — so a variable you defined called `e5` still wins. A language you can't say out loud is one nobody writes music in. Co-Authored-By: Claude Opus 4.8 (1M context) --- system/public/aesthetic.computer/lib/kidlisp.mjs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/system/public/aesthetic.computer/lib/kidlisp.mjs b/system/public/aesthetic.computer/lib/kidlisp.mjs index 0684c554a..36967c483 100644 --- a/system/public/aesthetic.computer/lib/kidlisp.mjs +++ b/system/public/aesthetic.computer/lib/kidlisp.mjs @@ -28,6 +28,9 @@ import { setFadeAlpha, clearFadeAlpha } from "./fade-state.mjs"; // we borrow them rather than growing a second set here, because two definitions of // "what a bell sounds like" is one too many and they WILL drift. import { voices } from "./pads.mjs"; + +// A note: letter, optional sharp/flat, octave. `c4` `f#3` `bb5` `a1`. +const NOTE_LITERAL = /^[a-gA-G](#|s|b|f)?[0-8]$/; import { checkPackMode, getPackMode } from "./pack-mode.mjs"; import { log } from "./logs.mjs"; import { captureFrame, formatTimestamp, generateFilename } from "./frame-capture.mjs"; @@ -9466,9 +9469,15 @@ class KidLisp { } } + // A NOTE IS A LITERAL. `c4`, `f#3`, `bb5` evaluate to themselves, the way a + // number does — so you can write (bell e5) instead of (bell "e5"), and the + // language stays sayable out loud. Only when nothing else has claimed the + // name, so a variable called `e5` still wins if you defined one. + if (value === undefined && NOTE_LITERAL.test(expr)) return expr; + // If we get here and expr looks like an identifier but wasn't found, // flag it as an unknown word (same as function head detection) - if (value === undefined && validIdentifierRegex.test(expr) && + if (value === undefined && validIdentifierRegex.test(expr) && !this.unknownWordsLogged?.has(expr) && expr !== "fps" && expr !== "s" && expr.length > 1) { this.unknownWordsLogged?.add(expr); -- 2.51.2