-
Notifications
You must be signed in to change notification settings - Fork 0
/
module.zp
81 lines (77 loc) · 2.62 KB
/
module.zp
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
(define *modules* (make-hash))
(define-syntax import
(syntax-rules ()
((import name)
(let ((_name (if (symbol? 'name) (symbol->string 'name) name)))
(if (not (in? _name #\:))
(if (hash:contains? *modules* _name)
(*modules* _name)
:no)
(let* ((fullname (string:split _name #\:))
(_module (car fullname))
(function (cadr fullname)))
(if (hash:contains? *modules* _module)
(if (hash:contains? (*modules* _module) function)
((*modules* _module) function)
:no)
:no)))))))
(define-syntax import-all
(syntax-rules ()
((import-all name to env)
(if (hash:contains? *modules* name)
(hash:kv-map
(lambda (kv)
(eval `(define ,(string->symbol (++ to ":" (head kv))) (quote ,(cadr kv))) env))
(*modules* name))
:no))
((import-all name to)
(let ((env (current-env)))
(import-all name to env)))
((import-all name)
(import-all name name))))
(define-syntax module
(syntax-rules (export loads)
((module name)
(set! *modules* (make-hash *modules* (make-hash name #{}))))
((module name (export exports ...) (loads files ...) x ...)
((lambda ()
(let ((env (current-env)))
(begin
(map
(lambda (file) (load file env))
'files)
(module name (export exports ...) x ...))))))
((module name (export exports ...) x ...)
(letrec* (x ...)
(hash:set! *modules* name
(make-hash
(map
(lambda (el) "build the module map"
(if (atom? (car el))
(cons (string:tail (symbol->string (car el))) (cdr el))
el))
(list exports ...))))))))
(define-syntax module-extend
(syntax-rules (export loads)
((module name (export exports ...) (loads files ...) x ...)
((lambda ()
(let ((env (current-env)))
(begin
(map
(lambda (file) (load file env))
'files)
(module-extend name (export exports ...) x ...))))))
((module-extend name (export exports ...) x ...)
(letrec* (x ...)
(begin
(import-all name)
(hash:update! *modules* name
(lambda (h)
(make-hash h
(make-hash
(map
(lambda (el)
(if (atom? (car el))
(cons (string:tail (symbol->string (car el))) (cdr el))
el))
(list exports ...)))))))))))