File: module-system.jl

package info (click to toggle)
librep 0.90.2-1.3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 3,940 kB
  • sloc: ansic: 32,948; lisp: 11,025; sh: 9,844; makefile: 545; sed: 93
file content (173 lines) | stat: -rw-r--r-- 6,454 bytes parent folder | download | duplicates (3)
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#| rep.module-system bootstrap

   $Id$

   Copyright (C) 2000 John Harper <john@dcs.warwick.ac.uk>

   This file is part of librep.

   librep is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   librep is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with librep; see the file COPYING.  If not, write to
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|#

(declare (in-module rep.module-system))

(open-structures '(rep.lang.symbols
		   rep.structures
		   rep.data))

;; rename the bindings required by exported macros
(%define %make-structure make-structure)
(%define %make-interface make-interface)
(%define %parse-interface parse-interface)
(%define %external-structure-ref external-structure-ref)
(%define %alias-structure alias-structure)


;; module syntax

(defmacro define-interface (name sig)
  "Associate the symbol NAME with the module interface SIG (in a
separate interface-name namespace). An interface specification must be
of the form:

   INTERFACE ->  (export [ID...])
	     or  NAME
	     or  (compound-interface [INTERFACE...])
	     or  (structure-interface [STRUCTURE-NAME...])

where an ID is a symbol naming a top-level binding to export, and NAME
is the name of an interface previously defined using define-interface.

The `export' form adds top-level definitions ID... to the interface;
the `compound-interface' clauses forms the union of the given
interfaces."

  (list '%make-interface (list 'quote name)
	(list '%parse-interface (list 'quote sig))))

(defmacro structure (#!optional sig config . body)
  "Create a new module whose interface is SIG, whose configuration is
defined by CONFIG (either a single clause, or a list of clauses), and
whose definitions are defined by the list of forms BODY.

See `define-interface' for the interface syntax, each configuration
clause must have the syntax:

   CLAUSE ->  (open [NAME...])
	  or  (access [NAME...])

where NAME is the name of a module. Opening a module imports all of its
exported definitions into the currently module, while accessing a
module makes the exported definitions available from the current module
using the `structure-ref' form."

  (unless (listp (car config))
    (setq config (list config)))
  (list '%make-structure (list '%parse-interface (list 'quote sig))
	(list* 'lambda nil (cons '(open rep.module-system) config))
	(list* 'lambda nil body)))

(defmacro define-structure (name #!optional sig config . body)
  "Create a module called NAME whose interface is SIG, whose
configuration is defined by CONFIG (either a single clause, or a list
of clauses), and whose definitions are defined by the list of forms
BODY.

See the `define-interface' and `structure' macros for descriptions of
the interface and configuration clause syntaxes respectively."

  (unless (listp (car config))
    (setq config (list config)))
  (list '%make-structure (list '%parse-interface (list 'quote sig))
	(list* 'lambda nil (cons '(open rep.module-system) config))
	(list* 'lambda nil body)
	(list 'quote name)))

(defmacro define-structures (structs config . body)
  "Similar to `define-structure' except that multiple structures are
created, each exporting a particular view of the underlying bindings.

STRUCTS is a list defining the names and interfaces of the created
modules, each item has the form `(NAME INTERFACE)'. CONFIG and BODY are
exactly the same as in the `define-structure' syntax."
  (unless (listp (car config))
    (setq config (list config)))
  (require 'rep.lang.backquote)
  (let ((tem (gensym)))
    `(let ((,tem (list (structure () ((export-all) ,@config) ,@body))))
       ,@(mapcar (lambda (x)
		   (let ((name (car x))
			 (interface (cadr x)))
		     `(%make-structure
		       (%parse-interface ',interface)
		       (lambda ()
			 (open rep.module-system)
			 (%open-structures ,tem))
		       () ',name)))
		 structs))))

(defmacro define-structure-alias (to from)
  "Create a secondary name TO for the structure called FROM."
  (list '%alias-structure (list 'quote from) (list 'quote to)))

(defmacro structure-ref (struct-name var-name)
  "Evaluates to the current value of the global binding of symbol
VAR-NAME in the module called STRUCT-NAME. This structure must
previously have been opened or accessed by the current module.

When read, the syntax `FOO#BAR' expands to `(structure-ref FOO BAR)'."

  (list '%external-structure-ref
	(list 'quote struct-name) (list 'quote var-name)))


;; `%meta' structure used for configuring modules

;; helper definitions
(defmacro structure-open names
  (list '%open-structures (list 'quote names)))
(defmacro structure-access names
  (list '%access-structures (list 'quote names)))
(defmacro set-binds ()
  (list '%structure-set-binds (list '%current-structure) ''t))
(defmacro export-all ()
  (list '%structure-exports-all (list '%current-structure) ''t))

(let ((meta-struct (make-structure '(open %open-structures
				     access %access-structures
				     set-binds %structure-set-binds
				     export-all %structure-exports-all
				     %current-structure quote)
				   nil nil '%meta)))
  (structure-define meta-struct 'quote quote)
  (structure-define meta-struct 'open structure-open)
  (structure-define meta-struct '%open-structures open-structures)
  (structure-define meta-struct 'access structure-access)
  (structure-define meta-struct '%access-structures access-structures)
  (structure-define meta-struct 'set-binds set-binds)
  (structure-define meta-struct '%structure-set-binds structure-set-binds)
  (structure-define meta-struct 'export-all export-all)
  (structure-define meta-struct '%structure-exports-all structure-exports-all)
  (structure-define meta-struct '%current-structure current-structure))


;; exports

(export-bindings '(define-interface structure define-structure
		   define-structures define-structure-alias structure-ref
		   %make-structure %make-interface %parse-interface
		   %external-structure-ref %alias-structure))

(export-bindings '(lambda validate-byte-code run-byte-code load))