Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 41 additions & 50 deletions pkg/lang/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,39 @@ type Set struct {
meta IPersistentMap
hash, hasheq uint32

vals []interface{}
hashMap IPersistentMap
}

type PersistentHashSet = Set // hack until we have a proper persistent hash set
type PersistentHashSet = Set

func CreatePersistentTreeSet(keys ISeq) interface{} {
func CreatePersistentTreeSet(keys ISeq) any {
// TODO: implement
return NewSet(seqToSlice(keys)...)
}

func CreatePersistentTreeSetWithComparator(comparator IFn, keys ISeq) interface{} {
func CreatePersistentTreeSetWithComparator(comparator IFn, keys ISeq) any {
// TODO: implement
return NewSet(seqToSlice(keys)...)
}

func NewSet(vals ...interface{}) *Set {
func NewSet(vals ...any) *Set {
set, err := NewSet2(vals...)
if err != nil {
panic(err)
}
return set
}

func NewSet2(vals ...interface{}) (*Set, error) {
// check for duplicates
func NewSet2(vals ...any) (*Set, error) {
set := &Set{
hashMap: NewPersistentHashMap(),
}
for i := 0; i < len(vals); i++ {
for j := i + 1; j < len(vals); j++ {
if Equiv(vals[i], vals[j]) {
return nil, NewIllegalArgumentError(fmt.Sprintf("duplicate key: %v", vals[i]))
}
}
val := vals[i]
set.hashMap = set.hashMap.Assoc(val, true).(IPersistentMap)
}

return &Set{
vals: vals,
}, nil
return set, nil
}

var (
Expand All @@ -55,57 +52,52 @@ var (
emptySet = NewSet()
)

func (s *Set) Get(key interface{}) interface{} {
for _, v := range s.vals {
if Equiv(v, key) {
return v
}
func (s *Set) Get(key any) any {
val := s.hashMap.ValAt(key)
if val == true {
return key
}
return nil
}

func (s *Set) Invoke(args ...interface{}) interface{} {
func (s *Set) Invoke(args ...any) any {
if len(args) != 1 {
panic(fmt.Errorf("set apply expects 1 argument, got %d", len(args)))
}

return s.Get(args[0])
}

func (s *Set) ApplyTo(args ISeq) interface{} {
func (s *Set) ApplyTo(args ISeq) any {
return s.Invoke(seqToSlice(args)...)
}

func (s *Set) Cons(v interface{}) Conser {
func (s *Set) Cons(v any) Conser {
if s.Contains(v) {
return s
}
return NewSet(append(s.vals, v)...)
return &Set{
meta: s.meta,
hashMap: s.hashMap.Assoc(v, true).(IPersistentMap),
}
}

func (s *Set) Disjoin(v interface{}) IPersistentSet {
for i, val := range s.vals {
if Equiv(val, v) {
newItems := make([]interface{}, len(s.vals)-1)
copy(newItems, s.vals[:i])
copy(newItems[i:], s.vals[i+1:])
return NewSet(newItems...)
}
func (s *Set) Disjoin(v any) IPersistentSet {
if !s.Contains(v) {
return s
}
return &Set{
meta: s.meta,
hashMap: s.hashMap.Without(v).(IPersistentMap),
}
return s
}

func (s *Set) Contains(v interface{}) bool {
for _, val := range s.vals {
if Equiv(val, v) {
return true
}
}
return false
func (s *Set) Contains(v any) bool {
return s.hashMap.ContainsKey(v)
}

func (s *Set) Count() int {
return len(s.vals)
return s.hashMap.Count()
}

func (s *Set) xxx_counted() {}
Expand All @@ -122,7 +114,7 @@ func (s *Set) String() string {
return PrintString(s)
}

func (s *Set) Equals(v2 interface{}) bool {
func (s *Set) Equals(v2 any) bool {
if s == v2 {
return true
}
Expand All @@ -143,10 +135,10 @@ func (s *Set) Equals(v2 interface{}) bool {
}

func (s *Set) Seq() ISeq {
if s.Count() == 0 {
if s.hashMap.Count() == 0 {
return nil
}
return NewSliceSeq(s.vals)
return NewMapKeySeq(Seq(s.hashMap))
}

func (s *Set) Equiv(o any) bool {
Expand All @@ -165,15 +157,14 @@ func (s *Set) Meta() IPersistentMap {
return s.meta
}

func (s *Set) WithMeta(meta IPersistentMap) interface{} {
func (s *Set) WithMeta(meta IPersistentMap) any {
if meta == s.meta {
return s
}

return &Set{
meta: meta,
vals: s.vals,
}
cpy := *s
cpy.meta = meta
return &cpy
}

func (s *Set) AsTransient() ITransientCollection {
Expand All @@ -185,7 +176,7 @@ type TransientSet struct {
*Set
}

func (s *TransientSet) Conj(v interface{}) Conjer {
func (s *TransientSet) Conj(v any) Conjer {
return &TransientSet{Set: s.Set.Cons(v).(*Set)}
}

Expand Down
23 changes: 20 additions & 3 deletions pkg/lang/symbol.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type Symbol struct {

var (
symbolRegex = regexp.MustCompile(`^(?:[^0-9/].*/)?(?:/|[^0-9/][^/]*)$`)

_ IFn = (*Symbol)(nil)
)

// NewSymbol creates a new symbol.
Expand All @@ -34,7 +36,7 @@ func NewSymbol(s string) *Symbol {
}
}

func InternSymbol(ns, name interface{}) *Symbol {
func InternSymbol(ns, name any) *Symbol {
if ns == nil {
return NewSymbol(name.(string))
}
Expand Down Expand Up @@ -127,7 +129,7 @@ func (s *Symbol) String() string {
return s.ns + "/" + s.name
}

func (s *Symbol) Equals(v interface{}) bool {
func (s *Symbol) Equals(v any) bool {
if s == v {
return true
}
Expand All @@ -145,7 +147,7 @@ func (s *Symbol) Meta() IPersistentMap {
return s.meta
}

func (s *Symbol) WithMeta(meta IPersistentMap) interface{} {
func (s *Symbol) WithMeta(meta IPersistentMap) any {
if s.meta == meta {
return s
}
Expand All @@ -160,3 +162,18 @@ func (s *Symbol) Hash() uint32 {
h.Write([]byte(s.ns + "/" + s.name))
return h.Sum32() ^ symbolHashMask
}

func (s *Symbol) Invoke(args ...any) any {
switch len(args) {
case 1:
return Get(args[0], s)
case 2:
return GetDefault(args[0], s, args[1])
default:
panic(NewIllegalArgumentError("symbol invoke expects 1 or 2 arguments"))
}
}

func (s *Symbol) ApplyTo(args ISeq) any {
return s.Invoke(seqToSlice(args)...)
}
2 changes: 1 addition & 1 deletion pkg/reader/testdata/reader/set00.glj
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#{:a :b :c}
#{:a}
2 changes: 1 addition & 1 deletion pkg/reader/testdata/reader/set00.out
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#{:a :b :c}
#{:a}
16 changes: 8 additions & 8 deletions pkg/stdlib/clojure/core/loader.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.