Initial commit
commit
12040bc919
@ -0,0 +1,35 @@
|
||||
NAME=lispos
|
||||
|
||||
TEXFILES=$(NAME).tex $(shell ./tex-dependencies $(NAME).tex)
|
||||
BIBFILES=$(NAME).bib
|
||||
PDF_T=$(shell ./strip-dependence inputfig $(TEXFILES))
|
||||
VERBATIM=$(shell ./strip-dependence verbatimtabinput $(TEXFILES))
|
||||
CODEFILES=$(shell ./strip-dependence inputcode $(TEXFILES))
|
||||
PDF=$(subst .pdf_t,.pdf,$(PDF_T))
|
||||
|
||||
all : $(NAME).pdf
|
||||
|
||||
%.pdf: %.fig
|
||||
fig2dev -Lpdftex -m 0.75 $< $@
|
||||
|
||||
%.pdf_t: %.fig %.pdf
|
||||
fig2dev -Lpdftex_t -m 0.75 -p $(basename $<).pdf $< $@
|
||||
|
||||
%.code: %.lisp
|
||||
./codify $<
|
||||
|
||||
$(NAME).pdf: $(TEXFILES) $(PDF) $(PDF_T) $(VERBATIM) $(CODEFILES) $(BIBFILES)
|
||||
pdflatex $<
|
||||
makeindex $(NAME)
|
||||
bibtex $(NAME)
|
||||
pdflatex $<
|
||||
pdflatex $<
|
||||
|
||||
view: $(NAME).pdf
|
||||
xpdf $<
|
||||
|
||||
clean:
|
||||
rm -f *.aux *.log *~ *.pdf *.pdf *.pdf_t *.bbl *.blg
|
||||
|
||||
spotless: clean
|
||||
rm -f *.ps *.dvi *.pdf *.pdf_t *.toc *.idx *.ilg *.ind *.fig.bak
|
@ -0,0 +1,94 @@
|
||||
\chapter{All standard macros}
|
||||
\label{app-all-standard-macros}
|
||||
|
||||
\texttt{and}
|
||||
\texttt{assert}
|
||||
\texttt{call-method}
|
||||
\texttt{case}
|
||||
\texttt{ccase}
|
||||
\texttt{check-type}
|
||||
\texttt{cond}
|
||||
\texttt{ctypecase}
|
||||
\texttt{declaim}
|
||||
\texttt{decf}
|
||||
\texttt{defclass}
|
||||
\texttt{defconstant}
|
||||
\texttt{defgeneric}
|
||||
\texttt{define-compiler-macro}
|
||||
\texttt{define-condition}
|
||||
\texttt{define-method-combination}
|
||||
\texttt{define-modify-macro}
|
||||
\texttt{define-setf-expander}
|
||||
\texttt{define-symbol-macro}
|
||||
\texttt{defmacro}
|
||||
\texttt{defmethod}
|
||||
\texttt{defpackage}
|
||||
\texttt{defparameter}
|
||||
\texttt{defsetf}
|
||||
\texttt{defstruct}
|
||||
\texttt{deftype}
|
||||
\texttt{defun}
|
||||
\texttt{defvar}
|
||||
\texttt{destructuring-bind}
|
||||
\texttt{do}
|
||||
\texttt{do*}
|
||||
\texttt{do-all-symbols}
|
||||
\texttt{do-external-symbols}
|
||||
\texttt{do-symbols}
|
||||
\texttt{dolist}
|
||||
\texttt{dotimes}
|
||||
\texttt{ecase}
|
||||
\texttt{etypecase}
|
||||
\texttt{formatter}
|
||||
\texttt{handler-bind}
|
||||
\texttt{handler-case}
|
||||
\texttt{ignore-errors}
|
||||
\texttt{in-package}
|
||||
\texttt{incf}
|
||||
\texttt{lambda}
|
||||
\texttt{loop}
|
||||
\texttt{loop-finish}
|
||||
\texttt{multiple-value-bind}
|
||||
\texttt{multiple-value-list}
|
||||
\texttt{multiple-value-setq}
|
||||
\texttt{nth-value}
|
||||
\texttt{or}
|
||||
\texttt{pop}
|
||||
\texttt{pprint-exit-if-list-exhausted}
|
||||
\texttt{pprint-logical-block}
|
||||
\texttt{pprint-pop}
|
||||
\texttt{print-unreadable-object}
|
||||
\texttt{prog}
|
||||
\texttt{prog*}
|
||||
\texttt{prog1}
|
||||
\texttt{prog2}
|
||||
\texttt{psetf}
|
||||
\texttt{psetq}
|
||||
\texttt{push}
|
||||
\texttt{pushnew}
|
||||
\texttt{remf}
|
||||
\texttt{restart-bind}
|
||||
\texttt{restart-case}
|
||||
\texttt{return}
|
||||
\texttt{rotatef}
|
||||
\texttt{setf}
|
||||
\texttt{shiftf}
|
||||
\texttt{step}
|
||||
\texttt{time}
|
||||
\texttt{trace}
|
||||
\texttt{typecase}
|
||||
\texttt{unless}
|
||||
\texttt{untrace}
|
||||
\texttt{when}
|
||||
\texttt{with-accessors}
|
||||
\texttt{with-compilation-unit}
|
||||
\texttt{with-condition-restarts}
|
||||
\texttt{with-hash-table-iterator}
|
||||
\texttt{with-input-from-string}
|
||||
\texttt{with-open-file}
|
||||
\texttt{with-open-stream}
|
||||
\texttt{with-output-to-string}
|
||||
\texttt{with-package-iterator}
|
||||
\texttt{with-simple-restart}
|
||||
\texttt{with-slots}
|
||||
\texttt{with-standard-io-syntax}
|
@ -0,0 +1,55 @@
|
||||
\chapter{Environments}
|
||||
\label{chap-environments}
|
||||
|
||||
Recall that an \emph{environment} is a mapping from \emph{names} to
|
||||
\emph{objects}. This mapping consists of a set of \emph{bindings}.
|
||||
|
||||
When a user is created in the system, a \emph{default global
|
||||
environment} is created for that user. The global environment of a
|
||||
user consists of a \emph{system-wide} environment and a
|
||||
\emph{user-specific} environment.
|
||||
|
||||
The system-wide environment consists of bindings that are themselves
|
||||
immutable (i.e., the user is not allowed to alter the binding) such as
|
||||
the binding of the symbol \texttt{cl:length} to the function that
|
||||
returns the length of a sequence. The objects of these bindings are
|
||||
also immutable, such as the length function itself. The system-wide
|
||||
environment is the same for every user, allowing the installation of
|
||||
software that is immediately visible to all users.
|
||||
|
||||
The user-specific environment consists of bindings that are created by
|
||||
the user. These bindings are of three different kinds:
|
||||
|
||||
\begin{itemize}
|
||||
\item Bindings created by the user for instance as a result of
|
||||
executing a \texttt{defparameter} or \texttt{defun} form.
|
||||
\item Default system-wide bindings that can be altered by the user,
|
||||
such as the value of \texttt{*print-base*}.
|
||||
\item Immutable bindings where the \emph{object} can be modified by
|
||||
the user, such as system-defined generic functions to which the user
|
||||
is allowed to add specific methods. Each user has a private copy of
|
||||
such objects.
|
||||
\end{itemize}
|
||||
|
||||
When a function or method object is created as a result of calling
|
||||
\texttt{compile} on a lambda expression, or as a result of loading a
|
||||
\emph{fasl} file, the object is \emph{linked} to the current global
|
||||
environment, in that external references are then resolved. When such
|
||||
a function or method object is given to a different user, that
|
||||
different user can execute it, but external references in it will
|
||||
still refer to the environment into which it was compiled or loaded.
|
||||
|
||||
This mechanism provides an efficient method of protection. A user A
|
||||
can grant controlled access to part of his or her global environment
|
||||
by allowing a user B to execute a function made available to him or
|
||||
her through the \emph{object store}. \seechap{chap-object-store}
|
||||
In a traditional modern operating system such as Unix, this kind of
|
||||
controlled access required the use of the \emph{setuid} mechanism,
|
||||
simply because in such a system there is no way to access an object
|
||||
other than through the global file system, and the accessing user must
|
||||
have the right permissions to access the object.
|
||||
|
||||
The same mechanism can be used by the system itself to protect objects
|
||||
that would be unwise to give users direct access to, such as disks or
|
||||
printers.
|
||||
|
@ -0,0 +1,311 @@
|
||||
\chapter{Introduction}
|
||||
\pagenumbering{arabic}
|
||||
|
||||
\section{What a Lisp operating system is}
|
||||
|
||||
A Lisp Operating System (LispOS for short) is not just another
|
||||
operating system that happens to be written in Lisp (although that
|
||||
would be a good thing in itself). A LispOS is also an operating
|
||||
system that uses the Lisp interactive environment as an inspiration
|
||||
for the interface between the user and the system, and between
|
||||
applications and the system.
|
||||
|
||||
In this document, we give some ideas on what a LispOS might contain,
|
||||
how it would be different from existing operating systems, and how
|
||||
such a system might be created.
|
||||
|
||||
\section{Problems with existing systems}
|
||||
|
||||
\subsection{The concept of a \emph{process}}
|
||||
|
||||
Most popular existing operating systems are derived from Unix which
|
||||
was written in the 1970s. The computers for which Unix was intended
|
||||
has a very small address space; too small for most usable end-user
|
||||
applications. To solve this problem, the creators of Unix used the
|
||||
concept of a \emph{process}. A large application was written so
|
||||
that it consisted of several smaller programs, each of which ran in
|
||||
its own address space. These smaller programs would communicate by
|
||||
having one application write text to its output stream for another
|
||||
application to read. This method of communication was called
|
||||
a \emph{pipe} and a sequence of small applications was called
|
||||
a \emph{pipeline}. As a typical example of a chain of applications,
|
||||
consider the pipeline for producing a typeset document (one of the
|
||||
main applications for which Unix was designed). This chain had a
|
||||
program for creating tables (called \texttt{tbl}), a program for
|
||||
generating pictures (called \texttt{pic}), a program for generating
|
||||
equations (called \texttt{eqn}), and of course the typesetting program
|
||||
itself (called \texttt{troff}).
|
||||
|
||||
Using pipes to communicate between different components of an
|
||||
application has several disadvantages:
|
||||
|
||||
\begin{itemize}
|
||||
\item To communicate complex data structures (such as trees or
|
||||
graphs), they must be converted to a stream of bytes by the
|
||||
creating component, and it must be analyzed and parsed into an
|
||||
equivalent data structure by the using component. Not only is
|
||||
this unparsing/parsing inefficient in terms of computing
|
||||
resources, but it is also problematic from a
|
||||
software-engineering point of view, because the external format
|
||||
must be specified and maintained as a separate aspect of each
|
||||
component.
|
||||
\item An artificial \emph{order} between the different components is
|
||||
imposed, so that components can not work as libraries that other
|
||||
components can use in any order. Sometimes (as in the example
|
||||
of the \texttt{troff} chain) the end result of a computation
|
||||
depends in subtle ways on the order between the components of
|
||||
the chain. Introducing a new component may require other
|
||||
components to be modified.
|
||||
\end{itemize}
|
||||
|
||||
It is an interesting observation that in most text books on
|
||||
operating systems, the concept of a process is presented as playing
|
||||
a central role in operating-system design, whereas it ought to be
|
||||
presented as an unfortunate necessity due to the limited address
|
||||
space of existing minicomputers in the 1970s. It is also presented
|
||||
as \emph{the} method for obtaining some kind of \emph{security},
|
||||
preventing one application from intentionally or accidentally
|
||||
modifying the data of some other application. In reality, there are
|
||||
several ways of obtaining such security, and separate address spaces
|
||||
should be considered to be a method with too many disadvantages.
|
||||
|
||||
Nowadays, computers have addresses that are 64 bit wide, making it
|
||||
possible to address almost 20 exabytes of data. To get an idea of
|
||||
the order of magnitude of such a number, consider a fairly large
|
||||
disc that can hold a terabyte of data. Then 20 million such discs
|
||||
can be directly addressed by the processor. We can thus consider
|
||||
the problem of too small an address space to be solved.
|
||||
|
||||
\subsection{Hierarchical file systems}
|
||||
|
||||
Existing operating system come with a \emph{hierarchical file
|
||||
system}. There are two significant problems,
|
||||
namely \emph{hierarchical} and \emph{file}.
|
||||
|
||||
The \emph{ hierarchy} is also a concept that dates back to the
|
||||
1970s, and it was considered a vast improvement on flat file
|
||||
systems. However, as some authors%
|
||||
\footnote{See
|
||||
\texttt{http://www.shirky.com/writings/ontology\_overrated.html}}
|
||||
explain, most things are not naturally hierarchical. A hierarchical
|
||||
organization imposes an artificial order between names. Whether a
|
||||
document is called \texttt{Lisp/Programs/2013/stuff},
|
||||
\texttt{Programs/Lisp/2013/stuff}, or something else like
|
||||
\texttt{2013/Programs/Lisp/stuff}, is usually not important.
|
||||
|
||||
The problem with a \emph{file} is that it is only a sequence of
|
||||
bytes with no structure. This lack of structure fits the Unix pipe
|
||||
model very well, because intermediate steps between individual
|
||||
software components can be saved to a file without changing the
|
||||
result. But it also means that in order for complex data structures
|
||||
to be stored in the file system, they have to be transformed into a
|
||||
sequence of bytes. And whenever such a structure needs to be
|
||||
modified by some application, it must again be parsed and
|
||||
transformed into an in-memory structure.
|
||||
|
||||
\subsection{Distinction between primary and secondary memory}
|
||||
|
||||
Current system (at least for desktop computers) make a very clear
|
||||
distinction between primary and secondary memory. Not only are the
|
||||
two not the same, but they also have totally different semantics:
|
||||
\begin{itemize}
|
||||
\item Primary memory is \emph{volatile}. When power is turned off,
|
||||
whatever was in primary memory is lost.
|
||||
\item Secondary memory is \emph{permanent}. Stored data will not
|
||||
disappear when power is turned off.
|
||||
\end{itemize}
|
||||
|
||||
This distinction coupled with the semantics of the two memories
|
||||
creates a permanent conundrum for the user of most applications, in
|
||||
that if current application data is \emph{not} saved, then it will
|
||||
be lost in case of power loss, and if it \emph{is} saved, then
|
||||
previously saved data is forever lost.
|
||||
|
||||
Techniques were developed as early in the 1960s for presenting
|
||||
primary and secondary memory as a single abstraction to the user.
|
||||
For example, the Multics system had a single hierarchy of fixed-size
|
||||
byte arrays (called segments) that served as permanent storage, but
|
||||
that could also be treated as any in-memory array by applications.
|
||||
As operating systems derived from Unix became widespread, these
|
||||
techniques were largely forgotten.
|
||||
|
||||
\section{Objectives for a Lisp operating system}
|
||||
|
||||
The three main objectives of a Lisp operating system correspond to
|
||||
solutions to the two main problems with exiting systems as indicated
|
||||
in the previous section.
|
||||
|
||||
\subsection{Single address space}
|
||||
|
||||
Instead of each application having its own address space, we propose
|
||||
that all applications share a single large address space. This way,
|
||||
applications can share data simply by passing pointers around,
|
||||
because a pointer is globally valid, unlike pointers in current
|
||||
operating systems.
|
||||
|
||||
Clearly, if there is a single address space shared by all
|
||||
applications, there needs to be a different mechanism to
|
||||
ensure \emph{protection} between them so that one application can
|
||||
not intentionally or accidentally destroy the data of another
|
||||
application. Most high-level programming languages (in particular
|
||||
Lisp, but also Java, and many more) propose a solution to this
|
||||
problem by simply not allowing users to execute arbitrary machine
|
||||
code. Instead, they allow only code that has been produced from the
|
||||
high-level notation of the language and which excludes arbitrary
|
||||
pointer arithmetic so that the application can only address its own
|
||||
data. This technique is sometimes called "trusted compiler".
|
||||
|
||||
It might sometimes be desirable to write an application in a
|
||||
low-level language like C or even assembler, or it might be
|
||||
necessary to run applications that have been written for other
|
||||
systems. Such applications could co-exist with the normal ones, but
|
||||
they would have to work in their own address space as with current
|
||||
operating systems, and with the same difficulties of communicating
|
||||
with other applications.
|
||||
|
||||
\subsection{Object store based on tags}
|
||||
|
||||
Instead of a hierarchical file system, we propose an \emph{object
|
||||
store} which can contain any objects. If a file (i.e. a
|
||||
sequence of bytes) is desired, it would be stored as an array of
|
||||
bytes.
|
||||
|
||||
Instead of organizing the objects into a hierarchy, objects in the
|
||||
store can optionally be associated with an arbitrary number
|
||||
of \emph{tags}. These tags are \emph{key/value} pairs, such as for
|
||||
example the date of creation of the archive entry, the creator (a
|
||||
user) of the archive entry, and the \emph{access permissions} for
|
||||
the entry. Notice that tags are not properties of the objects
|
||||
themselves, but only of the archive entry that allows an object to
|
||||
be accessed. Some tags might be derived from the contents of the
|
||||
object being stored such as the \emph{sender} or the \emph{date} of
|
||||
an email message. It should be possible to accomplish most searches
|
||||
of the store without accessing the objects themselves, but only the
|
||||
tags. Occasionally, contents must be accessed such as when a raw
|
||||
search of the contents of a text is wanted.
|
||||
|
||||
For a more detailed description of the object store, see
|
||||
\refChap{chap-object-store}.
|
||||
|
||||
It is sometimes desirable to group related objects together as
|
||||
with \emph{directories} of current operating systems. Should a user
|
||||
want such a group, it would simply be another object (say instances
|
||||
of the class \texttt{directory}) in the store. Users who can not
|
||||
adapt to a non-hierarchical organization can even store such
|
||||
directories as one of the objects inside another directory.
|
||||
|
||||
Here are some examples of possible keyword/value pairs, how they
|
||||
might be used, and what kinds of values are permitted:
|
||||
|
||||
\newcolumntype{Y}{>{\raggedright\arraybackslash}X}
|
||||
|
||||
|
||||
When (a pointer to) an object is returned to a user as a result of a
|
||||
search of the object store, it is actually similar to what is called
|
||||
a "capability" in the operating-system literature. Such a
|
||||
capability is essentially only a pointer with a few bits indicating
|
||||
what \emph{access rights} the user has to the objects. Each creator
|
||||
may interpret the contents of those bits as he or she likes, but
|
||||
typically they would be used to restrict access, so that for
|
||||
instance executing a \emph{reader} method is allowed, but executing
|
||||
a \emph{writer} method is not.
|
||||
|
||||
\subsection{Single memory abstraction}
|
||||
|
||||
Instead of two different memory abstractions (primary and
|
||||
secondary), the Lisp operating system would contain a single
|
||||
abstraction which looks like any interactive Lisp system, except
|
||||
that data is permanent.
|
||||
|
||||
Since data is permanent, application writers are encouraged to
|
||||
provide a sophisticated \emph{undo} facility.
|
||||
|
||||
The physical main (semiconductor) memory of the computer simply acts
|
||||
as a \emph{cache} for the disk(s), so that the address of an object
|
||||
uniquely determines where on the disk it is stored. The cache is
|
||||
managed as an ordinary \emph{virtual memory} with existing
|
||||
algorithms.
|
||||
|
||||
\subsection{Other features}
|
||||
|
||||
\subsubsection{Crash proof (maybe)}
|
||||
|
||||
There is extensive work on crash-proof systems, be it operating
|
||||
systems or data base systems. In our opinion, this work is
|
||||
confusing in that the objective is not clearly stated.
|
||||
|
||||
Sometimes the objective is stated as the desire that no data be lost
|
||||
when power is lost. But the solution to that problem already exists
|
||||
in every laptop computer; it simply provides a \emph{battery} that
|
||||
allow the system to continue to work, or to be \emph{shut down} in a
|
||||
controlled way.
|
||||
|
||||
Other times, the objective is stated as a protection against
|
||||
defective software, so that data is stored at regular intervals
|
||||
(checkpointing) perhaps combined with a \emph{transaction log} so
|
||||
that the state of the system immediately before a crash can always
|
||||
be recovered. But it is very hard to protect oneself against
|
||||
defective software. There can be defects in the checkpointing code
|
||||
or in the code for logging transactions, and there can be defects in
|
||||
the underlying file system. We believe that it is a better use of
|
||||
developer time to find and eliminate defects than to aim for a
|
||||
recovery as a result of existing defects.
|
||||
|
||||
\subsubsection{Multiple simultaneous environments}
|
||||
|
||||
To allow for a user to add methods to standard generic functions
|
||||
(such as \texttt{print-object}) without interfering with other
|
||||
users, we suggest that each user gets a different \emph{global
|
||||
environment}. The environment maps \emph{names}
|
||||
to \emph{objects} such as functions, classes, types, packages, and
|
||||
more. Immutable objects (such as the \texttt{common-lisp} package)
|
||||
can exist in several different environments simultaneously, but
|
||||
objects (such as the generic function \texttt{print-object} would be
|
||||
different in different environments.
|
||||
|
||||
Multiple environments would also provide more safety for users in
|
||||
that if a user inadvertently removes some system feature, then it
|
||||
can be recovered from a default environment, and in the worst case a
|
||||
fresh default environment could be installed for a user who
|
||||
inadvertently destroyed large parts of his or her environment.
|
||||
|
||||
Finally, multiple environments would simplify experimentation with
|
||||
new features without running the risk of destroying the entire
|
||||
system. Different versions of a single package could exist in
|
||||
different environments.
|
||||
|
||||
\section{How to accomplish it}
|
||||
|
||||
The most important aspect of a Lisp operating system is not that all
|
||||
the code be written in Lisp, but rather to present a Lisp-like
|
||||
interface between users and the system and between applications and
|
||||
the system. It is therefore legitimate to take advantage of some
|
||||
existing system (probably Linux or some BSD version) in order to
|
||||
provide services such as device drivers, network communication,
|
||||
thread scheduling, etc.
|
||||
|
||||
\subsection{Create a Lisp system to be used as basis}
|
||||
|
||||
The first step is to create a Common Lisp system that can be used as
|
||||
a basis for the Lisp operating system. It should already allow for
|
||||
multiple environments, and it should be available on 64-bit
|
||||
platforms. Preferably, this system should use as little C code as
|
||||
possible and interact directly with the system calls of the
|
||||
underlying kernel.
|
||||
|
||||
\subsection{Create a single-user system as a Unix process}
|
||||
|
||||
The next step is to transform the Common Lisp system into an
|
||||
operating system in the sense of the API for users and
|
||||
applications. This system would contain the object store, but
|
||||
perhaps not access control functionality.
|
||||
|
||||
When this step is accomplished, it is possible to write or adapt
|
||||
applications such as text editors, inspectors, debuggers, GUI
|
||||
interface libraries, etc. for the system.
|
||||
|
||||
\subsection{Create device drivers}
|
||||
|
||||
The final step is to replace the temporary Unix kernel with native
|
||||
device drivers for the new system and to turn the system into a full
|
||||
multi-user operating system.
|
@ -0,0 +1,110 @@
|
||||
\chapter{Object store}
|
||||
\label{chap-object-store}
|
||||
|
||||
The \emph{object store} is a system-wide database containing
|
||||
any kind of objects. Each object is a \emph{capability}.
|
||||
|
||||
An object in the store can optionally be associated with a certain
|
||||
number of \emph{attributes}. An attribute is a \emph{pair} consisting
|
||||
of the \emph{attribute name} and the \emph{attribute value}. The
|
||||
attribute name is a symbol in the \texttt{keyword} package. The
|
||||
attribute value can be any object.
|
||||
|
||||
\begin{tabularx}{\linewidth}%
|
||||
{|>{\setlength\hsize{.2\hsize}}X|%
|
||||
>{\setlength\hsize{.8\hsize}}X|}
|
||||
\hline
|
||||
Keyword & Possible-values\\
|
||||
\hline\hline
|
||||
\textbf{category} &
|
||||
|
||||
The nature of the object such
|
||||
as \textbf{movie}, \textbf{music}, \textbf{article}, \textbf{book}, \textbf{user
|
||||
manual}, \textbf{dictionary}, \textbf{course}, \textbf{lecture},
|
||||
\textbf{recipe}, \textbf{program}, \textbf{bank statement},
|
||||
\textbf{email}. These would be chosen from an
|
||||
editable set that is defined per user.\\
|
||||
\hline
|
||||
\textbf{name} &
|
||||
|
||||
A string that is displayed with the object, such as "A Dramatic
|
||||
Turn of Events", "Three seasons", "Alternative energy".\\
|
||||
\hline
|
||||
\textbf{author} &
|
||||
|
||||
An object identifying a person, an organization, a company,
|
||||
etc. \\
|
||||
\hline
|
||||
\textbf{genre} &
|
||||
|
||||
\textbf{progressive
|
||||
metal}, \textbf{science}, \textbf{algorithms}, \textbf{garbage
|
||||
collection}, \textbf{game}, \textbf{programming language
|
||||
implementation}, \textbf{operating system}. These would be
|
||||
chosen from an editable set that is defined per user.\\
|
||||
\hline
|
||||
\textbf{format} &
|
||||
|
||||
This attribute can be used to identify the file type of documents such
|
||||
as \textbf{PDF}, \textbf{ogg/vorbis}, \textbf{MPEG4} \textbf{PNG}, in
|
||||
which case the attribute can be assigned automatically, but also to
|
||||
identify the source format of files in a directory containing
|
||||
things like articles or user manuals, for
|
||||
example \textbf{LaTeX}, \textbf{Texinfo}, \textbf{HTML}. These would
|
||||
be chosen from an editable set that is defined per user. \\
|
||||
\hline
|
||||
\end{tabularx}
|
||||
|
||||
\begin{tabularx}{\linewidth}%
|
||||
{|>{\setlength\hsize{.2\hsize}}X|%
|
||||
>{\setlength\hsize{.8\hsize}}X|}
|
||||
\hline
|
||||
Keyword & Possible-values\\
|
||||
\hline\hline
|
||||
\textbf{date of creation} &
|
||||
|
||||
A date interval.\\
|
||||
\hline
|
||||
\textbf{composer} &
|
||||
|
||||
An object representing a person. On a compilation album there
|
||||
can be more than one attribute of this kind. \\
|
||||
\hline
|
||||
\textbf{language} &
|
||||
|
||||
An object representing a natural language such
|
||||
as \textbf{English}, \textbf{Vietnamese}, or a programming languages
|
||||
such as \textbf{Lisp}, \textbf{Python}. These would
|
||||
be chosen from an editable set that is defined per user. If
|
||||
appropriate, a document can have several of these attributes, for
|
||||
instance if some program uses multiple programming languages, or
|
||||
if a document is written using several languages, such as a
|
||||
dictionary. \\
|
||||
\hline
|
||||
\textbf{duration} &
|
||||
|
||||
An object representing a duration. \\
|
||||
\hline
|
||||
\textbf{source control} &
|
||||
|
||||
\textbf{GIT}, \textbf{SVN}, \textbf{CVS}, \textbf{darks}, etc. These
|
||||
would be chosen from an editable set that is defined per user.\\
|
||||
\hline
|
||||
\end{tabularx}
|
||||
|
||||
In a typical operating system installation, there are many fairly
|
||||
large objects such as movies, music files, pictures, etc. The amount
|
||||
data associated with such an object that would be stored in the object
|
||||
store is typically very small compared to the object itself. Even a
|
||||
fairly modest text file probably has $10^4 -- 10^5$ characters in it,
|
||||
whereas the meta-data probably takes up no more than $10^2 -- 10^3$
|
||||
bytes. It is therefore likely that the entire object store will fit
|
||||
in main memory. Scanning the entire object store would then take at
|
||||
most a few second of CPU time. For better performance, one or more
|
||||
\emph{indexes} could be created. The objects could for instance be
|
||||
divided by \emph{category}.
|
||||
|
||||
Searching the object store amounts to defining a \emph{filter},
|
||||
i.e. a function that, given a set of keyword/value pairs returns
|
||||
\emph{true} if and only if the corresponding object should be included
|
||||
in the search result.
|
@ -0,0 +1,78 @@
|
||||
\chapter{Protection}
|
||||
\label{chap-protection}
|
||||
|
||||
There are two kinds of protection that are important in an operating
|
||||
system:
|
||||
|
||||
\begin{itemize}
|
||||
\item \emph{protecting different users from each other}. A user A
|
||||
should not be able to access or destroy the data of some other user
|
||||
B, other than if B explicitly permits it, and then only in ways that
|
||||
are acceptable to B.
|
||||
\item \emph{protecting the system from the users}. Users should be
|
||||
able to access system resources such as memory and peripherals only
|
||||
in controlled ways, so as to guarantee the integrity of the system.
|
||||
\end{itemize}
|
||||
|
||||
\section{Protecting users from each other}
|
||||
|
||||
We use a combination of \emph{access control lists} and
|
||||
\emph{capabilities}. All heap-allocated objects except \texttt{cons}
|
||||
cells and (heap-allocated) numbers are manipulated through a
|
||||
\emph{tagged pointer}. In addition to containing a type tag, the
|
||||
pointer also contains an \emph{access tag}. The access tag consists
|
||||
of the 4 most-significant bits of a 64-bit pointer. Before a pointer
|
||||
is used to fetch an object from memory, the access bits are cleared.
|
||||
A primitive operation to fetch the access tag of a pointer is
|
||||
available to any user code. Each of the 4 bits represents a potential
|
||||
\emph{access restriction}, the significance of which is up to the
|
||||
programmer. A function that wishes to restrict permission to some
|
||||
object can test the corresponding access bit and signal an error if
|
||||
that bit is set.
|
||||
|
||||
The author of some complex data structure may for instance grant
|
||||
access to it only to certain other users. This would be done by
|
||||
interpreting one of the access bits as \emph{read permission}, and by
|
||||
having generic functions that access the data structures check that
|
||||
this bit has the desired value (for instance in a \texttt{:before}
|
||||
method).
|
||||
|
||||
The access bits of a capability are determined when the object is
|
||||
accessed through the object store. \seechap{chap-object-store} One of
|
||||
the possible key/value pairs associated with the object in the object
|
||||
store corresponds to the access permissions in the form of an
|
||||
\emph{access control list}. A user who accesses the object from the
|
||||
object store will be checked against the access control list and
|
||||
appropriate access bits will be added to the object before it is given
|
||||
to the user.
|
||||
|
||||
\section{Protecting system from the users}
|
||||
|
||||
In a typical modern operating system, the system is protected from the
|
||||
users through the use of a \emph{mode} of execution of the processor,
|
||||
which can be either \emph{user mode} or \emph{supervisor mode}.
|
||||
Certain instructions are restricted to supervisor mode, such as
|
||||
instructions for input/output or for remapping the address space.
|
||||
|
||||
In \sysname{}, the normal mode of execution is \emph{supervisor mode}.
|
||||
The code executed by the user is translated to machine code by a
|
||||
\emph{trusted compiler} which is known not to generate code that, if
|
||||
executed, might represent a risk to the integrity of the system.
|
||||
Since no remapping of the address space is required as a result of an
|
||||
\emph{interrupt} or a \emph{trap}, such events can be handled very
|
||||
quickly.
|
||||
|
||||
Occasionally, it might be useful to write or install some software
|
||||
that is compiled to machine code by some compiler that can not be
|
||||
trusted. The result of such a compilation or installation is a single
|
||||
(possibly large) Lisp function. When this function is executed, the
|
||||
mode of execution is switched to \emph{user mode}. As with
|
||||
traditional modern operating systems, the code of such software has
|
||||
its own \emph{address space}, which means that it can not directly
|
||||
manipulate \sysname{} capabilities. Instead, it has to communicate
|
||||
with the system through the user of \emph{system calls}. A
|
||||
system-wide object is referred to by such code through an interposing
|
||||
\emph{object descriptor}, much like a file descriptor in Unix. The
|
||||
details of this mechanism have not yet been fully determined.
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
OUTFILE=$(echo $1 | sed -e 's/lisp/code/')
|
||||
echo -n "\\" >$OUTFILE
|
||||
echo "begin{Verbatim}[frame=single]" >>$OUTFILE
|
||||
expand $1 >>$OUTFILE
|
||||
echo "\\end{Verbatim}" >>$OUTFILE
|
@ -0,0 +1,291 @@
|
||||
@book{Sedgewick:1996:IAA:227351,
|
||||
author = {Sedgewick, Robert and Flajolet, Philippe},
|
||||
title = {An introduction to the analysis of algorithms},
|
||||
year = {1996},
|
||||
isbn = {0-201-40009-X},
|
||||
publisher = {Addison-Wesley Longman Publishing Co., Inc.},
|
||||
address = {Boston, MA, USA},
|
||||
}
|
||||
|
||||
|
||||
@book{McConnell:2007:AA:1374801,
|
||||
author = {McConnell, Jeffrey J.},
|
||||
title = {Analysis of Algorithms},
|
||||
year = {2007},
|
||||
isbn = {9780763707828},
|
||||
edition = {2},
|
||||
publisher = {Jones and Bartlett Publishers, Inc.},
|
||||
address = {USA},
|
||||
}
|
||||
|
||||
|
||||
@article{Sleator:1985:SBS:3828.3835,
|
||||
author = {Sleator, Daniel Dominic and Tarjan, Robert Endre},
|
||||
title = {Self-adjusting binary search trees},
|
||||
journal = {J. ACM},
|
||||
issue_date = {July 1985},
|
||||
volume = {32},
|
||||
number = {3},
|
||||
month = jul,
|
||||
year = {1985},
|
||||
issn = {0004-5411},
|
||||
pages = {652--686},
|
||||
numpages = {35},
|
||||
url = {http://doi.acm.org/10.1145/3828.3835},
|
||||
doi = {10.1145/3828.3835},
|
||||
acmid = {3835},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
|
||||
@incollection{Bayer:2002:BDP:944331.944346,
|
||||
author = {Bayer, Rudolf},
|
||||
chapter = {B-trees and databases, past and future},
|
||||
title = {Software pioneers},
|
||||
editor = {Broy, Manfred and Denert, Ernst},
|
||||
year = {2002},
|
||||
isbn = {3-540-43081-4},
|
||||
pages = {232--244},
|
||||
numpages = {13},
|
||||
url = {http://dl.acm.org/citation.cfm?id=944331.944346},
|
||||
acmid = {944346},
|
||||
publisher = {Springer-Verlag New York, Inc.},
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
|
||||
@article{Adelson-Velskii_Landis_1962,
|
||||
title = {An algorithm for the organization of information},
|
||||
volume = {3},
|
||||
url = {http://en.scientificcommons.org/19884302},
|
||||
number = {2},
|
||||
journal = {Soviet Mathematics Doklady},
|
||||
publisher = {JOINT PUBLICATIONS RESEARCH SERVICE WASHINGTON DC},
|
||||
author = {Adelson-Velskii, G M and Landis, E M},
|
||||
year={1962},
|
||||
pages={263--266}
|
||||
}
|
||||
|
||||
@article{Tan:1972:FIS:361573.361588,
|
||||
author = {Tan, K. C.},
|
||||
title = {On Foster's information storage and retrieval using AVL trees},
|
||||
journal = {Commun. ACM},
|
||||
issue_date = {Sept. 1972},
|
||||
volume = {15},
|
||||
number = {9},
|
||||
month = sep,
|
||||
year = {1972},
|
||||
issn = {0001-0782},
|
||||
pages = {843--},
|
||||
url = {http://doi.acm.org/10.1145/361573.361588},
|
||||
doi = {10.1145/361573.361588},
|
||||
acmid = {361588},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
keywords = {binary trees, information retrieval, information storage, search trees},
|
||||
}
|
||||
|
||||
@inproceedings{Wilson:1992:UGC:645648.664824,
|
||||
author = {Wilson, Paul R.},
|
||||
title = {Uniprocessor Garbage Collection Techniques},
|
||||
booktitle = {Proceedings of the International Workshop on Memory Management},
|
||||
series = {IWMM '92},
|
||||
year = {1992},
|
||||
isbn = {3-540-55940-X},
|
||||
pages = {1--42},
|
||||
numpages = {42},
|
||||
url = {http://dl.acm.org/citation.cfm?id=645648.664824},
|
||||
acmid = {664824},
|
||||
publisher = {Springer-Verlag},
|
||||
address = {London, UK, UK},
|
||||
}
|
||||
|
||||
@book{Jones:2011:GCH:2025255,
|
||||
author = {Jones, Richard and Hosking, Antony and Moss, Eliot},
|
||||
title = {The Garbage Collection Handbook: The Art of Automatic Memory Management},
|
||||
year = {2011},
|
||||
isbn = {1420082795, 9781420082791},
|
||||
edition = {1st},
|
||||
publisher = {Chapman \& Hall/CRC},
|
||||
}
|
||||
|
||||
@article{Andersson:1999:GBT:308088.308094,
|
||||
author = {Andersson, Arne},
|
||||
title = {General balanced trees},
|
||||
journal = {J. Algorithms},
|
||||
issue_date = {Jan. 1999},
|
||||
volume = {30},
|
||||
number = {1},
|
||||
month = jan,
|
||||
year = {1999},
|
||||
issn = {0196-6774},
|
||||
pages = {1--18},
|
||||
numpages = {18},
|
||||
url = {http://dx.doi.org/10.1006/jagm.1998.0967},
|
||||
doi = {10.1006/jagm.1998.0967},
|
||||
acmid = {308094},
|
||||
publisher = {Academic Press, Inc.},
|
||||
address = {Duluth, MN, USA},
|
||||
}
|
||||
|
||||
@article{Stout:1986:TRO:6592.6599,
|
||||
author = {Stout, Q. F and Warren, B. L},
|
||||
title = {Tree rebalancing in optimal time and space},
|
||||
journal = {Commun. ACM},
|
||||
issue_date = {Sept. 1986},
|
||||
volume = {29},
|
||||
number = {9},
|
||||
month = sep,
|
||||
year = {1986},
|
||||
issn = {0001-0782},
|
||||
pages = {902--908},
|
||||
numpages = {7},
|
||||
url = {http://doi.acm.org/10.1145/6592.6599},
|
||||
doi = {10.1145/6592.6599},
|
||||
acmid = {6599},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
|
||||
@article{Waters:1992:UNC:1039991.1039996,
|
||||
author = {Waters, Richard C.},
|
||||
title = {Using the new common Lisp pretty printer},
|
||||
journal = {SIGPLAN Lisp Pointers},
|
||||
issue_date = {April-June 1992},
|
||||
volume = {V},
|
||||
number = {2},
|
||||
month = apr,
|
||||
year = {1992},
|
||||
issn = {1045-3563},
|
||||
pages = {27--34},
|
||||
numpages = {8},
|
||||
url = {http://doi.acm.org/10.1145/1039991.1039996},
|
||||
doi = {10.1145/1039991.1039996},
|
||||
acmid = {1039996},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
|
||||
@INPROCEEDINGS{Waters89xp:a,
|
||||
author = {Richard C. Waters},
|
||||
title = {XP: A Common Lisp Pretty Printing System},
|
||||
booktitle = {A.I. Memo 1102a, MIT Artificial Intelligence Laboratory},
|
||||
year = {1989}
|
||||
}
|
||||
|
||||
BibTeX | BibTeX (beta) | EndNote | ACM Ref
|
||||
|
||||
@techreport{Huang:1990:FSM:898863,
|
||||
author = {Huang, Bing and Langston, Michael A.},
|
||||
title = {Fast Stable Merging and Sorting in Constant Extra Space},
|
||||
year = {1990},
|
||||
source = {http://www.ncstrl.org:8900/ncstrl/servlet/search?formname=detail\&id=oai%3Ancstrlh%3Autk_cs%3Ancstrl.utk_cs%2F%2FUT-CS-90-106},
|
||||
publisher = {University of Tennessee},
|
||||
address = {Knoxville, TN, USA},
|
||||
}
|
||||
|
||||
@article{Huang:1988:PIM:42392.42403,
|
||||
author = {Huang, Bing-Chao and Langston, Michael A.},
|
||||
title = {Practical in-place merging},
|
||||
journal = {Commun. ACM},
|
||||
issue_date = {March 1988},
|
||||
volume = {31},
|
||||
number = {3},
|
||||
month = mar,
|
||||
year = {1988},
|
||||
issn = {0001-0782},
|
||||
pages = {348--352},
|
||||
numpages = {5},
|
||||
url = {http://doi.acm.org/10.1145/42392.42403},
|
||||
doi = {10.1145/42392.42403},
|
||||
acmid = {42403},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
|
||||
@article{Katajainen:1996:PIM:642136.642138,
|
||||
author = {Katajainen, Jyrki and Pasanen, Tomi and Teuhola, Jukka},
|
||||
title = {Practical in-place mergesort},
|
||||
journal = {Nordic J. of Computing},
|
||||
issue_date = {Spring 1996},
|
||||
volume = {3},
|
||||
number = {1},
|
||||
month = mar,
|
||||
year = {1996},
|
||||
issn = {1236-6064},
|
||||
pages = {27--40},
|
||||
numpages = {14},
|
||||
url = {http://dl.acm.org/citation.cfm?id=642136.642138},
|
||||
acmid = {642138},
|
||||
publisher = {Publishing Association Nordic Journal of Computing},
|
||||
address = {Finland},
|
||||
keywords = {in-place algorithms, mergesort, sorting},
|
||||
}
|
||||
|
||||
@inproceedings{Clinger:1990:RFP:93542.93557,
|
||||
author = {Clinger, William D.},
|
||||
title = {How to read floating point numbers accurately},
|
||||
booktitle = {Proceedings of the ACM SIGPLAN 1990 conference on Programming language design and implementation},
|
||||
series = {PLDI '90},
|
||||
year = {1990},
|
||||
isbn = {0-89791-364-7},
|
||||
location = {White Plains, New York, USA},
|
||||
pages = {92--101},
|
||||
numpages = {10},
|
||||
url = {http://doi.acm.org/10.1145/93542.93557},
|
||||
doi = {10.1145/93542.93557},
|
||||
acmid = {93557},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
|
||||
@inproceedings{Burger:1996:PFN:231379.231397,
|
||||
author = {Burger, Robert G. and Dybvig, R. Kent},
|
||||
title = {Printing floating-point numbers quickly and accurately},
|
||||
booktitle = {Proceedings of the ACM SIGPLAN 1996 conference on Programming language design and implementation},
|
||||
series = {PLDI '96},
|
||||
year = {1996},
|
||||
isbn = {0-89791-795-2},
|
||||
location = {Philadelphia, Pennsylvania, USA},
|
||||
pages = {108--116},
|
||||
numpages = {9},
|
||||
url = {http://doi.acm.org/10.1145/231379.231397},
|
||||
doi = {10.1145/231379.231397},
|
||||
acmid = {231397},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
keywords = {floating-point printing, run-time systems},
|
||||
}
|
||||
|
||||
@TECHREPORT{Gay90correctlyrounded,
|
||||
author = {David M. Gay},
|
||||
title = {Correctly Rounded Binary-Decimal and Decimal-Binary Conversions},
|
||||
institution = {Numerical Analysis Manuscript 90-10, AT\&T Bell Laboratories},
|
||||
year = {1990}
|
||||
}
|
||||
|
||||
@inproceedings{Doligez:1993:CGG:158511.158611,
|
||||
author = {Doligez, Damien and Leroy, Xavier},
|
||||
title = {A concurrent, generational garbage collector for a multithreaded implementation of ML},
|
||||
booktitle = {Proceedings of the 20th ACM SIGPLAN-SIGACT symposium on Principles of programming languages},
|
||||
series = {POPL '93},
|
||||
year = {1993},
|
||||
isbn = {0-89791-560-7},
|
||||
location = {Charleston, South Carolina, USA},
|
||||
pages = {113--123},
|
||||
numpages = {11},
|
||||
url = {http://doi.acm.org/10.1145/158511.158611},
|
||||
doi = {10.1145/158511.158611},
|
||||
acmid = {158611},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
|
||||
@book{Kiczales:1991:AMP:574212,
|
||||
author = {Kiczales, Gregor and Rivieres, Jim Des},
|
||||
title = {The Art of the Metaobject Protocol},
|
||||
year = {1991},
|
||||
isbn = {0262111586},
|
||||
publisher = {MIT Press},
|
||||
address = {Cambridge, MA, USA},
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
\documentclass[11pt]{book}
|
||||
\newcommand{\Comment}[1]{\begin{center}\tt #1 \end{center}}
|
||||
% \usepackage{doublespace}
|
||||
\usepackage[paperwidth=7.5in, paperheight=9.25in,
|
||||
inner=35mm, outer=25mm,
|
||||
tmargin=25mm, bmargin=30mm]{geometry}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{alltt}
|
||||
\usepackage{moreverb}
|
||||
\usepackage{fancyvrb}
|
||||
\usepackage{epsfig}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{float}
|
||||
\usepackage{color}
|
||||
\usepackage{amsthm}
|
||||
\usepackage{changebar}
|
||||
\usepackage{tabularx}
|
||||
\usepackage[nottoc]{tocbibind}
|
||||
\usepackage{shadow}
|
||||
\setlength\sdim{2mm}
|
||||
|
||||
\floatplacement{figure}{!htbp}
|
||||
|
||||
\newfloat{codefragment}{!htbp}{cod}[chapter]
|
||||
\floatname{codefragment}{Code fragment}
|
||||
|
||||
\newtheorem{theorem}{Theorem}[chapter]
|
||||
\newtheorem{exercise}{Exercise}[chapter]
|
||||
\newtheorem{definition}{Definition}[chapter]
|
||||
|
||||
\setlength{\parskip}{0.3cm}
|
||||
\setlength{\parindent}{0cm}
|
||||
|
||||
\def\lispout#1{\underline{#1}}
|
||||
|
||||
\def\mop{MOP}
|
||||
\def\bs{$\backslash$}
|
||||
\def\lispobj#1{\textsl{#1}}
|
||||
\def\lispobjindex#1{\lispobj{#1}\index{#1@\lispobj{#1}}}
|
||||
\def\syntax#1{\texttt{#1}}
|
||||
\def\metavar#1{\textit{#1}}
|
||||
\def\keyword#1{\code{\textbf{#1}}}
|
||||
\def\code#1{\textsf{#1}}
|
||||
\def\fixme#1{\footnote{\color{red}FIXME: #1}}
|
||||
|
||||
\def\sysname{LispOS}
|
||||
|
||||
\def\inputfig#1{\input #1}
|
||||
\def\inputtex#1{\input #1}
|
||||
\def\inputal#1{\input #1}
|
||||
\def\inputcode#1{\input #1}
|
||||
|
||||
\inputtex{logos.tex}
|
||||
\inputtex{refmacros.tex}
|
||||
\inputtex{other-macros.tex}
|
||||
|
||||
\newenvironment{itemize0}{
|
||||
\begin{itemize}
|
||||
\setlength{\parskip}{0cm}%
|
||||
}
|
||||
{\end{itemize}}
|
||||
|
||||
\newenvironment{enumerate0}{
|
||||
\begin{enumerate}
|
||||
\setlength{\parskip}{0cm}%
|
||||
}
|
||||
{\end{enumerate}}
|
||||
|
||||
\newenvironment{smalltt}{
|
||||
\begin{alltt}
|
||||
\small
|
||||
}
|
||||
{\end{alltt}}
|
||||
|
||||
%UPDATE version number when it changes.
|
||||
\def\majorversion{0}
|
||||
\def\minorversion{1}
|
||||
\def\bookversion{\majorversion{}.\minorversion{}}
|
||||
\title{{\Huge \sysname{}\\
|
||||
Specification of a Lisp operating system.}}
|
||||
|
||||
\author{Robert Strandh}
|
||||
|
||||
\date{2013}
|
||||
|
||||
\makeindex
|
||||
\begin{document}
|
||||
\pagenumbering{roman}
|
||||
|
||||
\maketitle
|
||||
|
||||
\newpage
|
||||
|
||||
{\setlength{\parskip}{0cm}
|
||||
\tableofcontents}
|
||||
|
||||
\inputtex{chap-intro.tex}
|
||||
\inputtex{chap-object-store.tex}
|
||||
\inputtex{chap-protection.tex}
|
||||
\inputtex{chap-environments.tex}
|
||||
|
||||
\bibliography{lispos}{}
|
||||
\bibliographystyle{alpha}
|
||||
|
||||
\printindex
|
||||
|
||||
\end{document}
|
||||
|
@ -0,0 +1,46 @@
|
||||
% Programming languages.
|
||||
\def\cl{Common Lisp}
|
||||
\def\clos{CLOS}
|
||||
\def\closs{Common Lisp Object System}
|
||||
\def\lisp{Lisp}
|
||||
\def\hs{HyperSpec}
|
||||
\def\bs{$\backslash$}
|
||||
\def\lispobj#1{\textsl{#1}}
|
||||
\def\emphindex#1{\emph{#1}\index{#1}}
|
||||
\def\syntax#1{\texttt{#1}}
|
||||
\def\metavar#1{\textit{#1}}
|
||||
\def\code#1{\textsf{#1}}
|
||||
\def\FIXME#1{\footnote{\color{red}FIXME: #1}}
|
||||
\def\java{Java}
|
||||
\def\csharp{C\#}
|
||||
\def\javascript{JavaScript}
|
||||
\def\php{PHP}
|
||||
\def\self{Self}
|
||||
\def\perl{Perl}
|
||||
\def\python{Python}
|
||||
\def\ruby{Ruby}
|
||||
\def\smalltalk{Smalltalk}
|
||||
\def\simula{Simula}
|
||||
\def\clanguage{C}
|
||||
\def\cplusplus{C++}
|
||||
\def\fortran{Fortran}
|
||||
\def\pascal{Pascal}
|
||||
\def\algol{Algol}
|
||||
\def\ml{ML}
|
||||
\def\haskell{Haskell}
|
||||
\def\miranda{Miranda}
|
||||
\def\cobol{COBOL}
|
||||
\def\plone{PL/I}
|
||||
\def\emacs{Emacs}
|
||||
|
||||
% Operating systems and kernels.
|
||||
\def\multics{Multics}
|
||||
\def\unix{UNIX}% The Wikipedia article says this is the way it is written.
|
||||
\def\gnulinux{GNU/Linux}
|
||||
\def\linux{Linux}
|
||||
\def\mach{Mach}
|
||||
\def\atlas{Atlas}
|
||||
\def\vms{VMS}
|
||||
\def\ibmvmcms{VM/CMS}
|
||||
\def\msdos{MS DOS}
|
||||
\def\genera{Genera}
|
@ -0,0 +1,6 @@
|
||||
\def\sll{simply linked list}
|
||||
\def\Sll{Simply linked list}
|
||||
\def\dll{doubly linked list}
|
||||
\def\Dll{Doubly linked list}
|
||||
\def\ttt{2-3 tree}
|
||||
|
@ -0,0 +1,50 @@
|
||||
\newcommand{\refalgo}[1]{algorithm~\ref{#1}}%
|
||||
\newcommand{\refAlgo}[1]{Algorithm~\ref{#1}}%
|
||||
\newcommand{\seealgo}[1]{(See \refAlgo{#1}.)}%
|
||||
\newcommand{\seealgox}[2]{(See \refAlgo{#1} #2.)}%
|
||||
|
||||
\newcommand{\refpart}[1]{part~\ref{#1}}%
|
||||
\newcommand{\refPart}[1]{Part~\ref{#1}}%
|
||||
\newcommand{\seepart}[1]{(See \refPart{#1}.)}%
|
||||
\newcommand{\seepartx}[2]{(See \refPart{#1} #2.)}%
|
||||
|
||||
\newcommand{\refchap}[1]{chapter~\ref{#1}}%
|
||||
\newcommand{\refChap}[1]{Chapter~\ref{#1}}%
|
||||
\newcommand{\seechap}[1]{(See \refChap{#1}.)}%
|
||||
\newcommand{\seechapx}[2]{(See \refChap{#1} #2.)}%
|
||||
|
||||
\newcommand{\refapp}[1]{appendix~\ref{#1}}%
|
||||
\newcommand{\refApp}[1]{Appendix~\ref{#1}}%
|
||||
\newcommand{\seeapp}[1]{(See \refApp{#1}.)}%
|
||||
\newcommand{\seeappx}[2]{(See \refApp{#1} #2.)}%
|
||||
|
||||
\newcommand{\refsec}[1]{section~\ref{#1}}%
|
||||
\newcommand{\refSec}[1]{Section~\ref{#1}}%
|
||||
\newcommand{\seesec}[1]{(See \refSec{#1}.)}%
|
||||
\newcommand{\seesecx}[2]{(See \refSec{#1} #2.)}%
|
||||
|
||||
\newcommand{\reffig}[1]{figure~\ref{#1}}%
|
||||
\newcommand{\refFig}[1]{Figure~\ref{#1}}%
|
||||
\newcommand{\seefig}[1]{(See \refFig{#1}.)}%
|
||||
\newcommand{\seefigx}[2]{(See \refFig{#1} #2.)}%
|
||||
|
||||
\newcommand{\refdef}[1]{definition~\ref{#1}}%
|
||||
\newcommand{\refDef}[1]{Definition~\ref{#1}}%
|
||||
\newcommand{\seedef}[1]{(See \refDef{#1}.)}%
|
||||
\newcommand{\seedefx}[2]{(See \refDef{#1} #2.)}%
|
||||
|
||||
\newcommand{\reftheo}[1]{theorem~\ref{#1}}%
|
||||
\newcommand{\refTheo}[1]{Theorem~\ref{#1}}%
|
||||
\newcommand{\seetheo}[1]{(See \refTheo{#1}.)}%
|
||||
\newcommand{\seetheox}[2]{(See \refTheo{#1} #2.)}%
|
||||
|
||||
\newcommand{\refexo}[1]{exercise~\ref{#1}}%
|
||||
\newcommand{\refExo}[1]{Exercise~\ref{#1}}%
|
||||
\newcommand{\seeexo}[1]{(See \refExo{#1}.)}%
|
||||
\newcommand{\seeexox}[2]{(See \refExo{#1} #2.)}%
|
||||
|
||||
\newcommand{\refcode}[1]{code fragment~\ref{#1}}%
|
||||
\newcommand{\refCode}[1]{Code fragment~\ref{#1}}%
|
||||
\newcommand{\seecode}[1]{(See \refCode{#1}.)}%
|
||||
\newcommand{\seecodex}[2]{(See \refCode{#1} #2.)}%
|
||||
|
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
CHAINE=$1
|
||||
MOTIF="^\\\\$CHAINE\{.*\}"
|
||||
shift
|
||||
for i in $*
|
||||
do
|
||||
egrep $MOTIF $i \
|
||||
| sed "s/^\\\\$CHAINE{\(.*\)}/\1/" \
|
||||
| tr ['\n'] [' ']
|
||||
done
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
#set -x
|
||||
TEXFILES=$(./strip-dependence inputtex $1)
|
||||
echo -n $TEXFILES
|
||||
for i in $TEXFILES
|
||||
do
|
||||
echo -n " " $(./tex-dependencies $i)
|
||||
done
|
||||
echo
|
Loading…
Reference in New Issue