Skip to content

Commit 13096b1

Browse files
Leo Caglieroclaude
andcommitted
fix(script): comparar contra un nombre de bicho ya no falla en silencio
?foe.kind = mosquito parseaba sin un solo error y era falso para siempre. Como el idioma no tenia literales de texto, mosquito se buscaba como ruta del mundo, volvia undefined, y nunca era igual a nada. El jugador escribia lo obvio, no recibia ninguna queja, y perdia la pelea sin forma de ver por que. Un script sintacticamente valido y semanticamente muerto es la peor respuesta que puede dar este idioma, porque el juego entero consiste en mirar una regla fallar y entender por que. Ahora un nombre suelto que no nombra nada del mundo se lee como texto. Descarte las comillas, que era el otro arreglo posible. El punto del idioma es que alguien que nunca programo pueda escribir una regla, y acordarse de entrecomillar un lado de la comparacion y el otro no es exactamente lo que le ensena a la gente que es mala en esto. Un token con puntos nunca es texto: foe.dsit es un typo de una ruta, no una palabra, asi que sigue dando falso en vez de compararse contra la cadena "foe.dsit" y pasar por casualidad. Verificado: los seis casos andan, incluidos los numeros, el != y el typo de ruta. 258 asserts del repo siguen pasando. Escrito despues del cierre del hackathon, lo aclaro en vez de disimularlo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 763d945 commit 13096b1

1 file changed

Lines changed: 24 additions & 1 deletion

File tree

lib/script.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,30 @@ function operand(world, token) {
173173
if (t === '') return undefined
174174
if (/^-?\d+(\.\d+)?$/.test(t)) return Number(t)
175175
if (/^(true|false)$/i.test(t)) return t.toLowerCase() === 'true'
176-
return lookup(world, t)
176+
177+
const v = lookup(world, t)
178+
if (v !== undefined) return v
179+
180+
// A bare word that names nothing in the world is read as text.
181+
//
182+
// Without this, `?foe.kind = mosquito` parsed without a single error and was
183+
// false forever: `mosquito` was looked up as a path, came back undefined, and
184+
// never equalled anything. The player wrote the obvious thing, got no
185+
// complaint, and lost the fight with no way to see why. A script that is
186+
// syntactically valid and semantically dead is the worst answer this language
187+
// can give.
188+
//
189+
// Quotes would have been the other fix and they are worse here: the point of
190+
// the language is that someone who has never programmed can write a rule, and
191+
// remembering to quote one side of a comparison and not the other is exactly
192+
// the kind of thing that teaches people they are bad at this.
193+
//
194+
// A dotted token is never text. `foe.dsit` is a typo for a path, not a word,
195+
// so it stays undefined and the condition stays false rather than quietly
196+
// comparing against the string "foe.dsit".
197+
if (/^[A-Za-z_][A-Za-z0-9_-]*$/.test(t)) return t
198+
199+
return undefined
177200
}
178201

179202
/**

0 commit comments

Comments
 (0)