Skip to content

Commit f2c7782

Browse files
committed
Fix colon in symbol/keyword literals and enable reader tests
Allow colon (:) inside symbol and keyword names. Previously colons were unconditionally excluded from isSymbolChar(), causing 🔤def:ghi to be tokenized as three tokens. Now colons are only special at token boundaries (keyword literal start). Reader test assertions: 144 → 146.
1 parent 20c8fb2 commit f2c7782

3 files changed

Lines changed: 10 additions & 13 deletions

File tree

‎.dev/memo.md‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ Phase 53: Hardening & pprint Tests — IN PROGRESS
2727
- [x] 53.2: Fix loop destructuring recur bug
2828
- [x] 53.3: Align distinct? to upstream (enabled by 53.2)
2929
- [x] 53.4: Fix BigDecimal exponent notation (1.0e+1M)
30-
- [ ] 53.5: Fix colon in symbol/keyword literals
30+
- [x] 53.5: Fix colon in symbol/keyword literals
3131
- [ ] 53.6: Port pprint tests (content-equivalent, CW-adapted)
3232
- [ ] 53.7: Full regression + update docs
3333

3434
## Current Task
3535

36-
53.5: Fix colon in symbol/keyword literals
36+
53.6: Port pprint tests (content-equivalent, CW-adapted)
3737

3838
## Previous Task
3939

@@ -43,7 +43,6 @@ Phase 52: Quality & Alignment (complete)
4343
## Known Issues
4444

4545
- apply on infinite lazy seq realizes eagerly (deferred — no tests need it)
46-
- Colon in symbol/keyword literals parsed as keyword delimiter
4746
- binding *ns* doesn't affect read-string for auto-resolved keywords
4847
- Regex capture groups/backreferences not supported
4948

‎src/reader/tokenizer.zig‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,9 @@ fn isTerminator(c: u8) bool {
455455
fn isSymbolChar(c: u8) bool {
456456
// # is valid inside symbols (gensym: foo#, tagged: my#tag)
457457
// but not at start (handled by next() dispatch).
458-
// : is excluded — colons start keywords.
459-
return !isTerminator(c) and c != ':';
458+
// : is valid inside symbols/keywords (e.g. abc:def, :abc:def:ghi).
459+
// Colons only start keywords at token boundaries (handled by next()).
460+
return !isTerminator(c);
460461
}
461462

462463
fn isWhitespace(c: u8) bool {

‎test/upstream/clojure/test_clojure/reader.clj‎

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
;; Upstream: clojure/test/clojure/test_clojure/reader.cljc
1212
;; Upstream lines: 802
13-
;; CLJW markers: 29
13+
;; CLJW markers: 27
1414

1515
(ns clojure.test-clojure.reader
1616
;; CLJW: removed clojure.instant, clojure.walk, clojure.edn, test.generative,
@@ -22,12 +22,11 @@
2222
(deftest Symbols
2323
(is (= 'abc (symbol "abc")))
2424
(is (= '*+!-_? (symbol "*+!-_?")))
25-
;; CLJW: colon in symbol names parsed as keyword delimiter, skipped 2 tests
26-
;; (is (= 'abc:def:ghi (symbol "abc:def:ghi")))
25+
(is (= 'abc:def:ghi (symbol "abc:def:ghi")))
2726
(is (= 'abc/def (symbol "abc" "def")))
2827
(is (= 'abc.def/ghi (symbol "abc.def" "ghi")))
2928
(is (= 'abc/def.ghi (symbol "abc" "def.ghi")))
30-
;; (is (= 'abc:def/ghi:jkl.mno (symbol "abc:def" "ghi:jkl.mno")))
29+
(is (= 'abc:def/ghi:jkl.mno (symbol "abc:def" "ghi:jkl.mno")))
3130
;; CLJW: symbol? instead of instance? clojure.lang.Symbol
3231
(is (symbol? 'alphabet)))
3332

@@ -226,14 +225,12 @@
226225
(is (= :abc (keyword "abc")))
227226
(is (= :abc (keyword 'abc)))
228227
(is (= :*+!-_? (keyword "*+!-_?")))
229-
;; CLJW: colon in keyword literals parsed as keyword delimiter
230-
;; Use keyword fn to create and verify instead of literal
231-
(is (= (keyword "abc:def:ghi") (keyword "abc:def:ghi")))
228+
(is (= :abc:def:ghi (keyword "abc:def:ghi")))
232229
(is (= :abc/def (keyword "abc" "def")))
233230
(is (= :abc/def (keyword 'abc/def)))
234231
(is (= :abc.def/ghi (keyword "abc.def" "ghi")))
235232
(is (= :abc/def.ghi (keyword "abc" "def.ghi")))
236-
(is (= (keyword "abc:def" "ghi:jkl.mno") (keyword "abc:def" "ghi:jkl.mno")))
233+
(is (= :abc:def/ghi:jkl.mno (keyword "abc:def" "ghi:jkl.mno")))
237234
;; CLJW: keyword? instead of instance? clojure.lang.Keyword
238235
(is (keyword? :alphabet)))
239236

0 commit comments

Comments
 (0)