This repository is currently being migrated. It's locked while the migration is in progress.
forked from beingmeta/framerd-modules
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfindcycles.scm
72 lines (64 loc) · 2.5 KB
/
findcycles.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
;;; -*- Mode: Scheme; Character-encoding: utf-8; -*-
;;; Copyright (C) 2005-2018 beingmeta, inc. All rights reserved.
(in-module 'findcycles)
(module-export! 'findcycles)
(define (checkstack obj stack depth)
(if (eqv? obj (elt stack depth)) depth
(if (and (or (and (string? obj) (string? (elt stack depth)))
(and (packet? obj) (packet? (elt stack depth))))
(equal? obj (elt stack depth)))
depth
(if (= depth 0) #f
(checkstack obj stack (-1+ depth))))))
(define (loopdeloop obj objstack opstack depth return (pos))
(unless (or (oid? obj) (fixnum? obj) (immediate? obj)
(number? obj) (string? obj) (packet? obj))
(default! pos (if (= depth 1) #f
(checkstack obj opstack (- depth 2))))
;; (when pos (message "POS=" pos) (dbg obj))
(if pos (return (cons pos (subseq opstack 0 depth))))
(unless pos
(cond ((pair? obj)
(loopdeloop/push (qc (car obj)) car
objstack opstack depth return)
(loopdeloop/push (qc (cdr obj)) cdr
objstack opstack depth return))
((vector? obj)
(doseq (elt obj i)
(loopdeloop/push (qc elt) (glom "VEC" i)
objstack opstack depth return)))
((hashtable? obj)
(do-choices (key (getkeys obj) i)
(loopdeloop/push (qc (get obj key)) `(HASHGET ,key)
objstack opstack depth return)))
((table? obj)
(do-choices (key (getkeys obj) i)
(loopdeloop/push (qc (get obj key)) `(GET ,key)
objstack opstack depth return)))
((compound? obj)
(dotimes (i (compound-length obj))
(loopdeloop/push (qc (compound-ref obj i))
`(COMPOUND ,(compound-tag obj) ,i)
objstack opstack depth return)))
(else #f)))))
(define (loopdeloop/push obj op objstack opstack depth return)
(if (ambiguous? obj)
(doseq (ch (sorted obj) i)
(unless (or (oid? ch) (fixnum? ch) (immediate? ch)
(number? ch) (string? ch) (packet? ch))
(vector-set! objstack depth obj)
(vector-set! opstack depth op)
(vector-set! objstack (1+ depth) ch)
(vector-set! opstack (1+ depth) (glom "CHOICE" i))
(loopdeloop ch objstack opstack (+ depth 2) return)))
(begin
(vector-set! objstack depth obj)
(vector-set! opstack depth op)
(loopdeloop obj objstack opstack (1+ depth) return))))
(define (findcycles obj (maxdepth 16384))
(let ((objstack (make-vector maxdepth))
(opstack (make-vector maxdepth)))
(vector-set! objstack 0 obj)
(vector-set! opstack 0 'top)
(call/cc (lambda (return)
(loopdeloop obj objstack opstack 1 return)))))