answer the parsing question: a grammar is a basis, and five keywords reserved nothing

This commit is contained in:
bigmerge
2026-08-17 09:43:58 -05:00
2 changed files with 40 additions and 5 deletions
+16 -5
View File
@@ -145,6 +145,22 @@ fn tok_append(tokens: [Any], kind: String, value: String) -> [Any] {
// -- Keyword lookup ------------------------------------------------------------
// keyword_kind the language's reserved spellings.
//
// A grammar is a BASIS: `fn` means function-start because someone said so, and
// nothing derives it. But unlike the other tables moved out this session, this
// one stays code, and the SHOULD gate is why. The keyword set is closed by the
// language definition -- it does not leak the way an allowlist does -- and the
// lexer runs before the program is understood, so a program can never declare
// its own keywords. Externalising it would cost file I/O on every compile and
// buy nothing.
//
// Removed 2026-08-17: sealed, activate, seed, protocol, impl. Reserved in the
// lexer, consumed by no parser or codegen path, and each one stole an
// identifier from users for nothing. `test` LOOKED inert by the same measure
// and is not -- codegen consumes it at 4135 for --test mode, 408 uses in the
// tree. The first measurement checked only parser.el and would have broken all
// of them.
fn keyword_kind(word: String) -> String {
if word == "let" { return "Let" }
if word == "fn" { return "Fn" }
@@ -161,14 +177,9 @@ fn keyword_kind(word: String) -> String {
if word == "from" { return "From" }
if word == "as" { return "As" }
if word == "with" { return "With" }
if word == "sealed" { return "Sealed" }
if word == "activate" { return "Activate" }
if word == "where" { return "Where" }
if word == "test" { return "Test" }
if word == "seed" { return "Seed" }
if word == "assert" { return "Assert" }
if word == "protocol" { return "Protocol" }
if word == "impl" { return "Impl" }
if word == "retry" { return "Retry" }
if word == "times" { return "Times" }
if word == "fallback" { return "Fallback" }
+24
View File
@@ -943,3 +943,27 @@ test "string-plus-string-still-concatenates" {
let out: String = compile_capture(src)
assert str_contains(out, "el_str_concat"), "String + String still concatenates"
}
// Reserved words that reserved nothing
//
// sealed, activate, seed, protocol and impl were keywords in the lexer and were
// consumed by no parser or codegen path. Each stole an identifier from users
// for nothing, and using one silently miscompiled: `let seed = 42` compiled
// clean and produced the wrong value with no diagnostic at any layer.
test "freed-identifiers-compile-as-identifiers" {
let src: String = "fn main() { let seed = 42 let impl = seed + 1 println(int_to_str(impl)) }"
let out: String = compile_capture(src)
assert str_contains(out, "el_val_t seed"), "seed is an identifier"
assert str_contains(out, "el_val_t impl"), "impl is an identifier"
assert str_contains(out, "(seed + 1)"), "and arithmetic on them dispatches correctly"
}
test "test-keyword-is-still-reserved" {
// `test` LOOKED inert by the same measure and is not: codegen consumes it
// for --test mode, 408 uses in the tree. Measuring only parser.el would
// have removed it.
let src: String = "fn main() { println(\"x\") }"
let out: String = compile_capture(src)
assert str_contains(out, "int main"), "the suite still compiles, which requires test to remain a keyword"
}