From 4f618598f2f31bc466343e4d304f35b53a366da6 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Mon, 15 Mar 2021 16:59:32 -0400 Subject: Finish namespace specification --- docs/spec/scope.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/spec/scope.html') diff --git a/docs/spec/scope.html b/docs/spec/scope.html index d5280e31..8ed5bab2 100644 --- a/docs/spec/scope.html +++ b/docs/spec/scope.html @@ -22,9 +22,10 @@

Special names such as 𝕩 or 𝕣 refer to variables, but have no definition and do not use scoping. Instead, they always refer to the immediately enclosing scope, and are defined automatically when the block is evaluated.

The six special names are 𝕨𝕩𝕗𝕘𝕤𝕣, and the tokens 𝕎𝕏𝔽𝔾𝕊, _𝕣, and _𝕣_ are alternate spellings of these names as described in the tokenization rules. Special names may be modified with assignment but cannot appear as the target of other kinds of assignment. Two special names represent the same identifier if they are the same name and appear in the same body. The initial value these names have is defined by the evaluation rules; the grammar for blocks ensures that all special names used in a block will be defined (possibly as the special value · in the case of 𝕨).

Imports and exports

-

The names to be used in an IMPORT, that is, LHS_NAME terms in an NS_VAR or nsLHS, are variable references inside that IMPORT's brNS term. If they appear without an accompanying lhs "⇐" term (in NS_VAR), then this is in addition to their role as identifiers within the actual enclosing scope, which works like any other assignment. These references behave as though they are at the end of the brNS term, that is, they "see" all definitions in the block. However, they must refer to identifiers that are exported by that block; references to any other variable cause an error much like references that have no definition.

-

An identifier is exported if the ASGN node in its definition is "⇐", or if it appears anywhere in an EXPORT term. An identifier can only be exported in the scope where it is defined, and not in a containing scope. An EXPORT term that includes an identifier from such a scope causes an error.

+

Names that are preceded by an atom "." term, or that appear as LHS_NAME terms in an NS_VAR or lhsNs, are variable references in a namespace: in the first case, the result of the atom node, and in the second, of the overall assignments subExpr right hand side. These names do not follow lexical scoping; in general they must be stored in order to perform a name lookup when the namespace is available. Such a name in lhsNs, or in NS_VAR with no accompanying lhs "⇐" term, additionally serves as an identifier within the actual enclosing scope, which works like any other assignment.

+

An identifier is exported if the ASGN node in its definition is "⇐", or if it appears anywhere in an EXPORT term. An identifier can only be exported in the scope where it is defined, and not in a containing scope. An EXPORT term that includes an identifier from such a scope causes an error.

Variables

A variable is an entity that permits two operations: it can be set to a particular value, and its value can be obtained, resulting in the last value it was set to. When either operation is performed it is referred to as accessing the variable.

-

When a body in a block is evaluated, a variable is created for each definition (that is, defined identifier instance) the body contains. Whenever another block—the block itself, not its contents—is evaluated during the execution of the block, it is linked to the currently-evaluating block, so that it will use the variables defined in this instance. By following these links repeatedly, an instance of a block is always linked to exactly one instance of each block that contains it. These links form a tree that is not necessarily related to the call stack of functions and modifiers. Using the links, the variable an identifier refers to is the one corresponding to that variable's definition in the linked instance of the containing scope for the definition.

+

When a body in a block is evaluated, it creates a namespace, which contains a variable for each definition (that is, defined identifier instance) the body contains. Whenever another block—the block itself, not its contents—is evaluated during the execution of the block, it is linked to the currently-evaluating block, so that it will use the variables defined in this instance. By following these links repeatedly, an instance of a block is always linked to exactly one instance of each block that contains it. These links form a tree that is not necessarily related to the call stack of functions and modifiers. Using the links, the variable an identifier refers to is the one corresponding to that variable's definition in the linked instance of the containing scope for the definition.

The first access to a variable must be made by its definition (this also means it sets the variable). If a different instance of its identifier accesses it first, then an error results. This can happen because every scope contained in a particular scope sees all the definitions it uses, and such a scope could be called before the definition is run. Because of conditional execution, this property must be checked at run time in general; however, in cases where it is possible to statically determine that a program will always violate it, a BQN instance can give an error at compile time rather than run time.

+

A namespace defines a mapping from names to variables: if the given name is shared by an exported identifier in the body used to create that namespace, then that name maps to the variable corresponding to that identifier. The mapping is undefined for other names.

-- cgit v1.2.3