Changeset 4297

Show
Ignore:
Timestamp:
10/30/09 08:02:50 (4 weeks ago)
Author:
sukyoungryu
Message:

[spec] Added the Expressions chapter.

Location:
trunk
Files:
22 added
12 modified

Legend:

Unmodified
Added
Removed
  • trunk/ProjectFortress/hello.fss

    r4296 r4297  
    11(******************************************************************************* 
    2     Copyright 2008 Sun Microsystems, Inc., 
     2    Copyright 2009 Sun Microsystems, Inc., 
    33    4150 Network Circle, Santa Clara, California 95054, U.S.A. 
    44    All rights reserved. 
  • trunk/SpecData/examples/basic/Expr.Atomic.fss

    r3550 r4297  
    2525sum: ZZ32 := 0 
    2626accumArray[\N extends Number, nat x\](a: Array1[\N,0,x\]): () = 
    27   for i <- a.indices() do 
     27  for i <- a.indices do 
    2828    atomic sum += a[i] 
    2929  end 
  • trunk/Specification/appendices/appendices.tex

    r4295 r4297  
    2525% \input{\home/appendices/rendering} 
    2626% % \input{\home/appendices/ascii-to-unicode/ascii-to-unicode} 
    27 % \input{\home/appendices/operators/operators} 
     27\input{\home/appendices/operators/operators} 
    2828\input{\home/appendices/grammars/grammars} 
    2929% \input{\home/appendices/changes} 
  • trunk/Specification/basic/exceptions.tex

    r4271 r4297  
    1818\chapter{Exceptions} 
    1919\chaplabel{exceptions} 
     20 
     21\section{Causes of Exceptions} 
     22\section{Types of Exceptions} 
     23\seclabel{exception-types} 
     24\section{Information of Exceptions} 
     25\seclabel{chained-exceptions} 
  • trunk/Specification/basic/expressions/atomic.tex

    r4295 r4297  
    1818\section{Atomic Expressions} 
    1919\seclabel{atomic} 
     20 
     21\note{Modifiers on functionals such as \KWD{atomic} and \KWD{io} are not yet supported.} 
     22 
     23\begin{Grammar} 
     24\emph{FlowExpr} &::=&  \KWD{atomic} \emph{AtomicBack}\\ 
     25&$|$& \KWD{tryatomic} \emph{AtomicBack} \\ 
     26 
     27\emph{AtomicBack} 
     28&::=& \emph{AssignExpr}\\ 
     29&$|$& \emph{OpExpr}\\ 
     30&$|$& \emph{DelimitedExpr}\\ 
     31 
     32\end{Grammar} 
     33 
     34As Fortress is a parallel language, an executing Fortress program consists 
     35of a set of threads (See \secref{threads-parallelism} for a discussion of 
     36parallelism in Fortress).  In multithreaded programs, 
     37it is often convenient for a thread to evaluate some expressions 
     38\emph{atomically}.  For this purpose, Fortress provides \KWD{atomic} 
     39expressions. 
     40 
     41 
     42An \KWD{atomic} expression consists of \KWD{atomic} 
     43followed by a \emph{body expression}.  Evaluating an \KWD{atomic} 
     44expression is simply evaluating the body expression.  All reads and 
     45all writes which occur as part of this evaluation will appear to occur 
     46simultaneously in a single atomic step with respect to \emph{any} 
     47action performed by any thread which is dynamically outside.  This is 
     48specified in detail in \chapref{memory-model}.  The value and type of an 
     49\KWD{atomic} expression are the value and type of its body expression. 
     50 
     51A \KWD{tryatomic} expression consists of \KWD{tryatomic} followed by 
     52an expression.  It acts exactly like \KWD{atomic} except that in 
     53certain circumstances (see \secref{transactions}) it throws 
     54\TYP{TryAtomicFailure} and discards the effects of its body. 
     55 
     56A function or method with the modifier \KWD{atomic} acts as if its entire 
     57body were surrounded in an \KWD{atomic} expression. 
     58However, it is a static error if an API declares a functional \VAR{f} 
     59with the modifier \KWD{atomic} but a component implementing the API 
     60defines \VAR{f} whose body is an \KWD{atomic} expression without the 
     61modifier.  Functionals with the modifier \KWD{io} cannot be called 
     62within an \KWD{atomic} expression.  Thus, a 
     63functional must not have both \KWD{atomic} and \KWD{io} modifiers. 
     64 
     65When the body of an \KWD{atomic} expression completes abruptly, the 
     66\KWD{atomic} expression completes abruptly in the same way.  If it 
     67completes abruptly by exiting to an enclosing \KWD{label} expression, 
     68writes within the block are retained and become visible to other 
     69threads.  If it completes abruptly by throwing an uncaught exception, 
     70all writes to objects allocated before the \KWD{atomic} 
     71expression began evaluation are discarded.  Writes to newly 
     72allocated objects are retained.  Any variable reverts to the value it 
     73held before evaluation of the \KWD{atomic} expression began.  Thus, the 
     74only values retained from the abruptly completed \KWD{atomic} expression 
     75will be reachable from the exception object through a chain of newly 
     76allocated objects. 
     77 
     78Atomic expressions may be nested arbitrarily; the above semantics 
     79imply that an inner \KWD{atomic} expression is atomic with respect to 
     80evaluations which occur dynamically outside the inner \KWD{atomic} 
     81expression but dynamically inside an enclosing \KWD{atomic}. 
     82 
     83Implicit threads may be created dynamically within an \KWD{atomic} 
     84expression.  These implicit threads will complete before the 
     85\KWD{atomic} expression itself does so.  The implicit threads may 
     86run in parallel, and will see one another's writes; they may 
     87synchronize with one another using nested \KWD{atomic} expressions. 
     88 
     89Note that \KWD{atomic} expressions may be evaluated in parallel with 
     90other expressions.  An \KWD{atomic} expression experiences 
     91\emph{conflict} when another thread attempts to read or write a memory 
     92location which is accessed by the \KWD{atomic} expression.  The 
     93evaluation of such an expression must be partially serialized with the 
     94conflicting memory operation (which might be another \KWD{atomic} 
     95expression).  The exact mechanism by which this occurs will vary; the 
     96necessary serialization is provided by the implementation.  In 
     97general, the evaluation of a conflicting \KWD{atomic} expression may 
     98be abandoned, forcing the effects of execution to be discarded and 
     99execution to be retried.  The longer an \KWD{atomic} expression 
     100evaluates and the more memory it touches the greater the chance of 
     101conflict and the larger the bottleneck a conflict may impose. 
     102 
     103For example, 
     104the following code uses a shared counter atomically: 
     105\input{\home/basic/examples/Expr.Atomic.tex} 
     106The loop body reads \EXP{a_i} and \VAR{sum}, then adds them and 
     107writes the result back to \VAR{sum}; this will appear to occur 
     108atomically with respect to all other threads---including both other 
     109iterations of the loop body and other simultaneous calls to 
     110\VAR{accumArray}.  Note in particular that the \KWD{atomic} expression 
     111will appear atomic with respect to reads and writes of \EXP{a_i} and \VAR{sum} that do  not occur in 
     112\KWD{atomic} expressions. 
  • trunk/Specification/basic/expressions/constant.tex

    r4295 r4297  
    1818\section{Static Expressions} 
    1919\seclabel{static-expr} 
     20 
     21\note{Static expressions are not yet supported.} 
     22 
     23\emph{Static expressions} denote \emph{static values}.  Conceptually, 
     24a static expression is not evaluated while a program is running, and 
     25thus its evaluation 
     26cannot complete abruptly.  Given instantiations of all static 
     27parameters (described in \chapref{trait-parameters}) in scope of a 
     28static expression, the value of the static expression can be 
     29determined statically.  Static expressions which use a restricted subset of operations can occur as 
     30\emph{static arguments} which instantiate static parameters and 
     31\KWD{where}-clause constraints (described in \secref{where-clauses}). 
     32We define the set of static 
     33expressions by first defining the types of static expressions, and 
     34distinguishing static values from the closely related literal values. 
     35We then describe the expressions that evaluate to the various kinds of 
     36static values. 
     37 
     38 
     39\subsection{Types of Static Expressions} 
     40 
     41There are three groups of traits that describe literals 
     42and static expressions: 
     43\begin{enumerate} 
     44\item The \emph{literal} traits, which describe boolean, 
     45  character, string, and numerals.  For example, the literal \VAR{true} has 
     46  trait \EXP{\TYP{BooleanLiteral}\llbracket\VAR{true}\rrbracket} and a 
     47  character literal has trait \TYP{Character}. 
     48See \secref{literals} for a discussion of Fortress literals. 
     49 
     50\item The \emph{constant} traits, which describe values denoted by 
     51expressions composed from literals and operators (described in 
     52\secref{constant-values}); 
     53the type of a constant expression encodes the value of the expression. 
     54For example, the type of a constant expression \EXP{3+5}, 
     55%IntegerConstant[\false, 3+5\] 
     56\EXP{\TYP{IntegerConstant}\llbracket\VAR{false}, 3+5\rrbracket}, 
     57encodes the value of the expression; the operator \EXP{+} is 
     58used in the static arguments.  When an operator is not supported in static 
     59arguments, \library\ can still encode the value of the expression by 
     60providing a specific constant trait such as 
     61\EXP{\TYP{RationalValueTimesPi}\llbracket\VAR{false},1,1\rrbracket} 
     62(described in \secref{pi}). 
     63 
     64 
     65 
     66\item The \emph{static} traits, which describe values denoted by 
     67expressions composed from literals, operators (described in 
     68\secref{constant-values}), and \KWD{bool}, \KWD{nat}, 
     69and \KWD{int} parameters; here the type 
     70does not encode the value of the expression, but the value of the 
     71expression can nevertheless be known statically if specific 
     72values are specified for the static parameters.  Also, in situations 
     73where the type of an expression composed solely from literals and 
     74operators nevertheless cannot be described by a constant trait, then a 
     75static trait may be used to describe it instead. 
     76For example, a static expression \EXP{2(3+m)} where \VAR{m} is a 
     77\KWD{nat} parameter has trait \TYP{NaturalStatic}. 
     78\end{enumerate} 
     79 
     80 
     81The only operation on literals that produces a new literal (as opposed 
     82to a constant) is concatenation by using the operator \EXP{\|}. 
     83One may concatenate mixed string and 
     84character literals, producing a string literal. 
     85For example, ``\txt{foo}''\EXP{\|}''\txt{bar}'' yields ``\txt{foobar}''. 
     86One may also concatenate two natural numerals 
     87of the same radix, producing a new natural numeral of that radix. 
     88For example, \EXP{\mathtt{deadc}_{16} \| \mathtt{0de}_{16}} yields \EXP{\mathtt{deadc0de}_{16}}. 
     89 
     90Every literal trait extends an appropriate constant trait, and every 
     91constant trait extends an appropriate static trait.  So every 
     92literal is also a constant expression, and every constant expression 
     93is a static expression. 
     94 
     95 
     96 
     97 
     98\subsection{Static Expressions and Values} 
     99\seclabel{constant-values} 
     100 
     101Static parameters are static expressions. 
     102A \KWD{nat} parameter denotes a value that has type \TYP{NaturalStatic} 
     103(which extends \TYP{IntegerStatic}). 
     104An \KWD{int} parameter denotes a value that has type \TYP{IntegerStatic}. 
     105A \KWD{bool} parameter denotes a value that has type \TYP{BooleanStatic}. 
     106 
     107 
     108Boolean static expressions may be combined using the operators 
     109\EXP{\wedge}, \EXP{\vee}, \EXP{\oplus}, 
     110\EXP{\equiv}, \EXP{\leftrightarrow}, \OPR{NAND}, \OPR{NOR}, \EXP{=}, 
     111\EXP{\neq}, and \EXP{\rightarrow} (See \appref{operator-precedence} for a 
     112discussion of Fortress operators.) 
     113to produce other static expressions denoting boolean static expressions. 
     114If both operands are boolean constant expressions, then the result is also 
     115a boolean constant expression. 
     116 
     117Character static expressions may be compared using the operators \EXP{<}, 
     118\EXP{\leq}, \EXP{\geq}, \EXP{>}, 
     119\EXP{=}, and \EXP{\neq} to produce boolean static expressions.  If both 
     120operands are character constant expressions, then the result is a boolean 
     121constant expression. 
     122 
     123Numeric static expressions may be compared using the operators \EXP{<}, 
     124\EXP{\leq}, \EXP{\geq}, \EXP{>}, 
     125\EXP{=}, and \EXP{\neq} to produce boolean static expressions.  If both 
     126operands are numeric constant expressions, then the result is a boolean 
     127constant expression. 
     128 
     129Numeric static expressions may be combined using the operators and 
     130functions \EXP{+}, 
     131\EXP{-}, \EXP{\times}, \EXP{\cdot}, \EXP{/}, \EXP{!}, \OPR{MIN}, \OPR{MAX}, 
     132\EXP{\surd}, \VAR{floor}, \VAR{ceiling}, 
     133\VAR{hyperfloor}, \VAR{hyperceiling}, \EXP{\gcd}, \TYP{lcm}, \EXP{\sin}, 
     134\EXP{\cos}, \EXP{\tan}, \EXP{\arcsin}, \EXP{\arccos}, and \EXP{\arctan} 
     135to produce new numeric static expressions.  If the result is indeed 
     136a numeric static expression, and both operands are numeric constant 
     137expressions, then the result is also a numeric constant expression 
     138as long as the constant traits provided by \library\ can encode the value 
     139of the expression. 
  • trunk/Specification/basic/expressions/expressions.tex

    r4295 r4297  
    3030\input{\home/basic/expressions/bindings} 
    3131\input{\home/basic/expressions/blocks} 
    32 % \input{\home/basic/expressions/label} 
    33 % \input{\home/basic/expressions/while} 
     32\input{\home/basic/expressions/label} 
     33\input{\home/basic/expressions/while} 
    3434\input{\home/basic/expressions/generators} 
    3535\input{\home/basic/expressions/for} 
    36 % \input{\home/basic/expressions/ranges} 
    37 % \input{\home/basic/expressions/reductions} 
    38 % \input{\home/basic/expressions/if} 
    39 % \input{\home/basic/expressions/case} 
    40 % \input{\home/basic/expressions/typecase} 
     36\input{\home/basic/expressions/ranges} 
     37\input{\home/basic/expressions/reductions} 
     38\input{\home/basic/expressions/if} 
     39\input{\home/basic/expressions/case} 
     40\input{\home/basic/expressions/typecase} 
    4141\input{\home/basic/expressions/atomic} 
    42 % \input{\home/basic/expressions/spawn} 
    43 % \input{\home/basic/expressions/throw} 
    44 % \input{\home/basic/expressions/try} 
     42\input{\home/basic/expressions/spawn} 
     43\input{\home/basic/expressions/throw} 
     44\input{\home/basic/expressions/try} 
    4545\input{\home/basic/expressions/constant} 
    46 % \input{\home/basic/expressions/tuple-expr} 
    47 % \input{\home/basic/expressions/aggregate} 
    48 % \input{\home/basic/expressions/comprehensions} 
    49 % \input{\home/basic/expressions/type-annotation} 
    50 % \input{\home/basic/expressions/others} 
     46\input{\home/basic/expressions/tuple-expr} 
     47\input{\home/basic/expressions/aggregate} 
     48\input{\home/basic/expressions/comprehensions} 
     49\input{\home/basic/expressions/type-annotation} 
     50\input{\home/basic/expressions/others} 
  • trunk/Specification/basic/expressions/for.tex

    r4295 r4297  
    1818\section{For Loops} 
    1919\seclabel{for-expr} 
     20 
     21\note{Reduction variables are not yet supported.} 
     22 
     23\begin{Grammar} 
     24\emph{DelimitedExpr} &::=& 
     25\KWD{for} \emph{GeneratorClauseList} \emph{DoFront} \KWD{end}\\ 
     26 
     27\emph{DoFront} &::=& \options{\KWD{at} \emph{Expr}} \option{\KWD{atomic}} \KWD{do} \option{\emph{BlockElems}}\\ 
     28 
     29\end{Grammar} 
     30 
     31A \KWD{for} loop consists of \KWD{for} 
     32followed by a generator clause list (discussed in \secref{generators}), 
     33followed by a non-parallel \KWD{do} expression (the loop \emph{body}; 
     34see \secref{block-expr}).  Parallelism in \KWD{for} loops is specified 
     35by the generators used (see \secref{generators}); in general the 
     36programmer must assume that each loop iteration will occur 
     37independently in parallel unless every generator is explicitly 
     38\VAR{sequential}.  For each iteration, the body expression is 
     39evaluated in the scope of the values bound by the generators. 
     40The body of a \KWD{for} expression can make use of reduction variables as 
     41dscribed in \secref{reduction-vars}. 
     42The value and type of a \KWD{for} loop is \EXP{()}. 
  • trunk/Specification/basic/expressions/generators.tex

    r4295 r4297  
    1818\section{Generators} 
    1919\seclabel{generators} 
     20 
     21\note{Distributions are not yet supported.} 
     22 
     23\begin{Grammar} 
     24\emph{GeneratorClauseList} &::=& \emph{GeneratorBinding}(\EXP{,} \emph{GeneratorClause})$^*$ \\ 
     25 
     26\emph{GeneratorBinding} 
     27&::=& \emph{BindIdOrBindIdTuple}\EXP{\leftarrow}\emph{Expr} \\ 
     28 
     29\emph{GeneratorClause} 
     30&::=& \emph{GeneratorBinding} \\ 
     31&$|$& \emph{Expr} \\ 
     32 
     33\emph{BindIdOrBindIdTuple} 
     34&::=& \emph{BindId}\\ 
     35&$|$& \texttt{(} \emph{BindId}\EXP{,} \emph{BindIdList} \texttt{)}\\ 
     36 
     37\emph{BindIdList} &::=& \emph{BindId}(\EXP{,} \emph{BindId})$^*$\\ 
     38 
     39\emph{BindId} &::=& \emph{Id}\\ 
     40&$|$& \KWD{\_}\\ 
     41\end{Grammar} 
     42 
     43Fortress makes extensive use of comma-separated \emph{generator clause lists} 
     44to express parallel iteration.  Generator clause lists occur in 
     45generated expressions (described in \secref{generated}) and 
     46\KWD{for} loops (described in \secref{for-expr}), 
     47sums and big operators (described in \secref{reduction-expr}), 
     48and comprehensions (described in \secref{comprehensions}). 
     49We refer to these 
     50collectively as \emph{expressions with generator clauses}.  Every expression with 
     51generator clauses contains a \emph{body expression} which is evaluated for each 
     52combination of values bound in the generator clause list 
     53(each such combination yields an \emph{iteration} of the body). 
     54 
     55A generator clause is either a \emph{generator binding} or 
     56an expression of type \EXP{\TYP{Generator}\llbracket()\rrbracket} 
     57(this includes the type \TYP{Boolean}). 
     58A generator clause list must begin with a generator binding. 
     59A generator binding consists of one or more 
     60comma-separated identifiers followed by the token \EXP{\leftarrow}, 
     61followed by a subexpression (called the \emph{generator expression}). 
     62A generator expression evaluates to an object whose type is 
     63\TYP{Generator}.  A generator encapsulates zero or more 
     64\emph{generator iterations}.  By default, the programmer must assume 
     65that generator iterations are run in parallel in separate implicit 
     66threads unless the generators are instances of \TYP{SequentialGenerator}; the 
     67actual behavior of generators is dictated by library code, as 
     68described in \secref{defining-generators}. 
     69No generator iterations are run until the generator expression completes. 
     70For each generator iteration, a generator object produces a value or a tuple 
     71of values.  These values are bound to the identifiers to the left of the arrow, 
     72which are in scope of the subsequent generator clause list and of the 
     73body of the construct containing the generator clause list. 
     74 
     75An expression of type \EXP{\TYP{Generator}\llbracket()\rrbracket} in a 
     76generator clause list is interpreted as a \emph{filter}.  A generator 
     77iteration is performed only if the filter yields \EXP{()}. 
     78If the filter yields no value, subsequent expressions in 
     79the generator clause list will not be evaluated.  Note in particular that \VAR{true} is a \TYP{Boolean} value yielding \EXP{()} exactly once, while \VAR{false} is a \TYP{Boolean} value that yields no elements. 
     80 
     81The order of nesting of generators need not imply anything about the 
     82relative order of nesting of iterations.  In most cases, multiple 
     83generators can be considered equivalent to multiple nested loops. 
     84However, the compiler will make an effort to choose the best possible 
     85iteration order it can for a multiple-generator loop, and may even 
     86combine generators together; there may be no such guarantee for nested 
     87loops.  Thus loops with multiple generators are preferable to distinct nested loops in general. 
     88Note that the early termination behavior of nested looping is subtly 
     89different from a single multi-generator loop, since nested loops give 
     90rise to nested thread groups; see \secref{early-termination}. 
     91 
     92Each generator iteration of the innermost generator clause 
     93corresponds to a \emph{body iteration}, or simply an \emph{iteration} 
     94of the generator clause list.  Each iteration is run in its own implicit 
     95thread.  Each expression in the generator clause list can be considered 
     96to evaluate in a separate implicit thread.  Together these implicit 
     97threads form a thread group.  Evaluation of an expression with generators 
     98completes only when this thread group has completed. 
     99 
     100Some common \TYP{Generator}s include: 
     101\begin{quote} 
     102\begin{tabular}{ll} 
     103\EXP{l\COLONOP{}u}              & Any range expression \\ 
     104\EXP{a}                         & Array \VAR{a} generates its elements \\ 
     105\EXP{a.\VAR{indices}}           & The index set of array \VAR{a} \\ 
     106\EXP{\{0,1,2,3\}}               & The elements of an aggregate expression \\ 
     107\EXP{\VAR{sequential}(g)}       & A sequential version of generator \VAR{g} 
     108\end{tabular} 
     109\end{quote} 
     110The generator \EXP{\VAR{sequential}(g)} forces the iterations using 
     111values from \VAR{g} to be performed in order.  Every generator has an 
     112associated \emph{natural order} which is the order obtained by 
     113\EXP{sequential}.  For example, a sequential \KWD{for} loop starting 
     114at $1$ and going to $n$ can be written as follows: 
     115%for i <- sequential(1:n) do 
     116%  \cdots 
     117%end 
     118\begin{Fortress} 
     119\(\KWD{for} i \leftarrow \VAR{sequential}(1\COLONOP{}n) \KWD{do}\)\\ 
     120{\tt~~}\pushtabs\=\+\(  \cdots\)\-\\\poptabs 
     121\(\KWD{end}\) 
     122\end{Fortress} 
     123The \VAR{sequential} generator respects generator clause list ordering; it 
     124will always nest strictly inside preceding generator clauses and 
     125outside succeeding ones. 
     126 
     127Given a multidimensional array, the \VAR{indices} generator returns 
     128a tuple of values, which can be bound by a tuple of variables to the 
     129left of the arrow: 
     130%(i,j) <- my2DArray.indices 
     131\begin{Fortress} 
     132\((i,j) \leftarrow \VAR{my2DArray}.\VAR{indices}\) 
     133\end{Fortress} 
     134The parallelism of a loop on this generator follows the spatial 
     135distribution (discussed in \secref{distributions}) 
     136of \VAR{my2DArray} as closely as possible. 
  • trunk/Specification/basic/trait-parameters.tex

    r4271 r4297  
    1818\chapter{Static Parameters} 
    1919\chaplabel{trait-parameters} 
     20 
     21\section{Type Parameters} 
     22\seclabel{type-param} 
     23\section{Nat and Int Parameters} 
     24\seclabel{natparams} 
     25\section{Bool Parameters} 
     26\seclabel{boolparams} 
     27\section{Dimension and Unit Parameters} 
     28\seclabel{dimunitparams} 
     29\section{Operator Parameters} 
     30\seclabel{opr-ident} 
     31\section{Where Clauses} 
     32\seclabel{where-clauses} 
  • trunk/Specification/basic/types-vals-vars.tex

    r4271 r4297  
    1818\chapter{Types} 
    1919\chaplabel{types} 
     20 
     21\section{Kinds of Types} 
     22\seclabel{type-kinds} 
     23\section{Relationships between Types} 
     24\seclabel{type-relations} 
     25\section{Trait Types} 
     26\seclabel{trait-types} 
     27\section{Object Expression Types} 
     28\seclabel{object-exp-types} 
     29\section{Tuple Types} 
     30\seclabel{tuple-types} 
     31\section{Arrow Types} 
     32\seclabel{arrow-types} 
     33\section{Function Types} 
     34\seclabel{function-types} 
     35\section{Special Types} 
     36\seclabel{bottom-type} 
     37\section{Types in the Fortress Standard Libraries} 
     38\seclabel{types-libraries} 
     39\section{Intersection and Union Types} 
     40\seclabel{internal-types} 
     41\section{Type Aliases} 
     42\seclabel{type-alias} 
  • trunk/Specification/basic/variables.tex

    r4271 r4297  
    1818\chapter{Variables} 
    1919\chaplabel{variables} 
     20 
     21\section{Top-Level Variable Declarations} 
     22\seclabel{top-var-decls} 
     23\section{Local Variable Declarations} 
     24\seclabel{local-var-decls} 
     25\section{Matrix Unpasting} 
     26\seclabel{unpasting}