1. Kink Programming Language
  2. Untitled project
  3. kink

Commits

Taku Miyakawa  committed c9117c1

Set.show now does not cause stack overflow for recursive sets (closing issue #489)

  • Participants
  • Parent commits 15fdc49
  • Branches default

Comments (0)

Files changed (2)

File src/main/kink/SET.kn

View file
 # THE SOFTWARE.
 
 use('MAP')
+use('THREAD_LOCAL_STORAGE')
 
 :set = { (* :Args)
-    :Map = MAP.map
-    Args.loop {
-        Map.set(\0 true)
+    :Set = Set_proto.child._init(MAP.map)
+    Args.loop { (:Element)
+        Set.push(Element)
     }
-    _new_set(Map)
-}
-
-:_new_set = { (:Map)
-    Set_proto.child('Map' Map)
+    Set
 }
 
 :Set_proto = value(
-    # Map which contains the elements: {Element => Element}
-    'Map' MAP.map
+
+    # Initializes the map
+    '_init' { > :Set (:Map)
+        Set.set_vars(
+            # Map which contains the elements: {Element => true}
+            'Map' Map
+
+            # Map which contains the elements: {Element => true}
+            'Showing_tls' THREAD_LOCAL_STORAGE.new
+        )
+    }
+
     # Returns the count of elements
     'count' { > :Set ()
         Set.Map.count
     'loop' { > :Set (:_fun)
         Set.seq.loop($_fun)
     }
+
     # String representation of the set
     'show' { > :Set ()
-        'set(' + Set.list.map { \0.show } .join(' ') + ')'
+        Set.Showing_tls.get { false } .then {
+            'set(...)'
+        } {
+            Set.Showing_tls.setting(true) {
+                'set(' + Set.list.map { \0.show } .join(' ') + ')'
+            }
+        }
     }
+
     # Returns the clone of Set
     'clone' { > :Set ()
-        _new_set(Set.Map.clone)
+        Set_proto.child._init(Set.Map.clone)
     }
     # Returns true if Set is equal to Another
     'op_eq' { > :Set (:Another)
         true
     }
 )
+._init(MAP.map)

File src/test/kink/SET_test.kn

View file
 
 } # }}}1
 
+test_group('A set including the set itself as an element') { # {{{1
+
+    set_up(:Recursive_set) {
+        :Set = set
+        Set.push(Set)
+    }
+
+    test('.show returns a string representation') {
+        Recursive_set.show.check('set(set(...))')
+    }
+
+} # }}}1
+
 test_group('Equality groups') { # {{{1
 
     set_up(:Hoge_fuga_group) {