Skip to content

Commit f536b46

Browse files
authored
Add support for reader conditionals (#? and #?@) (#109)
* Add reader support for shebang-style comments Signed-off-by: James Hamlin <jfhamlin@gmail.com> * Basic support of reader conditionals Signed-off-by: James Hamlin <jfhamlin@gmail.com> * Handle reader conditionals at EOF or end of collections Signed-off-by: James Hamlin <jfhamlin@gmail.com> * Add more reader conditional tests Signed-off-by: James Hamlin <jfhamlin@gmail.com> * Reader fixes after fuzz testing runs Signed-off-by: James Hamlin <jfhamlin@gmail.com> --------- Signed-off-by: James Hamlin <jfhamlin@gmail.com>
1 parent d63e704 commit f536b46

19 files changed

Lines changed: 318 additions & 104 deletions

pkg/lang/set.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,26 @@ func CreatePersistentTreeSetWithComparator(comparator IFn, keys ISeq) interface{
2525
}
2626

2727
func NewSet(vals ...interface{}) *Set {
28+
set, err := NewSet2(vals...)
29+
if err != nil {
30+
panic(err)
31+
}
32+
return set
33+
}
34+
35+
func NewSet2(vals ...interface{}) (*Set, error) {
2836
// check for duplicates
2937
for i := 0; i < len(vals); i++ {
3038
for j := i + 1; j < len(vals); j++ {
3139
if Equiv(vals[i], vals[j]) {
32-
panic(NewIllegalArgumentError(fmt.Sprintf("duplicate key: %v", vals[i])))
40+
return nil, NewIllegalArgumentError(fmt.Sprintf("duplicate key: %v", vals[i]))
3341
}
3442
}
3543
}
3644

3745
return &Set{
3846
vals: vals,
39-
}
47+
}, nil
4048
}
4149

4250
var (

pkg/lang/symbol.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package lang
22

33
import (
44
"fmt"
5+
"regexp"
56
"strings"
67
)
78

@@ -11,6 +12,10 @@ type Symbol struct {
1112
name string
1213
}
1314

15+
var (
16+
symbolRegex = regexp.MustCompile(`^(?:[^0-9/].*/)?(?:/|[^0-9/][^/]*)$`)
17+
)
18+
1419
// NewSymbol creates a new symbol.
1520
func NewSymbol(s string) *Symbol {
1621
ns, name := "", s
@@ -83,6 +88,9 @@ func isValidSymbol(ns, name string) bool {
8388
} else {
8489
full = ns + "/" + name
8590
}
91+
if !symbolRegex.MatchString(full) {
92+
return false
93+
}
8694

8795
// early special case for the division operator /
8896
if full == "/" {
@@ -97,11 +105,11 @@ func isValidSymbol(ns, name string) bool {
97105
// empty namespace
98106
return false
99107
}
100-
if strings.HasSuffix(name, ":") {
108+
if strings.HasSuffix(name, ":") || strings.HasSuffix(ns, ":") {
101109
// name ends with a colon (match clojure)
102110
return false
103111
}
104-
if strings.Contains(name, "::") {
112+
if strings.Contains(full, "::") {
105113
// name contains double colon
106114
//
107115
// NB: clojure reader rejects this, but clojure.core/symbol

pkg/reader/clj_conformance_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ func FuzzCLJConformance(f *testing.F) {
6666
if err != nil {
6767
f.Fatal(err)
6868
}
69+
70+
// skip any files that contain the string ";; skip-clj"
71+
if strings.Contains(string(data), ";; skip-clj") {
72+
continue
73+
}
74+
6975
f.Add(string(data))
7076
}
7177

0 commit comments

Comments
 (0)