1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
|
% This file is part of Oaklisp.
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% The GNU GPL is available at http://www.gnu.org/licenses/gpl.html
% or from the Free Software Foundation, 59 Temple Place - Suite 330,
% Boston, MA 02111-1307, USA
\chapter{Evaluation and Locales} \label{locales}
Locales are the namespace structuring mechanism of Oaklisp. Whenever
an Oaklisp expression is evaluated, a locale must be provided in order
to specify a particular mapping from symbols to macro-expanders and
from symbols to storage cells.
\section{Evaluation}
\op{eval}{form locale}
\doc{Evaluates \emph{form} relative to \emph{locale}.}
Although programmers don't often need to call \df{eval} directly,
every expression typed at the top level is passed in to \df{eval} to
be evaluated relative to the locale specified by the fluid variable
\df{current-locale}. Files may be evaluated using the \df{load}
function.
\op{load}{file-name $[$locale$]$}
\doc{Reads all of the forms in the file \emph{file-name} and evaluates
them relative to \emph{locale}, which defaults to the value of
\dffl{current-locale} if not specified.}
The file compiler can be used to create an assembly language file that
has the same effect as an Oaklisp source file.
\op{compile-file}{locale file-name}
\doc{Compiles the file \emph{file-name} relative to \emph{locale},
which defaults to the value of \dffl{current-locale}. A file must be
compiled and loaded relative to the same locale in order to guarantee
that the program's semantics are preserved.
Oaklisp source files have a default extension of \df{.oak} while
compiled files are given the extension \df{.oa}. \df{compile-file}
first tries to read the file \emph{file-name}\df{.oak}, and then looks
for \emph{file-name}, while \df{load} looks first for
\emph{file-name}\df{.oa}, then for \emph{file-name}\df{.oak}, and finally for
\emph{file-name}.}
\section{Installing Names in a Locale}
Oaklisp has several forms that can be used to insert global variables
and macro definitions into a locale. The target locale isn't
explicitly specified by any of these forms, but is implicitly
understood to be the locale with respect to which the form is being
evaluated. Thus, when a form is typed at the top level, the effect is
on \dffl{current-locale}, and when a file is loaded, the effect is on
the locale specified in the call to \df{load}.
\sform{define}{var val}
\doc{Installs the global variable \emph{var} in the current locale with
value \emph{val}.}
\sform{define-constant}{var val}
\doc{This form is like \df{define} except that \emph{var} is marked as frozen in
the current locale so that the compiler can be free to substitute
the value for references to \emph{var}.}
\sform{define-instance}{var typ \dt make-args}
\doc{If the contents of \emph{var} isn't of type \emph{typ}, this is the same
as \texttt{(set! \emph{var} (make \emph{typ} . \emph{make-args}))}. If
\emph{var} is already bound to an object of the right type, this form has no
effect. \emph{Note:} this language feature is in flux. Currently, it
sends an \df{initialize} message to the object with the new
\emph{make-args}.}
\sform{define-syntax}{macro-name expander}
\doc{
Installs \emph{macro-name} in the current locale. \emph{expander}
should be a lambda that is able to translate an example of the macro
into a form that has simpler syntax. }
As with all Oaklisp forms, the effect of a \df{define-syntax} form in
a file is not felt until run-time when the file is loaded. Since it
is often convenient to be able to use a macro in the file in which it
is defined, a special mechanism has been provided for defining
file-local macros that are in effect at compile time. The following
magic forms should be used with care, since they violate the usually
absolute dichotomy between compile time and load time.
\sform{local-syntax}{macro-name expander}
\doc{
During the compilation of a file in which a \df{local-syntax} form
is contained, the form augments the name space with the
macro specified by \emph{macro-name} and \emph{expander}. This form can
only appear at top level in a file; and essentially disappears before
load time.
}
\sform{define-local-syntax}{macro-name expander}
\doc{
Temporarily augments the compile-time name space with the specified
macro, and also installs the macro in the current locale when the
file is loaded. This form can only appear at top level in a file.
}
\section{Structuring the Namespace}
\discuss{
Oaklisp locales are not associated with textual binding
contours, nor are they particularly user-friendly objects. They were
designed to be a powerful implementation tool, leaving the task of providing
a convenient interactive interface to higher-level code.}
\op{make}{\df{locale} superior-list}
\doc{Returns a new locale which inherits names from the locales in
\emph{superior-list}. During recursive name lookups, the superiors are
searched deapth first in left-to-right order.}
\section{Variables} \label{variables}
Locales are essentially mappings from symbols to storage cells.
Although locales can be created on-the-fly, their main use is in
building the structured top-level environment for global variables.
Variable names must be installed in a locale before they can be
referenced. Precise control over shadowing and cross-referencing can
be achieved using the following settable operations.
\so{variable?}{locale symbol}
\doc{Returns a locative to the appropriate storage cell if \emph{symbol}
is installed as a variable name, or \df{\#f} otherwise. The search is
allowed to proceed to superior locales if necessary.}
\setter{variable?}{locale symbol}{locative}
\doc{If \emph{symbol} is not currently defined at any level, then it is
installed in \emph{locale}, with the location named by \emph{locative}
serving as its value cell. If \emph{symbol} is defined at some level,
then its value cell at the highest level\footnote{\ie\ in the nearest
locale to the one handling the operation.} is changed to be the
location referenced by \emph{locative}.}
\setter{variable?}{locale symbol}{\texttt{\#f}}
\doc{If \emph{symbol} is defined at some level, then its definition is removed
from the highest level. Otherwise an error is generated.}
\so{variable-here?}{locale symbol}
\doc{Returns a locative to the appropriate storage cell if \emph{symbol}
is installed as a variable name, or \df{\#f} otherwise. The search is
constrained to \emph{locale} itself.}
\setter{variable-here?}{locale symbol}{locative}
\doc{If \emph{symbol} is not currently defined in \emph{locale}, then it is
installed, with the location named by \emph{locative} serving as its value
cell. If \emph{symbol} is defined in \emph{locale}, then its value cell is
changed to be the location referenced by \emph{locative}.}
\setter{variable-here?}{locale symbol}{\texttt{\#f}}
\doc{If \emph{symbol} is defined in \emph{locale} then its definition
is removed. Otherwise an error is generated.}
\section{Macros}
Macro definitions are also stored in locales. These definitions are
stored as a mapping from names to macro expanders. A macro expander
is simply a one-argument function that takes an S-expression as its
input and returns a transformed S-expression. Macro definitions are
installed with the following settable operations, which are entirely
analogous to the ones described in Section~\ref{variables}.
\so{macro?}{locale symbol}
\doc{Returns the appropriate macro expander if \emph{symbol} is installed
as a macro name and \df{\#f} otherwise. The search is allowed to proceed to
superior locales if necessary.}
\so{macro-here?}{locale symbol}
\doc{Returns the appropriate macro expander if \emph{symbol} is installed
as a macro name, or \df{\#f} otherwise. The search is constrained to
\emph{locale} itself.}
\section{Compilation}
All evaluation in Oaklisp is performed with respect to some locale.
The syntax of the language is determined by the macro tables visible
from that locale, and free variable references are likewise resolved
using the global variables defined in its name space.
%%
% Evaluation is
% performed by sending a \df{compile} message to the desired locale.
%
% \begin{group}
% \op{(COMPILE locale form)}
% \doc{Evaluates \df{form} in the name space defined by \df{locale} and
% its ancestors.}
% \end{group}
%
% \begin{group}
% \op{(LOAD file locale)}
% \doc{Completes the suspended evaluation of the form that was compiled to
% \df{file}.\ \df{locale} must be the locale within which the
% form was originally compiled.}
% \end{group}
%
% \discuss{For improved efficiency, it is desirable for the compiler to
% be able to open-code some functions. This is only possible if
% the variables bound to those functions will never change their
% values. The following operations may be used to inform the compiler that a
% variable will always have the same value.}
%
%
\spred{frozen?}{locale symbol}
\doc{Returns \df{\#t} if \emph{symbol} is a frozen variable, otherwise
\df{\#f}. The search is allowed to proceed to superior locales if
necessary. If \emph{symbol} is not found anywhere, an error occurs.}
\spred{frozen-here?}{locale symbol}
\doc{Returns \df{\#t} if \emph{symbol} is a frozen variable, otherwise
\df{\#f}. The search is constrained to \emph{locale} itself. If
\emph{symbol} is not installed as a variable in \emph{locale}, an error
occurs.}
|