Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
;; Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd.
2
;; All rights reserved.
3
;; Copyright (C) 2007-2016, Gabriel Dos Reis.
4
;; All rights reserved.
5
;;
6
;; Redistribution and use in source and binary forms, with or without
7
;; modification, are permitted provided that the following conditions are
8
;; met:
9
;;
10
;; - Redistributions of source code must retain the above copyright
11
;; notice, this list of conditions and the following disclaimer.
12
;;
13
;; - Redistributions in binary form must reproduce the above copyright
14
;; notice, this list of conditions and the following disclaimer in
15
;; the documentation and/or other materials provided with the
16
;; distribution.
17
;;
18
;; - Neither the name of The Numerical Algorithms Group Ltd. nor the
19
;; names of its contributors may be used to endorse or promote products
20
;; derived from this software without specific prior written permission.
21
;;
22
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23
;; IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24
;; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
;; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26
;; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
;; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29
;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30
;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34
35
;; In order to understand this program you need to understand some details
36
;; of the structure of the databases it reads. Axiom has 4 databases,
37
;; the interp.daase, operation.daase, category.daase, and
38
;; browse.daase.
39
;;
40
;; This documentation refers to KAF files which are random access files.
41
;; NRLIB files are KAF files (look for NRLIB/index.KAF)
42
;; The format of a random access file is
43
;; \begin{verbatim}
44
;; byte-offset-of-key-table
45
;; first-entry
46
;; second-entry
47
;; ...
48
;; last-entry
49
;; ((key1 . first-entry-byte-address)
50
;; (key2 . second-entry-byte-address)
51
;; ...
52
;; (keyN . last-entry-byte-address))
53
;; \end{verbatim}
54
;; The key table is a standard lisp alist.
55
;;
56
;; To open a database you fetch the first number, seek to that location,
57
;; and (read) which returns the key-data alist. To look up data you
58
;; index into the key-data alist, find the ith-entry-byte-address,
59
;; seek to that address, and (read).
60
;;
61
;; For instance, see src/share/algebra/USERS.DAASE/index.KAF
62
;;
63
;; One existing optimization is that if the data is a simple thing like a
64
;; symbol then the nth-entry-byte-address is replaced by immediate data.
65
;;
66
;; Indeed, a faster optimization is to simply read the whole database
67
;; into the image before it is saved. The system would be easier to
68
;; understand and the interpreter would be faster.
69
;;
70
;; The system uses another optimization: database contains a stamp
71
;; (consisting of offset to the main list and build time). Before
72
;; saving the image selected data is fetched to memory. When the
73
;; saved image starts it checks if the stamp of saved data matches
74
;; in-core data -- in case of agreement in-core data is used.
75
;; Parts of the datatabase which was not pre-loaded is still
76
;; (lazily) fetched from the filesystem.
77
;;
78
;; Database files are very similar to KAF files except that there
79
;; is an optimization (currently broken) which makes the first
80
;; item a pair of two numbers. The first number in the pair is
81
;; the offset of the key-value table, the second is a time stamp.
82
;; If the time stamp in the database matches the time stamp in
83
;; the image the database is not needed (since the internal hash
84
;; tables already contain all of the information). When the database
85
;; is built the time stamp is saved in both the gcl image and the
86
;; database.
87
88
89
;;TTT 7/2/97
90
; Regarding the 'ancestors field for a category: Note that the ancestor
91
; information in interp.daase involves #1, #2, etc
92
; instead of R, Coef, etc. The latter thingies appear in all
93
; .NRLIB/index.KAF files. So we need to be careful when we )lib
94
; categories and update the ancestor info.
95
96
97
; This file contains the code to build, open and access the .DAASE
98
; files this file contains the code to )library NRLIBS
99
100
; There is a major issue about the data that resides in these
101
; databases. the fundamental problem is that the system requires more
102
; information to build the databases than it needs to run the
103
; interpreter. in particular, MODEMAP.DAASE is constructed using
104
; properties like "modemaps" but the interpreter will never ask for
105
; this information.
106
107
; So, the design is as follows:
108
; first, the MODEMAP.DAASE needs to be built. this is done by doing
109
; a )library on ALL of the NRLIB files that are going into the system.
110
; this will bring in "modemap" information and add it to the
111
; *modemaps-hash* hashtable.
112
; next, database build proceeds, accessing the "modemap" property
113
; from the hashtables. once this completes this information is never
114
; used again.
115
; next, the interp.daase database is built. this contains only the
116
; information necessary to run the interpreter. note that during the
117
; running of the interpreter users can extend the system by do a
118
; )library on a new NRLIB file. this will cause fields such as "modemap"
119
; to be read and hashed.
120
121
; In the old system each constructor (e.g. LIST) had one library directory
122
; (e.g. LIST.NRLIB). this directory contained a random access file called
123
; the index.KAF file. the interpreter needed this KAF file at runtime for
124
; two entries, the operationAlist and the ConstructorModemap.
125
; during the redesign for the new compiler we decided to merge all of
126
; these .NRLIB/index.KAF files into one database, INTERP.DAASE.
127
; requests to get information from this database are intended to be
128
; cached so that multiple references do not cause additional disk i/o.
129
; this database is left open at all times as it is used frequently by
130
; the interpreter. one minor complication is that newly compiled files
131
; need to override information that exists in this database.
132
; The design calls for constructing a random read (KAF format) file
133
; that is accessed by functions that cache their results. when the
134
; database is opened the list of constructor-index pairs is hashed
135
; by constructor name. a request for information about a constructor
136
; causes the information to replace the index in the hash table. since
137
; the index is a number and the data is a non-numeric sexpr there is
138
; no source of confusion about when the data needs to be read.
139
;
140
; The format of this new database is as follows:
141
;
142
;first entry:
143
; an integer giving the byte offset to the constructor alist
144
; at the bottom of the file
145
;second and subsequent entries (one per constructor)
146
; (operationAlist)
147
; (constructorModemap)
148
; ....
149
;last entry: (pointed at by the first entry)
150
; an alist of (constructor . index) e.g.
151
; ( (PI offset-of-operationAlist offset-of-constructorModemap)
152
; (NNI offset-of-operationAlist offset-of-constructorModemap)
153
; ....)
154
; This list is read at open time and hashed by the car of each item.
155
156
; the system has been changed to use the property list of the
157
; symbols rather than hash tables. since we already hashed once
158
; to get the symbol we need only an offset to get the property
159
; list. this also has the advantage that eq hash tables no longer
160
; need to be moved during garbage collection.
161
; there are 3 potential speedups that could be done. the best
162
; would be to use the value cell of the symbol rather than the
163
; property list but i'm unable to determine all uses of the
164
; value cell at the present time.
165
; a second speedup is to guarantee that the property list is
166
; a single item, namely the database structure. this removes
167
; an assoc but leaves one open to breaking the system if someone
168
; adds something to the property list. this was not done because
169
; of the danger mentioned.
170
; a third speedup is to make the getdatabase call go away, either
171
; by making it a macro or eliding it entirely. this was not done
172
; because we want to keep the flexibility of changing the database
173
; forms.
174
175
; the new design does not use hash tables. the database structure
176
; contains an entry for each item that used to be in a hash table.
177
; initially the structure contains file-position pointers and
178
; these are replaced by real data when they are first looked up.
179
; the database structure is kept on the property list of the
180
; constructor, thus, (get '|DenavitHartenbergMatrix| 'database)
181
; will return the database structure object.
182
183
; each operation has a property on its symbol name called 'operation
184
; which is a list of all of the signatures of operations with that name.
185
186
; -- tim daly
187
188
(import-module "sys-utility")
189
(in-package "AxiomCore")
190
(in-package "BOOT")
191
192
(defstruct database
193
abbreviation ; interp.
194
ancestors ; interp.
195
constructor ; interp.
196
constructorcategory ; interp.
197
constructorkind ; interp.
198
constructormodemap ; interp.
199
cosig ; interp.
200
defaultdomain ; interp.
201
modemaps ; interp.
202
object ; interp.
203
operationalist ; interp.
204
documentation ; browse.
205
constructorform ; browse.
206
attributes ; browse.
207
predicates ; browse.
208
sourcefile ; browse.
209
parents ; browse.
210
users ; browse.
211
dependents ; browse.
212
superdomain ; interp.
213
instantiations ; nil if mutable constructor
214
compiler-data ; holds compiler data when processing constructor
215
load-path ; full object path name, when loaded.
216
capsule-definitions ; capsule-level definitions
217
template ; for a category, this is the generic instance.
218
; for a functor, this is the template.
219
lookup-function ; for a functor, lookup function. For category
220
; constructor, default package constructor.
221
optable ; for a functor, operation table.
222
) ; database structure
223
224
(deftype |%Database| nil 'database)
225
226
(defmacro |dbAbbreviation| (db)
227
`(database-abbreviation ,db))
228
229
(defmacro |dbConstructor| (db)
230
`(database-constructor ,db))
231
232
(defmacro |dbConstructorKind| (db)
233
`(database-constructorkind ,db))
234
235
(defmacro |dbConstructorForm| (db)
236
`(database-constructorform ,db))
237
238
(defmacro |dbOperations| (db)
239
`(database-operationalist ,db))
240
241
(defmacro |dbModemaps| (db)
242
`(database-modemaps ,db))
243
244
(defmacro |dbConstructorModemap| (db)
245
`(database-constructormodemap ,db))
246
247
(defmacro |dbDualSignature| (db)
248
`(database-cosig ,db))
249
250
(defmacro |dbSuperDomain| (db)
251
`(database-superdomain ,db))
252
253
(defmacro |dbCategory| (db)
254
`(database-constructorcategory ,db))
255
256
(defmacro |dbPrincipals| (db)
257
`(database-parents ,db))
258
259
(defmacro |dbAncestors| (db)
260
`(database-ancestors ,db))
261
262
(defmacro |dbDefaultDomain| (db)
263
`(database-defaultdomain ,db))
264
265
(defmacro |dbAttributes| (db)
266
`(database-attributes ,db))
267
268
(defmacro |dbPredicates| (db)
269
`(database-predicates ,db))
270
271
(defmacro |dbSourceFile| (db)
272
`(database-sourcefile ,db))
273
274
(defmacro |dbModule| (db)
275
`(database-object ,db))
276
277
(defmacro |dbArity| (db)
278
`(list-length (cdr (|dbConstructorForm| ,db))))
279
280
(defmacro |dbInstanceCache| (db)
281
`(database-instantiations ,db))
282
283
(defmacro |dbCompilerData| (db)
284
`(database-compiler-data ,db))
285
286
(defmacro |dbBeingDefined?| (db)
287
`(|dbCompilerData| ,db))
288
289
(defmacro |dbLoadPath| (db)
290
`(database-load-path ,db))
291
292
(defmacro |dbCapsuleDefinitions| (db)
293
`(database-capsule-definitions ,db))
294
295
(defmacro |dbTemplate| (db)
296
`(database-template ,db))
297
298
(defmacro |dbOperationTable| (db)
299
`(database-optable ,db))
300
301
(defmacro |dbLookupFunction| (db)
302
`(database-lookup-function ,db))
303
304
(defmacro |dbDocumentation| (db)
305
`(database-documentation ,db))
306
307
(defun |makeDB| (c &optional (k nil) (a nil))
308
(let ((db (make-database)))
309
(|makeConstructor| c k a)
310
(setf (|dbConstructor| db) c)
311
(setf (|dbConstructorKind| db) k)
312
(setf (|dbAbbreviation| db) a)
313
(setf (|constructorDB| c) db)))
314
315
; there are only a small number of domains that have default domains.
316
; rather than keep this slot in every domain we maintain a list here.
317
318
(defvar *defaultdomain-list* '(
319
(|MultisetAggregate| |Multiset|)
320
(|FunctionSpace| |Expression|)
321
(|AlgebraicallyClosedFunctionSpace| |Expression|)
322
(|ThreeSpaceCategory| |ThreeSpace|)
323
(|DequeueAggregate| |Dequeue|)
324
(|ComplexCategory| |Complex|)
325
(|LazyStreamAggregate| |Stream|)
326
(|AssociationListAggregate| |AssociationList|)
327
(|QuaternionCategory| |Quaternion|)
328
(|PriorityQueueAggregate| |Heap|)
329
(|PointCategory| |Point|)
330
(|PlottableSpaceCurveCategory| |Plot3D|)
331
(|PermutationCategory| |Permutation|)
332
(|StringCategory| |String|)
333
(|FileNameCategory| |FileName|)
334
(|OctonionCategory| |Octonion|)))
335
336
; this hash table is used to answer the question "does domain x
337
; have category y?". this is answered by constructing a pair of
338
; (x . y) and doing an equal hash into this table.
339
340
(defvar *operation-hash* nil
341
"given an operation name, what are its modemaps?")
342
343
(defvar *miss* nil
344
"if true print out cache misses on getdatabase calls")
345
346
; note that constructorcategory information need only be kept for
347
; items of type category.
348
; note that the *modemaps-hash* information does not need to be kept
349
; for system files. these are precomputed and kept in modemap.daase
350
; however, for user-defined files these are needed.
351
; currently these are added to the database for 2 reasons:
352
; there is a still-unresolved issue of user database extensions
353
; this information is used during database build time
354
355
356
357
; this are the streams for the databases. they are always open.
358
; there is an optimization for speeding up system startup. if the
359
; database is opened and the ..-stream-stamp* variable matches the
360
; position information in the database then the database is NOT
361
; read in and is assumed to match the in-core version
362
363
(defvar *interp-stream* nil
364
"an open stream to the interpreter database")
365
366
(defvar *interp-stream-stamp* 0
367
"*interp-stream* (position . time)")
368
369
; this is indexed by operation, not constructor
370
(defvar *operation-stream*
371
nil "the stream to operation.daase")
372
373
(defvar *operation-stream-stamp* 0
374
"*operation-stream* (position . time)")
375
376
(defvar *browse-stream* nil
377
"an open stream to the browser database")
378
379
(defvar *browse-stream-stamp* 0
380
"*browse-stream* (position . time)")
381
382
; this is indexed by (domain . category)
383
(defvar *category-stream* nil
384
"an open stream to the category table")
385
386
(defvar *category-stream-stamp* 0
387
"*category-stream* (position . time)")
388
389
(defvar *allconstructors* nil
390
"a list of all the constructors in the system")
391
392
(defvar *allOperations* nil
393
"a list of all the operations in the system")
394
395
(defvar |$ConstructorCache| nil)
396
397
(defun |closeAllDatabaseStreams| nil
398
(close *interp-stream*)
399
(close *operation-stream*)
400
(close *category-stream*)
401
(close *browse-stream*))
402
403
(defun |fillDatabasesInCore| nil
404
"set all -hash* to clean values. used to clean up core before saving system"
405
(setq |$HasCategoryTable| (make-hash-table :test #'equal))
406
(setq *operation-hash* (make-hash-table))
407
(setq *allconstructors* nil)
408
(setq *interp-stream-stamp* '(0 . 0))
409
(interpopen)
410
(setq *operation-stream-stamp* '(0 . 0))
411
(operationopen)
412
(setq *browse-stream-stamp* '(0 . 0))
413
(browseopen)
414
(setq *category-stream-stamp* '(0 . 0))
415
(categoryopen) ;note: this depends on constructorform in browse.daase
416
#+:AKCL (gbc t)
417
)
418
419
420
; format of an entry in interp.daase:
421
; (constructor-name
422
; operationalist
423
; constructormodemap
424
; modemaps -- this should not be needed. eliminate it.
425
; object -- the name of the object file to load for this con.
426
; constructorcategory -- note that this info is valid only for categories.
427
; abbrev -- kept directly
428
; cosig -- kept directly
429
; constructorkind -- kept directly
430
; defaultdomain -- a short list, for %i
431
; ancestors -- used to compute new category updates
432
; superdomain -- valid for domain, NIL for category and package.
433
; )
434
(defun interpOpen ()
435
"open the interpreter database and hash the keys"
436
(let (constructors pos stamp dbstruct)
437
(setq *interp-stream* (open (|pathToDatabase| "interp.daase")))
438
(setq stamp (read *interp-stream*))
439
(unless (equal stamp *interp-stream-stamp*)
440
(when |$verbose|
441
(format t " Re-reading interp.daase"))
442
(setq *interp-stream-stamp* stamp)
443
(setq pos (car stamp))
444
(file-position *interp-stream* pos)
445
(setq constructors (read *interp-stream*))
446
(dolist (item constructors)
447
(setq *allconstructors* (adjoin (first item) *allconstructors*))
448
(setq dbstruct (|makeDB| (first item) (ninth item) (seventh item)))
449
(setf (|dbOperations| dbstruct) (second item))
450
; (setf (|dbConstructorModemap| dbstruct) (third item))
451
(setf (|dbModemaps| dbstruct) (fourth item))
452
(setf (|dbModule| dbstruct) (fifth item))
453
(setf (|dbCategory| dbstruct) (sixth item))
454
(setf (get (seventh item) 'abbreviationfor) (first item)) ;invert
455
; (setf (|dbDualSignature| dbstruct) (eighth item))
456
; (setf (|dbAncestors| dbstruct) (nth 10 item))
457
; (setf (|dbSuperDomain| dbstruct) (nth 11 item))
458
))
459
460
(format t "~&")))
461
462
; this is an initialization function for the constructor database
463
; it sets up 2 hash tables, opens the database and hashes the index values
464
465
; there is a slight asymmetry in this code. sourcefile information for
466
; system files is only the filename and extension. for user files it
467
; contains the full pathname. when the database is first opened the
468
; sourcefile slot contains system names. the lookup function
469
; has to prefix the $spadroot information if the directory-namestring is
470
; null (we don't know the real root at database build time).
471
; a object-hash table is set up to look up nrlib and ao information.
472
; this slot is empty until a user does a )library call. we remember
473
; the location of the nrlib or ao file for the users local library
474
; at that time. a NIL result from this probe means that the
475
; library is in the system-specified place. when we get into multiple
476
; library locations this will also contain system files.
477
478
479
; format of an entry in browse.daase:
480
; ( constructorname
481
; sourcefile
482
; constructorform
483
; documentation
484
; attributes
485
; predicates
486
; )
487
488
(defun browseOpen ()
489
"open the constructor database and hash the keys"
490
(let (constructors pos stamp dbstruct)
491
(setq *browse-stream* (open (|pathToDatabase| "browse.daase")))
492
(setq stamp (read *browse-stream*))
493
(unless (equal stamp *browse-stream-stamp*)
494
(when |$verbose|
495
(format t " Re-reading browse.daase"))
496
(setq *browse-stream-stamp* stamp)
497
(setq pos (car stamp))
498
(file-position *browse-stream* pos)
499
(setq constructors (read *browse-stream*))
500
(dolist (item constructors)
501
(unless (setq dbstruct (|constructorDB| (car item)))
502
(format t "browseOpen:~%")
503
(format t "the browse database contains a constructor ~a~%" item)
504
(format t "that is not in the interp.daase file. we cannot~%")
505
(format t "get the database structure for this constructor and~%")
506
(warn "will create a new one~%")
507
(setq dbstruct (|makeDB| (first item)))
508
(setq *allconstructors* (adjoin item *allconstructors*)))
509
(setf (|dbSourceFile| dbstruct) (second item))
510
; (setf (|dbConstructorForm| dbstruct) (third item))
511
(setf (database-documentation dbstruct) (fourth item))
512
; (setf (|dbAttributes| dbstruct) (fifth item))
513
; (setf (|dbPredicates| dbstruct) (sixth item))
514
; (setf (|dbPrincipals| dbstruct) (seventh item))
515
))
516
(format t "~&")))
517
518
(defun categoryOpen ()
519
"open category.daase and hash the keys"
520
(let (pos keys stamp)
521
(setq *category-stream* (open (|pathToDatabase| "category.daase")))
522
(setq stamp (read *category-stream*))
523
(unless (equal stamp *category-stream-stamp*)
524
(when |$verbose|
525
(format t " Re-reading category.daase"))
526
(setq *category-stream-stamp* stamp)
527
(setq pos (car stamp))
528
(file-position *category-stream* pos)
529
(setq keys (read *category-stream*))
530
(setq |$HasCategoryTable| (make-hash-table :test #'equal))
531
(dolist (item keys)
532
(setf (gethash (first item) |$HasCategoryTable|) (second item))))
533
(format t "~&")))
534
535
(defun operationOpen ()
536
"read operation database and hash the keys"
537
(let (operations pos stamp)
538
(setq *operation-stream* (open (|pathToDatabase| "operation.daase")))
539
(setq stamp (read *operation-stream*))
540
(unless (equal stamp *operation-stream-stamp*)
541
(when |$verbose|
542
(format t " Re-reading operation.daase"))
543
(setq *operation-stream-stamp* stamp)
544
(setq pos (car stamp))
545
(file-position *operation-stream* pos)
546
(setq operations (read *operation-stream*))
547
(dolist (item operations)
548
(setf (gethash (car item) *operation-hash*) (cdr item))))
549
(format t "~&")))
550
551
(defun addoperations (constructor oldmaps)
552
"add ops from a )library domain to *operation-hash*"
553
(declare (special *operation-hash*))
554
(dolist (map oldmaps) ; out with the old
555
(let (oldop op)
556
(setq op (car map))
557
(setq oldop (|getOperationFromDB| op))
558
(setq oldop (delete (cdr map) oldop :test #'equal))
559
(setf (gethash op *operation-hash*) oldop)))
560
(dolist (map (|getOperationModemapsFromDB| constructor)) ; in with the new
561
(let (op newmap)
562
(setq op (car map))
563
(setq newmap (|getOperationFromDB| op))
564
(setf (gethash op *operation-hash*) (cons (cdr map) newmap)))))
565
566
(defun showdatabase (constructor)
567
(format t "~&~a: ~a~%" 'constructorkind
568
(|getConstructorKindFromDB| constructor))
569
(format t "~a: ~a~%" 'cosig
570
(|getDualSignature| constructor))
571
(format t "~a: ~a~%" 'operation
572
(|getOperationFromDB| constructor))
573
(format t "~a: ~%" 'constructormodemap)
574
(pprint (|getConstructorModemap| constructor))
575
(format t "~&~a: ~%" 'constructorcategory)
576
(pprint (|getConstructorCategory| constructor))
577
(format t "~&~a: ~%" 'operationalist)
578
(pprint (|getConstructorOperationsFromDB| constructor))
579
(format t "~&~a: ~%" 'modemaps)
580
(pprint (|getOperationModemapsFromDB| constructor))
581
(format t "~a: ~a~%" 'hascategory
582
(|constructorHasCategoryFromDB| constructor))
583
(format t "~a: ~a~%" 'object
584
(|getConstructorModuleFromDB| constructor))
585
(format t "~a: ~a~%" 'abbreviation
586
(|getConstructorAbbreviationFromDB| constructor))
587
(format t "~a: ~a~%" 'constructor?
588
(|getConstructorOperationsFromDB| constructor))
589
(format t "~a: ~a~%" 'constructor
590
(|getConstructorFullNameFromDB| constructor))
591
(format t "~a: ~a~%" 'defaultdomain
592
(|getConstructorDefaultFromDB| constructor))
593
(format t "~a: ~a~%" 'ancestors
594
(|getConstructorAncestorsFromDB| constructor))
595
(format t "~a: ~a~%" 'sourcefile
596
(|getConstructorSourceFileFromDB| constructor))
597
(format t "~a: ~a~%" 'constructorform
598
(|getConstructorFormFromDB| constructor))
599
(format t "~a: ~a~%" 'constructorargs
600
(|getConstructorArgs| constructor))
601
(format t "~a: ~a~%" 'attributes
602
(|getConstructorAttributes| constructor))
603
(format t "~a: ~%" 'predicates)
604
(pprint (|getConstructorPredicates| constructor))
605
(format t "~a: ~a~%" 'documentation
606
(|getConstructorDocumentationFromDB| constructor))
607
(format t "~a: ~a~%" 'parents
608
(|getConstructorParentsFromDB| constructor)))
609
610
(defun setdatabase (constructor key value)
611
(let (struct)
612
(when (symbolp constructor)
613
(unless (setq struct (|constructorDB| constructor))
614
(setq struct (|makeDB| constructor)))
615
(case key
616
(abbreviation
617
(setf (|dbAbbreviation| struct) value)
618
(when (symbolp value)
619
(setf (get value 'abbreviationfor) constructor)))
620
(superdomain
621
(setf (|dbSuperDomain| struct) value))
622
(constructorkind
623
(setf (|dbConstructorKind| struct) value))))))
624
625
(defun deldatabase (constructor key)
626
(when (symbolp constructor)
627
(case key
628
(abbreviation
629
(setf (get constructor 'abbreviationfor) nil)))))
630
631
(defun getdatabase (constructor key)
632
(declare (special *miss*))
633
(when (eq *miss* t)
634
(format t "getdatabase call: ~20a ~a~%" constructor key))
635
(let (data table stream ignore struct)
636
(declare (ignore ignore))
637
(when (or (symbolp constructor)
638
(and (eq key 'hascategory) (consp constructor)))
639
(let ((struct (and (symbolp constructor) (|constructorDB| constructor))))
640
(case key
641
(operation
642
(setq stream *operation-stream*)
643
(setq data (gethash constructor *operation-hash*)))
644
(modemaps
645
(setq stream *interp-stream*)
646
(when struct
647
(setq data (|dbModemaps| struct))))
648
(hascategory
649
(setq table |$HasCategoryTable|)
650
(setq stream *category-stream*)
651
(setq data (gethash constructor table)))
652
(object
653
(setq stream *interp-stream*)
654
(when struct
655
(setq data (|dbModule| struct))))
656
(constructor?
657
(|fatalError| "GETDATABASE called with CONSTRUCTOR?"))
658
(defaultdomain
659
(setq data (cadr (assoc constructor *defaultdomain-list*))))
660
(sourcefile
661
(setq stream *browse-stream*)
662
(when struct
663
(setq data (|dbSourceFile| struct))))
664
(documentation
665
(setq stream *browse-stream*)
666
(when struct
667
(setq data (database-documentation struct))))
668
(users
669
(setq stream *browse-stream*)
670
(when struct
671
(setq data (database-users struct))))
672
(dependents
673
(setq stream *browse-stream*)
674
(when struct
675
(setq data (database-dependents struct))))
676
(otherwise
677
(error "~%(GETDATABASE ~a ~a) failed~%" constructor key)))
678
(when (numberp data) ;fetch the real data
679
(when *miss*
680
(format t "getdatabase miss: ~20a ~a~%" key constructor))
681
(file-position stream data)
682
(setq data (read stream))
683
(case key ; cache the result of the database read
684
(operation
685
(setf (gethash constructor *operation-hash*) data))
686
(hascategory
687
(setf (gethash constructor |$HasCategoryTable|) data))
688
(modemaps
689
(setf (|dbModemaps| struct) data))
690
(object
691
(setf (|dbModule| struct) data))
692
(documentation
693
(setf (database-documentation struct) data))
694
(users
695
(setf (database-users struct) data))
696
(dependents
697
(setf (database-dependents struct) data))
698
(sourcefile
699
(setf (|dbSourceFile| struct) data))))
700
(case key ; fixup the special cases
701
(sourcefile
702
(when (and data (string= (directory-namestring data) "")
703
(string= (pathname-type data) "spad"))
704
(setq data
705
(concatenate 'string
706
(|systemRootDirectory|)
707
"src/algebra/" data))))
708
(object ; fix up system object pathname
709
(if (consp data)
710
(setq data
711
(if (string= (directory-namestring (car data)) "")
712
(|getSystemModulePath| (car data))
713
(car data)))
714
(when (and data (string= (directory-namestring data) ""))
715
(setq data (|getSystemModulePath| data)))))))
716
data)))
717
718
; localdatabase tries to find files in the order of:
719
; NRLIB/index.KAF
720
721
(defun localdatabase (filelist options &optional (make-database? nil))
722
"read a local filename and update the hash tables"
723
(labels
724
((processOptions (options)
725
(let (only dir noexpose)
726
(when (setq only (assoc '|only| options))
727
(setq options (delete only options :test #'equal))
728
(setq only (cdr only)))
729
(when (setq dir (assoc '|dir| options))
730
(setq options (delete dir options :test #'equal))
731
(setq dir (second dir))
732
(when (null dir)
733
(|sayKeyedMsg| 'S2IU0002 nil) ))
734
(when (setq noexpose (assoc '|noexpose| options))
735
(setq options (delete noexpose options :test #'equal))
736
(setq noexpose 't) )
737
(when options
738
(format t " Ignoring unknown )library option: ~a~%" options))
739
(values only dir noexpose)))
740
(processDir (dirarg)
741
(let ((indexFiles (|getAllIndexPathnames| dirarg))
742
(aldorFiles (|getAllAldorObjectFiles| dirarg)))
743
(values
744
indexFiles
745
;; At the moment we will only look for user.lib: others
746
;; are taken care of by localnrlib.
747
nil
748
))))
749
(let (thisdir nrlibs libs object only dir key
750
(|$forceDatabaseUpdate| t) noexpose)
751
(declare (special |$forceDatabaseUpdate|))
752
(setq thisdir (|getWorkingDirectory|))
753
(setq noexpose nil)
754
(multiple-value-setq (only dir noexpose) (processOptions options))
755
;don't force exposure during database build
756
(if make-database?
757
(setq noexpose t))
758
(if dir
759
(multiple-value-setq (nrlibs libs)
760
(processDir (|ensureTrailingSlash| (string dir)))))
761
(dolist (file filelist)
762
(let ((filename (pathname-name file))
763
(namedir (directory-namestring file)))
764
(unless namedir
765
(setq thisdir (concatenate 'string thisdir "/")))
766
(cond
767
((setq file (probe-file
768
(concatenate 'string
769
namedir
770
filename
771
".NRLIB/"
772
|$IndexFilename|)))
773
(push (namestring file) nrlibs))
774
('else (format t " )library cannot find the file ~a.~%" filename)))))
775
(dolist (file (|reverse!| nrlibs))
776
(setq key (pathname-name (first (last (pathname-directory file)))))
777
(setq object (concatenate 'string
778
(directory-namestring file)
779
"code." |$faslType|))
780
(localnrlib key file object make-database? noexpose))
781
(HCLEAR |$ConstructorCache|))))
782
783
784
(defun localnrlib (key nrlib object make-database? noexpose)
785
"given a string pathname of an index.KAF and the object update the database"
786
(labels
787
((fetchdata (alist in index)
788
(let (pos)
789
(setq pos (third (assoc index alist :test #'string=)))
790
(when pos
791
(file-position in pos)
792
(read in)))))
793
(let (alist kind (systemdir? nil) pos
794
constructorform oldmaps abbrev dbstruct)
795
(with-open-file (in nrlib)
796
(file-position in (read in))
797
(setq alist (read in))
798
(setq pos (third (assoc "constructorForm" alist :test #'string=)))
799
(file-position in pos)
800
(setq constructorform (read in))
801
(setq key (car constructorform))
802
(setq oldmaps (|getOperationModemapsFromDB| key))
803
(setq dbstruct (|makeDB| key))
804
(setq *allconstructors* (adjoin key *allconstructors*))
805
(setf (|dbConstructorForm| dbstruct) constructorform)
806
(setq *allOperations* nil) ; force this to recompute
807
(setf (|dbModule| dbstruct) object)
808
(setq abbrev
809
(intern (pathname-name (first (last (pathname-directory object))))))
810
(setf (|dbAbbreviation| dbstruct) abbrev)
811
(setf (get abbrev 'abbreviationfor) key)
812
(setf (|dbOperations| dbstruct) nil)
813
(setf (|dbOperations| dbstruct)
814
(fetchdata alist in "operationAlist"))
815
(setf (|dbConstructorModemap| dbstruct)
816
(fetchdata alist in "constructorModemap"))
817
(setf (|dbModemaps| dbstruct)
818
(fetchdata alist in "modemaps"))
819
(setf (|dbSourceFile| dbstruct)
820
(fetchdata alist in "sourceFile"))
821
(when make-database?
822
(setf (|dbSourceFile| dbstruct)
823
(file-namestring (|dbSourceFile| dbstruct))))
824
(setf (|dbConstructorKind| dbstruct)
825
(setq kind (fetchdata alist in "constructorKind")))
826
(setf (|dbCategory| dbstruct)
827
(fetchdata alist in "constructorCategory"))
828
(setf (database-documentation dbstruct)
829
(fetchdata alist in "documentation"))
830
(setf (|dbAttributes| dbstruct)
831
(fetchdata alist in "attributes"))
832
(setf (|dbPredicates| dbstruct)
833
(fetchdata alist in "predicates"))
834
(setf (|dbSuperDomain| dbstruct)
835
(fetchdata alist in "superDomain"))
836
(addoperations key oldmaps)
837
(unless make-database?
838
(|updateDatabase| key key systemdir?) ;makes many hashtables???
839
(|installConstructor| key kind) ;used to be key cname ...
840
(|updateCategoryTable| key kind)
841
(if |$InteractiveMode|
842
(setq |$CategoryFrame| |$EmptyEnvironment|)))
843
(setf (|dbDualSignature| dbstruct)
844
(fetchdata alist in "dualSignature"))
845
(setf (|dbLoadPath| (|constructorDB| key)) nil)
846
(if (null noexpose)
847
(|setExposeAddConstr| (cons key nil)))
848
(setf (symbol-function key) ; sets the autoload property for cname
849
#'(lambda (&rest args)
850
(unless (|dbLoaded?| (|constructorDB| key))
851
(|startTimingProcess| '|load|)
852
(|loadLibNoUpdate| key key object)) ; used to be cname key
853
(apply key args)))
854
(|sayKeyedMsg| 'S2IU0001 (list key object))))))
855
856
; making new databases consists of:
857
; 1) reset all of the system hash tables
858
; *) set up Union, Record and Mapping
859
; 2) map )library across all of the system files (fills the databases)
860
; 3) loading some normally autoloaded files
861
; 4) making some database entries that are computed (like ancestors)
862
; 5) writing out the databases
863
; 6) write out 'warm' data to be loaded into the image at build time
864
; note that this process should be done in a clean image
865
; followed by a rebuild of the system image to include
866
; the new index pointers (e.g. *interp-stream-stamp*)
867
; the system will work without a rebuild but it needs to
868
; re-read the databases on startup. rebuilding the system
869
; will cache the information into the image and the databases
870
; are opened but not read, saving considerable startup time.
871
; also note that the order the databases are written out is
872
; critical. interp.daase depends on prior computations and has
873
; to be written out last.
874
875
(defun make-databases (dirlist)
876
(labels (
877
;; these are types which have no library object associated with them.
878
;; we store some constructed data to make them perform like library
879
;; objects, the *operationalist-hash* key entry is used by allConstructors
880
(withSpecialConstructors ()
881
; note: if item is not in *operationalist-hash* it will not be written
882
; UNION
883
(setf (|constructorDB| '|Union|)
884
(make-database :operationalist nil :constructorkind '|domain|))
885
(push '|Union| *allconstructors*)
886
; RECORD
887
(setf (|constructorDB| '|Record|)
888
(make-database :operationalist nil :constructorkind '|domain|))
889
(push '|Record| *allconstructors*)
890
; MAPPING
891
(setf (|constructorDB| '|Mapping|)
892
(make-database :operationalist nil :constructorkind '|domain|))
893
(push '|Mapping| *allconstructors*)
894
; ENUMERATION
895
(setf (|constructorDB| '|Enumeration|)
896
(make-database :operationalist nil :constructorkind '|domain|))
897
(push '|Enumeration| *allconstructors*)
898
)
899
(final-name (root)
900
(concat root ".daase"))
901
)
902
(let ((ancestors-table (make-hash-table :test #'eq))
903
d)
904
(declare (special |$constructorList|))
905
(do-symbols (symbol)
906
(when (|constructorDB| symbol)
907
(setf (|constructorDB| symbol) nil)))
908
(setq |$HasCategoryTable| (make-hash-table :test #'equal))
909
(setq *operation-hash* (make-hash-table))
910
(setq *allconstructors* nil)
911
(withSpecialConstructors)
912
(localdatabase nil
913
(list (list '|dir| (|getWorkingDirectory|) ))
914
'make-database)
915
(dolist (dir dirlist)
916
(localdatabase nil
917
(list (list '|dir|
918
(namestring (probe-file
919
(concat "./"
920
dir)))))
921
'make-database))
922
#+:AKCL (|mkTopicHashTable|)
923
(setq |$constructorList| nil) ;; affects buildLibdb
924
(|buildLibdb|)
925
(|dbSplitLibdb|)
926
; (|dbAugmentConstructorDataTable|)
927
(|mkUsersHashTable|)
928
(|saveUsersHashTable|)
929
(|mkDependentsHashTable|)
930
(|saveDependentsHashTable|)
931
(|buildGloss|)
932
(write-browsedb)
933
(write-operationdb)
934
(write-categorydb ancestors-table)
935
(dolist (con (|allConstructors|))
936
(let (dbstruct)
937
(when (setq dbstruct (|constructorDB| con))
938
(setf (|dbDualSignature| dbstruct)
939
(cons nil (mapcar #'|categoryForm?|
940
(cddar (|dbConstructorModemap| dbstruct)))))
941
(when (and (eq (|dbConstructorKind| dbstruct) '|category|)
942
(= (length (setq d (|domainsOf| (list con) NIL NIL))) 1))
943
(setq d (caar d))
944
(when (= (length d) (length (|dbConstructorForm| dbstruct)))
945
(format t " ~a has a default domain of ~a~%" con (car d))
946
(setf (|dbDefaultDomain| dbstruct) (car d)))))))
947
(write-interpdb ancestors-table)
948
#+:AKCL (write-warmdata)
949
(when (probe-file (final-name "interp"))
950
(delete-file (final-name "interp")))
951
(rename-file "interp.build" (final-name "interp"))
952
(when (probe-file (final-name "operation"))
953
(delete-file (final-name "operation")))
954
(rename-file "operation.build" (final-name "operation"))
955
(when (probe-file (final-name "browse"))
956
(delete-file (final-name "browse")))
957
(rename-file "browse.build"
958
(final-name "browse"))
959
(when (probe-file (final-name "category"))
960
(delete-file (final-name "category")))
961
(rename-file "category.build"
962
(final-name "category")))))
963
964
(defun write-interpdb (ancestors-table)
965
"build interp.daase from hash tables"
966
(let (opalistpos modemapspos cmodemappos master masterpos obj *print-pretty*
967
concategory categorypos kind cosig abbrev defaultdomain
968
ancestors ancestorspos superpos out)
969
(print "building interp.daase")
970
(setq out (open "interp.build" :direction :output))
971
(princ " " out)
972
(finish-output out)
973
(dolist (constructor (|allConstructors|))
974
(let (struct)
975
(setq struct (|constructorDB| constructor))
976
(setq opalistpos (file-position out))
977
(print (|dbOperations| struct) out)
978
(finish-output out)
979
(setq cmodemappos (file-position out))
980
(print (|dbConstructorModemap| struct) out)
981
(finish-output out)
982
(setq modemapspos (file-position out))
983
(print (|dbModemaps| struct) out)
984
(finish-output out)
985
(let ((entry (|dbModule| struct)))
986
(cond ((consp entry)
987
(setq obj (cons (pathname-name (car entry))
988
(cdr entry))))
989
(entry
990
(setq obj (pathname-name
991
(first (last (pathname-directory entry))))))
992
(t (setq obj nil))))
993
(setq concategory (|dbCategory| struct))
994
(if concategory ; if category then write data else write nil
995
(progn
996
(setq categorypos (file-position out))
997
(print concategory out)
998
(finish-output out))
999
(setq categorypos nil))
1000
(setq abbrev (|dbAbbreviation| struct))
1001
(setq cosig (|dbDualSignature| struct))
1002
(setq kind (|dbConstructorKind| struct))
1003
(setq defaultdomain (|dbDefaultDomain| struct))
1004
(setq ancestors (gethash constructor ancestors-table))
1005
(if ancestors
1006
(progn
1007
(setq ancestorspos (file-position out))
1008
(print ancestors out)
1009
(finish-output out))
1010
(setq ancestorspos nil))
1011
(setq superpos
1012
(let ((super (|dbSuperDomain| struct)))
1013
(when super
1014
(prog1 (file-position out)
1015
(print (list (car super) (second super)) out)
1016
(finish-output out)))))
1017
1018
(push (list constructor opalistpos cmodemappos modemapspos
1019
obj categorypos abbrev cosig kind defaultdomain
1020
ancestorspos superpos) master)))
1021
(finish-output out)
1022
(setq masterpos (file-position out))
1023
(print master out)
1024
(finish-output out)
1025
(file-position out 0)
1026
(print (cons masterpos (get-universal-time)) out)
1027
(finish-output out)
1028
(close out)))
1029
1030
(defun write-browsedb ()
1031
"make browse.daase from hash tables"
1032
(let (master masterpos src formpos docpos attpos predpos *print-pretty* out)
1033
(print "building browse.daase")
1034
(setq out (open "browse.build" :direction :output))
1035
(princ " " out)
1036
(finish-output out)
1037
(dolist (constructor (|allConstructors|))
1038
(let (struct)
1039
(setq struct (|constructorDB| constructor))
1040
; sourcefile is small. store the string directly
1041
(setq src (|dbSourceFile| struct))
1042
(setq formpos (file-position out))
1043
(print (|dbConstructorForm| struct) out)
1044
(finish-output out)
1045
(setq docpos (file-position out))
1046
(print (database-documentation struct) out)
1047
(finish-output out)
1048
(setq attpos (file-position out))
1049
(print (|dbAttributes| struct) out)
1050
(finish-output out)
1051
(setq predpos (file-position out))
1052
(print (|dbPredicates| struct) out)
1053
(finish-output out)
1054
(push (list constructor src formpos docpos attpos predpos) master)))
1055
(finish-output out)
1056
(setq masterpos (file-position out))
1057
(print master out)
1058
(finish-output out)
1059
(file-position out 0)
1060
(print (cons masterpos (get-universal-time)) out)
1061
(finish-output out)
1062
(close out)))
1063
1064
(defun write-categorydb (ancestors-table)
1065
"make category.daase from scratch. contains the $HasCategoryTable table"
1066
(let (out master pos *print-pretty*)
1067
(print "building category.daase")
1068
(|generateCategoryTable| ancestors-table)
1069
(setq out (open "category.build" :direction :output))
1070
(princ " " out)
1071
(finish-output out)
1072
(maphash #'(lambda (key value)
1073
(if (or (null value) (eq value t))
1074
(setq pos value)
1075
(progn
1076
(setq pos (file-position out))
1077
(print value out)
1078
(finish-output out)))
1079
(push (list key pos) master))
1080
|$HasCategoryTable|)
1081
(setq pos (file-position out))
1082
(print master out)
1083
(finish-output out)
1084
(file-position out 0)
1085
(print (cons pos (get-universal-time)) out)
1086
(finish-output out)
1087
(close out)))
1088
1089
(defun write-operationdb ()
1090
(let (pos master out)
1091
(declare (special leaves))
1092
(setq out (open "operation.build" :direction :output))
1093
(princ " " out)
1094
(finish-output out)
1095
(maphash #'(lambda (key value)
1096
(setq pos (file-position out))
1097
(print value out)
1098
(finish-output out)
1099
(push (cons key pos) master))
1100
*operation-hash*)
1101
(finish-output out)
1102
(setq pos (file-position out))
1103
(print master out)
1104
(file-position out 0)
1105
(print (cons pos (get-universal-time)) out)
1106
(finish-output out)
1107
(close out)))
1108
1109
(defun write-warmdata ()
1110
"write out information to be loaded into the image at build time"
1111
(declare (special |$topicHash|))
1112
(with-open-file (out "warm.data" :direction :output)
1113
(format out "(in-package \"BOOT\")~%")
1114
(format out "(setq |$topicHash| (make-hash-table))~%")
1115
(maphash #'(lambda (k v)
1116
(format out "(setf (gethash '|~a| |$topicHash|) ~a)~%" k v)) |$topicHash|)))
1117
1118
(defun |allConstructors| ()
1119
(declare (special *allconstructors*))
1120
*allconstructors*)
1121
1122
(defun |allOperations| ()
1123
(declare (special *allOperations*))
1124
(unless *allOperations*
1125
(maphash #'(lambda (k v) (declare (ignore v)) (push k *allOperations*))
1126
*operation-hash*))
1127
*allOperations*)
1128
1129