File: ns.scm

package info (click to toggle)
sdc 1.0.8beta-8
  • links: PTS
  • area: contrib
  • in suites: slink
  • size: 1,400 kB
  • ctags: 874
  • sloc: lisp: 8,120; ansic: 967; makefile: 671; perl: 136; sh: 50
file content (84 lines) | stat: -rw-r--r-- 2,207 bytes parent folder | download
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
(module namespace
	(export
	 (rassq el lst)
	 (ass cmp el lst)
	 (gen-ns id . next)
	 (ns-ensure-name name namespace)))

(define (rassq el lst)
  (cond
   ((null? lst) #f)
   ((eq? el (cdar lst)) (car lst))
   (else (rassq el (cdr lst)))))

(define (ass cmp el lst)
  (cond
   ((null? lst) #f)
   ((cmp el (car lst)) (car lst))
   (else (ass cmp el (cdr lst)))))

(define (gen-ns id . next)
  (letrec ((objs '())
	   (last #f)
	   (link-in (lambda (entry)
		      (if last
			  (let ((new (list entry)))
			    (set-cdr! last new)
			    (set! last new))
			  (let ((new (list entry)))
			    (set! objs new)
			    (set! last new)))
		      entry))
	   (names-of (lambda (o objs)
		       (if (null? objs)
			   (if next
			       (next 'names-of o)
			       '())
			   (if (eq? o (cdar objs))
			       (cons (caar objs) (names-of o (cdr objs)))
			       (names-of o (cdr objs)))))))
    (set! next (if (null? next) #f (car next)))
    (lambda (cmd . rest)
      (case cmd
	((resolve) (apply (lambda (name)
			    (let ((entry (assq name objs)))
			      (if entry entry
				  (if next (next 'resolve name)
				      #f)))) rest))
	((lookup)  (apply (lambda (name)
			    (let ((entry (assoc name objs)))
			      (if entry entry
				  (if next (next 'lookup name)
				      #f)))) rest))
	((bound)   (apply (lambda (name)
			    (let ((entry (assoc name objs)))
			      (if entry (car entry)
				  (if next (next 'bound name)
				      #f)))) rest))
	((bind)  (apply (lambda (obj name)
			  (let ((entry (assoc name objs)))
			    (if entry
				(error id "bind: name already used" name)
				(link-in (cons name obj))))) rest))
	((bind!) (apply (lambda (obj name)
			  (let ((entry (assoc name objs)))
			    (if entry
				(begin
				  (set-cdr! entry obj)
				  entry)
				(link-in (cons name obj))))) rest))
	((list) objs)
	((names-of) (names-of (car rest) objs))
	((ass) (apply (lambda (cmp obj)
			(let ((entry (ass cmp obj objs)))
			  (if entry entry
			      (if next (next 'ass cmp obj)
				  #f)))) rest))
	(else (error id "ns: unknown request" cmd))))))

(define (ns-ensure-name name ns)
  (let ((nn (ns 'bound name)))
    (if (not nn)
	(error "ns-ensure-name" "name not bound" name)
	nn)))