mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-15 19:28:47 +00:00
Continue Spec
This commit is contained in:
parent
34eed3c71a
commit
a79cb93cf1
8 changed files with 314 additions and 70 deletions
105
doc/spec/03.03.scope_expressions.tex
Normal file
105
doc/spec/03.03.scope_expressions.tex
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
\begin{figure}[t]
|
||||
\[
|
||||
\begin{array}{rcl}
|
||||
\defterm{scopeExpression} & : & \nonterm{definition}^\star\s\nonterm{expression}\\
|
||||
\defterm{definition} & : & \nonterm{variableDefinition}\alt\nonterm{functionDefinition}\alt\nonterm{infixDefinition}\\
|
||||
\defterm{variableDefinition} & : & (\s\term{local}\alt\term{public}\s)\s\nonterm{variableDefinitionSequence}\s\term{;}\\
|
||||
\defterm{variableDefinitionSequence} & : & \nonterm{variableDefinitionSequenceItem}\s(\s\term{,}\s\nonterm{variableDefinitionSequenceItem}\s)^\star\\
|
||||
\defterm{variableDefinitionSequenceItem} & : & \token{LIDENT}\s[\s\term{=}\s\nonterm{basicExpression}\s]\\
|
||||
\defterm{functionDefinition} & : & [\s\term{public}\s]\s\term{fun}\s\token{LIDENT}\s\term{(}\s\nonterm{functionArguments}\s\term{)}\s\nonterm{functionBody}\\
|
||||
\defterm{functionArguments} & : & [\s\token{LIDENT}\s(\s\term{,}\s\token{LIDENT}\s)^\star\s]\\
|
||||
\defterm{functionBody} & : & \term{\{}\s\nonterm{scopeExpression}\s\term{\}}
|
||||
\end{array}
|
||||
\]
|
||||
\caption{Scope expression concrete syntax}
|
||||
\label{scope_expression}
|
||||
\end{figure}
|
||||
|
||||
\section{Scope Expressions}
|
||||
|
||||
Scope expressions provide a mean to put expressions is a scoped context. The definitions in scoped expressions comprise of function definitions and
|
||||
variable definitions (see Fig.~\ref{scope_expression}). For example:
|
||||
|
||||
\begin{lstlisting}
|
||||
local x, y, z; -- variable definitions
|
||||
|
||||
fun id (x) {x} -- function definition
|
||||
\end{lstlisting}
|
||||
|
||||
As scope expressions are expressions, they can be nested:
|
||||
|
||||
\begin{lstlisting}
|
||||
local x;
|
||||
|
||||
{ -- nested scope begins here
|
||||
local y;
|
||||
skip
|
||||
} -- nested scope ends here
|
||||
\end{lstlisting}
|
||||
|
||||
The definitions on the top-level of compilation unit can be tagged as ``\lstinline|public|'', in which case they are exported and become visible by
|
||||
other units which import the given one. Nested scopes can not contain public definitions.
|
||||
|
||||
The nesting relation has the shape of a tree, and in a concrete node of the tree all definitions in all enclosing scopes are visible:
|
||||
|
||||
\begin{lstlisting}
|
||||
local x;
|
||||
|
||||
{local y;
|
||||
{local z;
|
||||
skip -- x, y, and z are visible here
|
||||
};
|
||||
{local t;
|
||||
skip -- x, y, and t are visible here
|
||||
};
|
||||
skip -- x and y are visible here
|
||||
};
|
||||
skip -- only x is visible here
|
||||
\end{lstlisting}
|
||||
|
||||
Multiple definitions of the same name in the same scope are prohibited:
|
||||
|
||||
\begin{lstlisting}
|
||||
local x;
|
||||
fun x () {0} -- error
|
||||
\end{lstlisting}
|
||||
|
||||
However, a definition is a nested scope can override a definition in an enclosing one:
|
||||
|
||||
\begin{lstlisting}
|
||||
local x;
|
||||
|
||||
{
|
||||
fun x () {0} -- ok
|
||||
skip -- here x is associated with the function
|
||||
};
|
||||
|
||||
skip -- here x is asociated with the variable
|
||||
\end{lstlisting}
|
||||
|
||||
A function can freely use all visible definitions; in particular, functions defined in the
|
||||
same scope can be mutually recursive:
|
||||
|
||||
\begin{lstlisting}
|
||||
local x;
|
||||
fun f () {0}
|
||||
|
||||
{
|
||||
fun g () {f () + h () + y} -- ok
|
||||
fun h () {g () + x} -- ok
|
||||
local y;
|
||||
skip
|
||||
};
|
||||
skip
|
||||
\end{lstlisting}
|
||||
|
||||
A variable, defined in a scope, can be attributed with an expression, calcualting its initial value.
|
||||
These expressions, however, are evaluated in the order of variable declaration. Thus, while
|
||||
technically it is possible to have forward references in the initialization expression, their
|
||||
behaviour is undefined. For example:
|
||||
|
||||
\begin{lstlisting}
|
||||
local x = y + 2; -- undefined, as y is not yet initialized at this point
|
||||
local y = x + 2;
|
||||
skip
|
||||
\end{lstlisting}
|
||||
Loading…
Add table
Add a link
Reference in a new issue