From 7b72e5bc82cf075fc1807e289c553b292ab5e038 Mon Sep 17 00:00:00 2001 From: Matthew Pope Date: Thu, 17 Oct 2024 01:45:45 -0700 Subject: [PATCH 1/5] Adds chapters on modules --- _books/ion-1-1/src/SUMMARY.md | 6 +- _books/ion-1-1/src/modules.md | 145 +++++------ .../ion-1-1/src/modules/defining_modules.md | 242 ++++++++++++++++++ .../src/modules/encoding_directives.md | 30 --- _books/ion-1-1/src/modules/encoding_module.md | 70 ++++- _books/ion-1-1/src/modules/grammar.md | 73 ++++++ _books/ion-1-1/src/modules/inner_modules.md | 84 ++++++ _books/ion-1-1/src/modules/shared_modules.md | 44 ++++ _books/ion-1-1/src/modules/system_module.md | 2 +- 9 files changed, 588 insertions(+), 108 deletions(-) create mode 100644 _books/ion-1-1/src/modules/defining_modules.md delete mode 100644 _books/ion-1-1/src/modules/encoding_directives.md create mode 100644 _books/ion-1-1/src/modules/grammar.md create mode 100644 _books/ion-1-1/src/modules/inner_modules.md create mode 100644 _books/ion-1-1/src/modules/shared_modules.md diff --git a/_books/ion-1-1/src/SUMMARY.md b/_books/ion-1-1/src/SUMMARY.md index 56e688cb..08f995ac 100644 --- a/_books/ion-1-1/src/SUMMARY.md +++ b/_books/ion-1-1/src/SUMMARY.md @@ -8,8 +8,12 @@ - [Special forms](macros/special_forms.md) - [System macros](macros/system_macros.md) - [Modules](modules.md) - - [Encoding module](modules/encoding_module.md) + - [Defining modules](modules/defining_modules.md) + - [The encoding module](modules/encoding_module.md) + - [Shared modules](modules/shared_modules.md) + - [Inner modules](modules/inner_modules.md) - [The system module](modules/system_module.md) + - [Grammar](modules/grammar.md) - [Binary encoding](binary/encoding.md) - [Encoding primitives](binary/primitives.md) - [`FlexUInt`](binary/primitives/flex_uint.md) diff --git a/_books/ion-1-1/src/modules.md b/_books/ion-1-1/src/modules.md index e5a07ee3..f41cc502 100644 --- a/_books/ion-1-1/src/modules.md +++ b/_books/ion-1-1/src/modules.md @@ -9,106 +9,101 @@ Ion 1.1 also introduces the concept of a _module_, an organizational unit that h > [!TIP] > You can think of an Ion 1.0 symbol table as a module with an empty macro table. -In Ion 1.1, each stream has an [encoding module](modules/encoding_module.md)--the active `(symbol table, macro table)` pair that is being used to encode the stream. +In Ion 1.1, each stream has an [encoding module](modules/encoding_module.md)—the active `(symbol table, macro table)` pair that is being used to encode the stream. -## Identifiers +## Module Interface -Many of the grammatical elements used to define modules and macros are _identifiers_--symbols that do not require quotation marks. +The interface to a module consists of: -More explicitly, an identifier is a sequence of one or more ASCII letters, digits, or the characters `$` (dollar sign) or `_` (underscore), not starting with a digit. It also cannot be of the form `$\d+`, which is the syntax for symbol IDs. (For example: `$3`, `$10`, `$458`, etc.) +* its _spec version_, denoting the Ion version used to define the module +* its _exported symbols_, an array of strings denoting symbol content +* its _exported macros_, an array of `` pairs, where all names are unique identifiers (or null). -## Defining a module +The spec version is external to the macro body and the precise way it is determined depends on the type of module being defined. This is explained in further detail in [Module Versioning](#module-versioning). -A module has four kinds of subclauses: +The exported symbol array is denoted by the `symbol_table` clause of a module definition, and +by the `symbols` field of a shared symbol table. -1. `symbol_table` - an exported list of text values. -2. `macro_table` - an exported list of macro definitions. -3. `module` - a nested module definition. -4. `import` - a reference to a shared module definition +The exported macro array is denoted by the module’s `macro_table` clause, with addresses +allocated to macros or macro bindings in the order they are declared. - +The exported symbols and exported macros are defined in the [module body](body.md). -### `symbol_table` -The `symbol_table` clause assembles a list of text values for the module to export. It takes any number of arguments. +## Types of Modules -#### Syntax -```ion -(symbol_table arg1 arg2 ... argN) -``` +There are multiple types of modules. +All modules share the same interface, but vary in their implementation in order to support a variety of different use cases. -#### Processing +| Module Type | Purpose | +|:----------------------------------------------|:---------------------------------------------------------------| +| [Encoding Module](modules/encoding_module.md) | Defining the local encoding context | +| [System Module](modules/system_module.md) | Defining system symbols and macros | +| [Inner Module](modules/inner_modules.md) | Organizing symbols and macros and limiting the scope of macros | +| [Shared Module](modules/shared_modules.md) | Defining symbols and macros outside of the data stream | -When the `symbol_table` clause is encountered, the reader constructs an empty list. The arguments to the clause are then processed from left to right. -For each `arg`: -* **If the `arg` is a list of text values**, the nested text values are appended to the end of the symbol table being constructed. - * When `null`, `null.string`, `null.symbol`, or `$0` appear in the list of text values, this creates a symbol with unknown text. - * The presence of any other Ion value in the list raises an error. -* **If the `arg` is the name of a module**, the symbols in that module's symbol table are appended to the end of the symbol table being constructed. -* **If the `arg` is anything else**, the reader must raise an error. +## Module Versioning -#### Example `symbol_table` +Every module definition has a _spec version_ that determines the syntax and semantics of the module body. +A module’s spec version is expressed in terms of a specific Ion version; the meaning of the module is as defined by that version of the Ion specification. -```ion -(symbol_table // Constructs an empty symbol table (list) - ["a", b, 'c'] // The text values in this list are appended to the table - foo // Module `foo`'s symbol table values are appended to the table - ['''g''', "h", i]) // The text values in this list are appended to the table -``` -If module `foo`'s symbol table were `[d, e, f]`, then the symbol table defined by the above clause would be: -```ion -["a", "b", "c", "d", "e", "f", "g", "h", "i"] -``` +The spec version for an encoding module is implicitly derived from the Ion version of its containing segment. +The spec version for a shared module is denoted via a required annotation. +The spec version of an inner module is always the same as its containing module. +The spec version of a system module is the Ion version in which it was specified. -### `macro_table` +To ensure that all consumers of a module can properly understand it, a module can only import +shared modules defined with the same or earlier spec version. -The `macro_table` clause assembles a list of macro definitions for the module to export. It takes any number of arguments. +#### Examples +The spec version of a shared module must be declared explicitly using an annotation of the form `$ion_1_N`. +This allows the module to be serialized using any version of Ion, and its meaning will not change. -#### Syntax ```ion -(macro_table arg1 arg2 ... argN) +$ion_shared_module:: +$ion_1_1::("com.example.symtab" 3 + (symbol_table ...) + (macro_table ...)) ``` -#### Processing -When the `macro_table` clause is encountered, the reader constructs an empty list. The arguments to the clause are then processed from left to right. +The spec version of an encoding module is always the same as the Ion version of its enclosing segment. -For each `arg`: -* **If the `arg` is a `macro` clause**, the clause is processed and the resulting macro definition is appended to the end of the macro table being constructed. -* **If the `arg` is the name of a module**, the macro definitions in that module's macro table are appended to the end of the macro table being constructed. -* **If the `arg` is anything else**, the reader must raise an error. - - -Macro definitions being added to the macro table must have a unique name. If a macro is added whose name conflicts with one already present in the table, the reader must raise an error. +```ion +$ion_1_1 +$ion_encoding::( + // Module semantics specified by Ion 1.1 + ... +) + +// ... + +$ion_1_3 +$ion_encoding::( + // Module semantics specified by Ion 1.3 + ... +) +//... // Assuming no IVM +$ion_encoding::( + // Module semantics specified by Ion 1.3 + ... +) +``` -### `macro` +## Identifiers -The `macro` clause defines a new macro. See _[Defining macros](macros/defining_macros.md)_. +Many of the grammatical elements used to define modules and macros are _identifiers_--symbols that do not require quotation marks. - - - +More explicitly, an identifier is a sequence of one or more ASCII letters, digits, or the characters `$` (dollar sign) or `_` (underscore), not starting with a digit. It also cannot be of the form `$\d+`, which is the syntax for symbol IDs. (For example: `$3`, `$10`, `$458`, etc.) -## Grammar +```bnf +identifier ::= identifier-start identifier-char* -Literals appear in `code blocks`. Terminals are described in _italic text_. +identifier-start ::= letter + | '_' + | '$' letter + | '$_' + | '$$' -| Production | | Body | -|----------------------|-----|--------------------------------------------------------| -| module | ::= | `(module ` module-name-decl module-body `)` | -| module-body | ::= | import* module* symtab? mactab? | -| import | ::= | `(import` module-name catalog-name catalog-version `)` | -| symtab | ::= | `(symbol_table ` symtab-item* `)` | -| symtab-item | ::= | module-name \| symbol-def-seq | -| symbol-def-seq | ::= | _a list of unannotated text values (string/symbol)_ | -| mactab | ::= | `(macro_table ` mactab-item* `)` | -| mactab-item | ::= | module-name \| macro-def \| macro-export | -| macro-def | ::= | `(macro ` macro-name signature tdl-template `)` | -| macro-export | ::= | `(export ` macro-ref macro-name? `)` | -| catalog-name | ::= | _unannotated string_ | -| catalog-version | ::= | _unannotated int_ | -| module-name | ::= | _unannotated idenfitier symbol_ | -| macro-ref | ::= | macro-name \| qualified-macro-name \| macro-address | -| macro-name-decl | ::= | macro-name-ref \| `null` | -| macro-name | ::= | _unannotated idenfitier symbol_ | -| qualified-macro-name | ::= | module-name `::` macro-name | +identifier-char ::= letter | number | '$' | '_' +``` diff --git a/_books/ion-1-1/src/modules/defining_modules.md b/_books/ion-1-1/src/modules/defining_modules.md new file mode 100644 index 00000000..0caa4b6e --- /dev/null +++ b/_books/ion-1-1/src/modules/defining_modules.md @@ -0,0 +1,242 @@ +# Defining Modules + +A module is defined by four kinds of subclauses which, if present, always appear in the same order. + +1. `import` - a reference to a shared module definition; repeatable +2. `module` - a nested module definition; repeatable +3. `symbol_table` - an exported list of text values +4. `macro_table` - an exported list of macro definitions + + +### Internal Environment + +The body of a module tracks an internal environment by which macro references are resolved. +This environment is constructed incrementally by each clause in the definition and consists of: + +* the _visible modules_, a map from identifier to module +* the _exported macros_, an array containing name/macro pairs + +Before any clauses of the module definition are examined, the initial environment is as follows: + +* The visible modules map `$ion` to the system module for the appropriate spec version. + Inside an encoding directive, the visible modules also maps `$ion_encoding` to the current encoding module. + For an inner module, it also includes the modules previously made available by the enclosing + module (via `import` or `module`). +* The macro table and symbol table are empty. + +Each clause affects the environment as follows: + +* An `import` declaration retrieves a shared module from the implementation’s catalog, assigns + it a name in the visible modules, and makes its macros available for use. + An error must be signaled if the name already appears in the visible modules. +* A `module` declaration defines a new module and assigns it a name in the visible modules. + An error must be signaled if the name already appears in the visible modules. +* A `macro_table` declaration defines the exported macros. + +### Resolving Macro References + +Within a module definition, macros can be referenced in several contexts using the following +_macro-ref_ syntax: + +```bnf +qualified-ref ::= module-name '::' macro-ref + +macro-ref ::= macro-name | macro-addr + +macro-name ::= unannotated-identifier-symbol + +macro-addr ::= unannotated-uint +``` + +Macro references are resolved to a specific macro as follows: + +* An unqualified _macro-name_ is looked up within the exported macros, and if not found, then the system module. + If it maps to a macro, that’s the resolution of the reference. + Otherwise, an error is signaled due to an unbound reference. +* An anonymous local reference (`__address__`) is resolved by index in the exported macro array. + If the address exceeds the array boundary, an error is signaled due to an invalid reference. +* A qualified reference (`__module__::__name-or-address__`) resolves solely against the referenced module. + If the module name does not exist in the visible modules, an error is signaled due to an unbound reference. + Otherwise, the name or address is resolved within that module’s exported macro array. + +> [!WARNING] +> An unqualified macro name can change meaning in the middle of a module if you choose to shadow the +> name of a system macro. The system macros are imported and used with that meaning, then a declaration +> shadows that name and gives it a new meaning. + + +### `import` + +```bnf +import ::= '(import ' module-name catalog-key ')' +``` + +An import binds a lexically scoped module name to a shared symbol table that is identified by a catalog key—that is a `(name, version)` pair. The `version` of the catalog key is optional—when omitted, the version is implicitly 1. + +In Ion 1.0, imports may be substituted with a different version if an exact match is not found. +In Ion 1.1, however, all imports require an exact match to be found in the reader's catalog; +if an exact match is not found, the implementation must signal an error. + + + +### `module` + +The `module` clause defines a new module that is contained in the current module. + +```bnf +inner-module ::= '(module' module-name import* symbol-table? macro-table? ')' +``` + +Inner modules automatically have access to modules previously declared in the containing module using `module` or `import`. +The new module (and its exported symbols and macros) is available to any following `module`, `symbol_table`, and +`macro_table` clauses in the enclosing container. + +See [inner modules](inner_modules.md) for full explanation. + +### `symbol_table` + +A module can define a list of exported symbols by copying symbols from other modules and/or declaring new symbols. + +```bnf +symbol-table ::= '(symbol_table' symbol-table-entry* ')' + +symbol-table-entry ::= module-name | symbol-list + +symbol-list ::= '[' (symbol | string)* ']' +``` + +The `symbol_table` clause assembles a list of text values for the module to export. +It takes any number of arguments, each of which may be the name of visible module or a list of symbol-texts. +The symbol table is a list of symbol-texts by concatenating the symbol tables of named modules and lists of symbol/string values. + +Where a module name occurs, its symbol table is appended. +(The module name must refer to another module that is visible to the current module.) +Unlike Ion 1.0, no _symbol-maxid_ is needed because Ion 1.1 always required exact matches for imported modules. + +Where a list occurs, it must contain only non-null, unannotated strings and symbols. +The text of these strings and/or symbols are appended to the symbol table. +Upon encountering any non-text value, null value, or annotated value in the list, the implementation shall signal an error. +To create an intentional gap in the symbol table, one may use `$0`. + +All modules have a symbol table, so when a module has no `symbol_table` clause, the module has an empty symbol table. + +#### Processing + +When the `symbol_table` clause is encountered, the reader constructs an empty list. The arguments to the clause are then processed from left to right. + +For each `arg`: +* **If the `arg` is a list of text values**, the nested text values are appended to the end of the symbol table being constructed. + * When `$0` appears in the list of text values, this creates a symbol with unknown text. + * The presence of any other Ion value in the list raises an error. +* **If the `arg` is the name of a module**, the symbols in that module's symbol table are appended to the end of the symbol table being constructed. +* **If the `arg` is anything else**, the reader must raise an error. + +#### Example + +```ion +(symbol_table // Constructs an empty symbol table (list) + ["a", b, 'c'] // The text values in this list are appended to the table + foo // Module `foo`'s symbol table values are appended to the table + ['''g''', "h", i]) // The text values in this list are appended to the table +``` +If module `foo`'s symbol table were `[d, e, f]`, then the symbol table defined by the above clause would be: +```ion +["a", "b", "c", "d", "e", "f", "g", "h", "i"] +``` + + +```ion +$ion_1_0 +$ion_symbol_table::{ + imports: [{ name: "com.example.shared1", version: 1, max_id: 10 }, + { name: "com.example.shared2", version: 2, max_id: 20 }], + symbols: ["s1", "s2"] +} +``` +Here’s the Ion 1.1 equivalent in terms of symbol allocation order: + +```ion +$ion_1_1 +$ion_encoding::( + (import m1 "com.example.shared1" 1) + (import m2 "com.example.shared2" 2) + (symbol_table m1 m2 ["s1", "s2"]) +) +``` + + + +### `macro_table` + +Macros are declared after symbols. +The `macro_table` clause assembles a list of macro definitions for the module to export. It takes any number of arguments. +All modules have a macro table, so when a module has no `macro_table` clause, the module has an empty macro table. + +Most commonly, a macro table entry is a definition of a new macro expansion function, following +this general shape: + +When no name is given, this defines an anonymous macro that can be referenced by its numeric +address (that is, its index in the enclosing macro table). +Inside the defining module, that uses a local reference like `12`. + +The _signature_ defines the syntactic shape of expressions invoking the macro; +see [Macro Signatures](../macros/defining_macros.md#macro-signatures) for details. +The _template_ defines the expansion of the macro, in terms of the signature’s parameters; +see [Template Expressions](../macros/defining_macros.md#template-definition-language-tdl) for details. + +Imported macros must be explicitly exported if so desired. +Module names and `export` clauses can be intermingled with `macro` definitions inside the `macro_table`; +together, they determine the bindings that make up the module’s exported macro array. + +The _module-name_ export form is shorthand for referencing all exported macros from that module, +in their original order with their original names. + +An `export` clause contains a single macro reference followed by an optional alias for the exported macro. +The referenced macro is appended to the macro table. + +> [!TIP] +> No name can be repeated among the exported macros, including macro definitions. +> Name conflicts must be resolved by `export`s with aliases. + +#### Processing + +When the `macro_table` clause is encountered, the reader constructs an empty list. The arguments to the clause are then processed from left to right. + +For each `arg`: +* **If the `arg` is a `macro` clause**, the clause is processed and the resulting macro definition is appended + to the end of the macro table being constructed. +* **If the `arg` is an `export` clause**, the clause is processed and the referenced macro definition is appended + to the end of the macro table being constructed. +* **If the `arg` is the name of a module**, the macro definitions in that module's macro table are appended + to the end of the macro table being constructed. +* **If the `arg` is anything else**, the reader must raise an error. + + +A macro name is a symbol that can be used to reference a macro, both inside and outside the module. +Macro names are optional, and improve legibility when using, writing, and debugging macros. +When a name is used, it must be an identifier per Ion’s syntax for symbols. +Macro definitions being added to the macro table must have a unique name. +If a macro is added whose name conflicts with one already present in the table, the implementation must raise an error. + +#### `macro` + +A `macro` clause [defines a new macro](../macros/defining_macros.md). +When the macro declaration uses a name, an error must be signaled if it already appears in the exported macro array. + +#### `export` + +An `export` clause declares a name for an existing macro and appends the macro to the macro table. +* If the reference to the existing macro is followed by a name, the existing macro is appended to the exported + macro array with the latter name instead of the original name, if any. + An error must be signaled if that name already appears in the exported macro array. +* If the reference to the existing macro is followed by `null`, the macro is appended to the exported macro array + without a name, regardless of whether the macro has a name. +* If the reference to the existing macro is anonymous, the macro is appended to the exported macro array without + a name. +* When the reference to the existing macro uses a name, the name and macro are appended to the exported macro + array. An error must be signaled if that name already appears in the exported macro array. + + +#### Module names in `macro_table` +A module name appends all exported macros from the module to the exported macro array. +If any exported macro uses a name that already appears in the exported macro array, an error must be signaled. diff --git a/_books/ion-1-1/src/modules/encoding_directives.md b/_books/ion-1-1/src/modules/encoding_directives.md deleted file mode 100644 index 4999c0ea..00000000 --- a/_books/ion-1-1/src/modules/encoding_directives.md +++ /dev/null @@ -1,30 +0,0 @@ -## Encoding directives - -The _encoding module_ is the module that is currently being used to encode the data stream. When the stream begins, the encoding module is the [system module](system_module.md). - -The application may define a new encoding module by writing an _encoding directive_ at the top level of the stream. An encoding directive is an s-expression annotated with `$ion_encoding`; its nested clauses define a new encoding module. - -#### Example encoding directive -```ion -$ion_encoding::( - (symbol_table [ - "a", // $1 - "b", // $2 - "c" // $3 - ]) - (macro_table - (macro pi () 3.14159265) - (macro moon_landing_ts 1969-07-20T20:17Z) - ) -) -``` - -When the reader advances beyond the encoding directive, the module it defined becomes the new encoding module. - -### Modules - -In the context of an encoding directive, the encoding module is named `$ion_encoding`. - -The encoding directive may preserve symbols or macros that were defined in the previous encoding directive. - - diff --git a/_books/ion-1-1/src/modules/encoding_module.md b/_books/ion-1-1/src/modules/encoding_module.md index 96ff7f66..f17b1cd5 100644 --- a/_books/ion-1-1/src/modules/encoding_module.md +++ b/_books/ion-1-1/src/modules/encoding_module.md @@ -1 +1,69 @@ -# Encoding module +# The Encoding module + +The _encoding module_ is the module that is currently being used to encode the data stream. +When the stream begins, the encoding module is the [system module](system_module.md). + +The application may define a new encoding module by writing an _encoding directive_ at the top level of the stream. +An encoding directive is an s-expression annotated with `$ion_encoding`; its nested clauses define a new encoding module. + +When the reader advances beyond an encoding directive, the module it defined becomes the new encoding module. + +In the context of an encoding directive, the current encoding module is named `$ion_encoding`. +The encoding directive may preserve symbols or macros that were defined in the previous encoding directive by referencing `$ion_encoding`. +The `$ion_encoding` module may only be imported to an encoding directive, and it is done so automatically and implicitly. + +### Examples + +#### An encoding directive +A simple encoding directive—it defines a module that exports three symbols and two macros. +```ion +$ion_encoding::( + (symbol_table [ + "a", // $1 + "b", // $2 + "c" // $3 + ]) + (macro_table + (macro pi () 3.14159265) + (macro moon_landing_ts () 1969-07-20T20:17Z) + ) +) +``` + +#### Adding symbols to the current encoding module +The implicitly imported `$ion_encoding` is used to append to the current symbol and macro tables. + +```ion +$ion_encoding::( + (symbol_table [ + "a", // $1 + "b", // $2 + "c", // $3 + ]) + (macro_table + (macro pi () 3.14159265) + (macro moon_landing_ts () 1969-07-20T20:17Z) + ) +) + +// ... + +$ion_encoding::( + (symbol_table $ion_encoding + [ + "d", // $4 + "e", // $5 + "f", // $6 + ]) + (macro_table $ion_encoding + (macro e () 2.71828182)) +) + +// ... +``` + +#### Clearing the local symbols and local macros +```ion +$ion_encoding::() +``` +The absence of the `symbol_table` and `macro_table` clauses is interpreted as empty symbol and macro tables. diff --git a/_books/ion-1-1/src/modules/grammar.md b/_books/ion-1-1/src/modules/grammar.md new file mode 100644 index 00000000..bdbbc6ee --- /dev/null +++ b/_books/ion-1-1/src/modules/grammar.md @@ -0,0 +1,73 @@ +# Module Grammar + +```bnf +encoding-directive ::= '$ion_encoding::(' module-body ')' + +shared-module ::= '$ion_shared_module::' ion-version-marker '::(' catalog-key module-body ')' + +ion-version-marker ::= '$ion_1_0' | '$ion_1_1' + +module-body ::= import* inline-module* symbol-table? macro-table? + +import ::= '(import ' module-name catalog-key ')' + +catalog-key ::= catalog-name catalog-version? + +catalog-version ::= int // positive, unannotated + +catalog-name ::= string + +inner-module ::= '(module' module-name import* symbol-table? macro-table? ')' + +module-name ::= unannotated-identifier-symbol + + + +// Symbol Tables + +symbol-table ::= '(symbol_table' symbol-table-entry* ')' + +symbol-table-entry ::= module-name | symbol-list + +symbol-list ::= '[' (symbol | string)* ']' + + +// Macro Tables + +macro-table ::= '(macro_table' macro-table-entry* ')' + +macro-table-entry ::= macro-definition + | macro-export + | module-name + +macro-definition ::= '(macro' macro-name-declaration signature template-expression ')' + +macro-export ::= '(export' qualified-macro-ref macro-name-declaration? ')' + +macro-name-declaration ::= macro-name | 'null' + +qualified-macro-ref ::= module-name '::' macro-ref + +macro-ref ::= macro-name | macro-addr + +qualified-macro-name ::= module-name '::' macro-name + +macro-name ::= unannotated-identifier-symbol + +macro-addr ::= unannotated-uint + +signature ::= '(' macro-parameter* ')' + +macro-parameter ::= parameter-encoding? parameter-name parameter-cardinality? + +parameter-encoding ::= (primitive-encoding-type | macro-name | qualified-macro-name)'::' + +primitive-encoding-type ::= 'uint8' | 'uint16' | 'uint32' | 'uint64' + | 'int8' | 'int16' | 'int32' | 'int64' + | 'float16' | 'float32' | 'float64' + | 'flex_int' | 'flex_uint' | 'flex_sym' | 'flex_string' + +parameter-name ::= unannotated-identifier-symbol + +parameter-cardinality ::= '!' | '*' | '?' | '+' +``` diff --git a/_books/ion-1-1/src/modules/inner_modules.md b/_books/ion-1-1/src/modules/inner_modules.md new file mode 100644 index 00000000..d0bf1351 --- /dev/null +++ b/_books/ion-1-1/src/modules/inner_modules.md @@ -0,0 +1,84 @@ +# Inner Modules + +Inner modules are defined within another module, and can be referenced only within the enclosing module. +Their scope is lexical; they can be referenced immediately following their definition, up until the end of the containing module. + +Inline modules always have a symbolic name given at the point of definition. +They inherit their spec version from the containing module, and they have no content version. +Inner modules automatically have access to modules previously declared in their containing module using `module` or `import`. +Inner modules may not contain their own nested inner modules. + +### Examples + +Inner modules can be used to define helper macros and use them by name in the definitions of other macros without +having to export the helper macro by name. +```ion +$ion_shared_module::$ion_1_1::( + "org.example.Foo" 1 + (module util (macro_table (macro point2d (x y) { x:(%x), y:(%y) }))) + (macro_table + (export util::0) + (macro y_axis_point (y) (.util::point2d 0 (%y))) + (macro poylgon (util::point2d::points+) [(%points)])) +) +``` +In this example, the macro `point2d` is declared in an inner module. +It is added to the shared module's macro table _without a name_, and subsequently referenced by name in the definition +of other macros. + +
+ +Inner modules can also be used for grouping macros into namespaces (only visible within the outer module), and to declare +helper macros that are not added to the macro table of the outer module. +```ion +$ion_shared_module::$ion_1_1::( + "org.example.Foo" 1 + (module cartesian (macro_table (macro point2d (x y) { x:(%x), y:(%y) }) + (macro polygon (point2d::points+) [(%points)]) )) + + (module polar (macro_table (macro point2d (r phi) { r:(%r), phi:(%phi) }) + (macro polygon (point2d::points+) [(%points)]) )) + (macro_table + (export cartesian::polygon cartesian_poylgon) + (export polar::polygon polar_poylgon)) +) +``` +In this example, there are two macros named `point2d` and two named `polygon`. +There is no name conflict between them because they are declared in separate namespaces. +Both `polygon` macros are added to the shared module's macro table, each one given an alias in order to resolve the name conflict. +Neither one of the `point2d` macros needs to be added to the shared module's macro table because they can be referenced +in the definitions of both `polygon` macros without needing to be added to the shared module's macro table. + +
+ +When grouping macros in inner modules, there are more than just organizational benefits. +By defining helper macros in an inner module, the order in which the macros are added to the macro table of the outer module does not have to be the same as the order in which the macros are declared: +```ion +$ion_shared_module::$ion_1_1::( + "org.example.Foo" 1 + // point2d must be declared before polygon... + (module util (macro_table (macro point2d (x y) { x:(%x), y:(%y) }))) + (macro_table + // ...because it is used in the definition of polygon + (macro poylgon (util::point2d::points+) [(%points)]) + // But it can be added to the macro table after polygon + util) +) +``` + +
+ +Inner modules can also be used for organization of symbols. +```ion +$ion_encoding::( + (module diary (symbol_table [cheese, yogurt, milk])) + (module grains (symbol_table [cereal, bread, rice])) + (module vegetables (symbol_table [carrots, celery, peas])) + (module meat (symbol_table [chicken, mutton, beef])) + + (symbol_table dairy + grains + vegetables + meat) +) +``` \ No newline at end of file diff --git a/_books/ion-1-1/src/modules/shared_modules.md b/_books/ion-1-1/src/modules/shared_modules.md new file mode 100644 index 00000000..b9cfb9fe --- /dev/null +++ b/_books/ion-1-1/src/modules/shared_modules.md @@ -0,0 +1,44 @@ +# Shared Modules + +Shared modules exist independently of the documents that use them. +They are identified by a _catalog key_ consisting of a string name and an integer version. + +The self-declared catalog-names of shared modules are generally long, since they must be more-or-less globally unique. +When imported by another module, they are given local symbolic names by import declarations. + +They have a spec version that is explicit via annotation, and a content version derived from the catalog version. +The spec version of a shared module must be declared explicitly using an annotation of the form `$ion_1_N`. +This allows the module to be serialized using any version of Ion, and its meaning will not change. + +```ion +$ion_shared_module:: +$ion_1_1::("com.example.symtab" 3 + (symbol_table ...) + (macro_table ...) ) +``` + +### Example + +An Ion 1.1 shared module. +```ion +$ion_shared_module:: +$ion_1_1::("org.example.geometry" 2 + (symbol_table ["x", "y", "square", "circle"]) + (macro_table (macro point2d (x y) { x:(%x), y:(%y) }) + (macro polygon (point2d::points+) [(%points)]) ) +) +``` + +The system module provides a convenient macro ([`use`](../macros/system_macros.md#use)) to append a shared module to the current encoding module. +```ion +$ion_1_1 +(:use "org.example.geometry" 2) +(:polygon (:: (1 4) (1 8) (3 6))) +``` + + + +### Compatibility with Ion 1.0 + +Ion 1.0 shared symbol tables are treated as Ion 1.1 shared modules that have an empty macro table. + diff --git a/_books/ion-1-1/src/modules/system_module.md b/_books/ion-1-1/src/modules/system_module.md index e3091ccb..08191f64 100644 --- a/_books/ion-1-1/src/modules/system_module.md +++ b/_books/ion-1-1/src/modules/system_module.md @@ -1,4 +1,4 @@ -## The System Module +# The System Module The symbols and macros of the system module `$ion` are available everywhere within an Ion document, with the version of that module being determined by the spec-version of each segment. From bf4d5919e64656559e9e27e11cde193af8578951 Mon Sep 17 00:00:00 2001 From: Matthew Pope <81593196+popematt@users.noreply.github.com> Date: Thu, 17 Oct 2024 10:41:38 -0700 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Zack Slayton --- _books/ion-1-1/src/modules.md | 6 +++--- _books/ion-1-1/src/modules/defining_modules.md | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/_books/ion-1-1/src/modules.md b/_books/ion-1-1/src/modules.md index f41cc502..511198c1 100644 --- a/_books/ion-1-1/src/modules.md +++ b/_books/ion-1-1/src/modules.md @@ -19,7 +19,7 @@ The interface to a module consists of: * its _exported symbols_, an array of strings denoting symbol content * its _exported macros_, an array of `` pairs, where all names are unique identifiers (or null). -The spec version is external to the macro body and the precise way it is determined depends on the type of module being defined. This is explained in further detail in [Module Versioning](#module-versioning). +The spec version is external to the module body and the precise way it is determined depends on the type of module being defined. This is explained in further detail in [Module Versioning](#module-versioning). The exported symbol array is denoted by the `symbol_table` clause of a module definition, and by the `symbols` field of a shared symbol table. @@ -30,7 +30,7 @@ allocated to macros or macro bindings in the order they are declared. The exported symbols and exported macros are defined in the [module body](body.md). -## Types of Modules +## Types of modules There are multiple types of modules. All modules share the same interface, but vary in their implementation in order to support a variety of different use cases. @@ -105,5 +105,5 @@ identifier-start ::= letter | '$_' | '$$' -identifier-char ::= letter | number | '$' | '_' +identifier-char ::= letter | digit | '$' | '_' ``` diff --git a/_books/ion-1-1/src/modules/defining_modules.md b/_books/ion-1-1/src/modules/defining_modules.md index 0caa4b6e..6c246be3 100644 --- a/_books/ion-1-1/src/modules/defining_modules.md +++ b/_books/ion-1-1/src/modules/defining_modules.md @@ -50,7 +50,7 @@ macro-addr ::= unannotated-uint Macro references are resolved to a specific macro as follows: -* An unqualified _macro-name_ is looked up within the exported macros, and if not found, then the system module. +* An unqualified _macro-name_ is looked up within the exported macros, and if not found, then the active encoding module's macro table. If it maps to a macro, that’s the resolution of the reference. Otherwise, an error is signaled due to an unbound reference. * An anonymous local reference (`__address__`) is resolved by index in the exported macro array. @@ -61,17 +61,17 @@ Macro references are resolved to a specific macro as follows: > [!WARNING] > An unqualified macro name can change meaning in the middle of a module if you choose to shadow the -> name of a system macro. The system macros are imported and used with that meaning, then a declaration -> shadows that name and gives it a new meaning. +> name of a system macro. To unambiguously refer to the system module, use the qualified reference syntax: `__$ion__::__system-macro-name__`. ### `import` ```bnf -import ::= '(import ' module-name catalog-key ')' +import ::= '(import ' module-binding catalog-key ')' +catalog-key ::= module-name module-version? ``` -An import binds a lexically scoped module name to a shared symbol table that is identified by a catalog key—that is a `(name, version)` pair. The `version` of the catalog key is optional—when omitted, the version is implicitly 1. +An import binds a lexically scoped module name to a shared module that is identified by a catalog key—a `(name, version)` pair. The `version` of the catalog key is optional—when omitted, the version is implicitly 1. In Ion 1.0, imports may be substituted with a different version if an exact match is not found. In Ion 1.1, however, all imports require an exact match to be found in the reader's catalog; @@ -102,12 +102,12 @@ symbol-table ::= '(symbol_table' symbol-table-entry* ')' symbol-table-entry ::= module-name | symbol-list -symbol-list ::= '[' (symbol | string)* ']' +symbol-list ::= '[' ((symbol | string)',')* ']' ``` The `symbol_table` clause assembles a list of text values for the module to export. It takes any number of arguments, each of which may be the name of visible module or a list of symbol-texts. -The symbol table is a list of symbol-texts by concatenating the symbol tables of named modules and lists of symbol/string values. +The symbol table is a list of symbol-texts by concatenating the symbol tables of named modules and lists of symbol/string values. Where a module name occurs, its symbol table is appended. (The module name must refer to another module that is visible to the current module.) @@ -116,7 +116,7 @@ Unlike Ion 1.0, no _symbol-maxid_ is needed because Ion 1.1 always required exac Where a list occurs, it must contain only non-null, unannotated strings and symbols. The text of these strings and/or symbols are appended to the symbol table. Upon encountering any non-text value, null value, or annotated value in the list, the implementation shall signal an error. -To create an intentional gap in the symbol table, one may use `$0`. +To add a symbol with unknown text to the symbol table, one may use `$0`. All modules have a symbol table, so when a module has no `symbol_table` clause, the module has an empty symbol table. @@ -143,7 +143,7 @@ If module `foo`'s symbol table were `[d, e, f]`, then the symbol table defined b ```ion ["a", "b", "c", "d", "e", "f", "g", "h", "i"] ``` - +This is an Ion 1.0 symbol table that imports two shared symbol tables and then declares some symbols of its own. ```ion $ion_1_0 From 19a348e693ebd18cc3997a14f823c418b29a070f Mon Sep 17 00:00:00 2001 From: Matthew Pope Date: Thu, 17 Oct 2024 16:13:40 -0700 Subject: [PATCH 3/5] Adds more suggested changes --- _books/ion-1-1/src/modules.md | 6 +- .../ion-1-1/src/modules/defining_modules.md | 58 ++++++++++++++----- _books/ion-1-1/src/modules/encoding_module.md | 12 +++- _books/ion-1-1/src/modules/grammar.md | 18 +++--- _books/ion-1-1/src/modules/inner_modules.md | 4 +- _books/ion-1-1/src/modules/shared_modules.md | 4 +- _books/ion-1-1/src/modules/system_module.md | 4 +- 7 files changed, 73 insertions(+), 33 deletions(-) diff --git a/_books/ion-1-1/src/modules.md b/_books/ion-1-1/src/modules.md index 511198c1..b5537903 100644 --- a/_books/ion-1-1/src/modules.md +++ b/_books/ion-1-1/src/modules.md @@ -1,4 +1,4 @@ -# Ion 1.1 Modules +# Ion 1.1 modules In Ion 1.0, each stream has a [symbol table](https://amazon-ion.github.io/ion-docs/docs/symbols.html#processing-of-symbol-tables). The symbol table stores text values that can be referred to by their integer index in the table, providing a much more compact representation than repeating the full UTF-8 text bytes each time the value is used. Symbol tables do not store any other information used by the reader or writer. @@ -11,7 +11,7 @@ Ion 1.1 also introduces the concept of a _module_, an organizational unit that h In Ion 1.1, each stream has an [encoding module](modules/encoding_module.md)—the active `(symbol table, macro table)` pair that is being used to encode the stream. -## Module Interface +## Module interface The interface to a module consists of: @@ -43,7 +43,7 @@ All modules share the same interface, but vary in their implementation in order | [Shared Module](modules/shared_modules.md) | Defining symbols and macros outside of the data stream | -## Module Versioning +## Module versioning Every module definition has a _spec version_ that determines the syntax and semantics of the module body. A module’s spec version is expressed in terms of a specific Ion version; the meaning of the module is as defined by that version of the Ion specification. diff --git a/_books/ion-1-1/src/modules/defining_modules.md b/_books/ion-1-1/src/modules/defining_modules.md index 6c246be3..59f63629 100644 --- a/_books/ion-1-1/src/modules/defining_modules.md +++ b/_books/ion-1-1/src/modules/defining_modules.md @@ -1,4 +1,4 @@ -# Defining Modules +# Defining modules A module is defined by four kinds of subclauses which, if present, always appear in the same order. @@ -8,18 +8,20 @@ A module is defined by four kinds of subclauses which, if present, always appear 4. `macro_table` - an exported list of macro definitions -### Internal Environment +### Internal environment The body of a module tracks an internal environment by which macro references are resolved. This environment is constructed incrementally by each clause in the definition and consists of: * the _visible modules_, a map from identifier to module +* the _exported symbols_, an array containing symbol texts * the _exported macros_, an array containing name/macro pairs Before any clauses of the module definition are examined, the initial environment is as follows: -* The visible modules map `$ion` to the system module for the appropriate spec version. - Inside an encoding directive, the visible modules also maps `$ion_encoding` to the current encoding module. +* The visible modules map binds `$ion` to the system module for the appropriate spec version. + Inside an encoding directive, the visible modules map also binds `$ion_encoding` to the active encoding module + (the encoding module that was active when the encoding directive was encountered). For an inner module, it also includes the modules previously made available by the enclosing module (via `import` or `module`). * The macro table and symbol table are empty. @@ -31,6 +33,7 @@ Each clause affects the environment as follows: An error must be signaled if the name already appears in the visible modules. * A `module` declaration defines a new module and assigns it a name in the visible modules. An error must be signaled if the name already appears in the visible modules. +* A `symbol_table` declaration defines the exported symbols. * A `macro_table` declaration defines the exported macros. ### Resolving Macro References @@ -50,25 +53,32 @@ macro-addr ::= unannotated-uint Macro references are resolved to a specific macro as follows: -* An unqualified _macro-name_ is looked up within the exported macros, and if not found, then the active encoding module's macro table. - If it maps to a macro, that’s the resolution of the reference. +* An unqualified _macro-name_ is looked up within the exported macros, and if not found, then the + active encoding module's macro table. If it maps to a macro, that’s the resolution of the reference. Otherwise, an error is signaled due to an unbound reference. -* An anonymous local reference (`__address__`) is resolved by index in the exported macro array. +* An anonymous local reference (_macro-addr_) is resolved by index in the exported macro array. If the address exceeds the array boundary, an error is signaled due to an invalid reference. -* A qualified reference (`__module__::__name-or-address__`) resolves solely against the referenced module. +* A qualified reference (_qualified-ref_) resolves solely against the referenced module. If the module name does not exist in the visible modules, an error is signaled due to an unbound reference. Otherwise, the name or address is resolved within that module’s exported macro array. > [!WARNING] > An unqualified macro name can change meaning in the middle of a module if you choose to shadow the -> name of a system macro. To unambiguously refer to the system module, use the qualified reference syntax: `__$ion__::__system-macro-name__`. +> name of a system macro. To unambiguously refer to the system module, use the qualified reference syntax: `$ion::`. ### `import` ```bnf -import ::= '(import ' module-binding catalog-key ')' -catalog-key ::= module-name module-version? +import ::= '(import ' module-name catalog-key ')' + +module-name ::= unannotated-identifier-symbol + +catalog-key ::= catalog-name catalog-version? + +catalog-name ::= string + +catalog-version ::= int // positive, unannotated ``` An import binds a lexically scoped module name to a shared module that is identified by a catalog key—a `(name, version)` pair. The `version` of the catalog key is optional—when omitted, the version is implicitly 1. @@ -102,7 +112,9 @@ symbol-table ::= '(symbol_table' symbol-table-entry* ')' symbol-table-entry ::= module-name | symbol-list -symbol-list ::= '[' ((symbol | string)',')* ']' +symbol-list ::= '[' ( symbol-text ',' )* ']' + +symbol-text ::= symbol | string ``` The `symbol_table` clause assembles a list of text values for the module to export. @@ -113,12 +125,31 @@ Where a module name occurs, its symbol table is appended. (The module name must refer to another module that is visible to the current module.) Unlike Ion 1.0, no _symbol-maxid_ is needed because Ion 1.1 always required exact matches for imported modules. +> [!TIP] +> In an encoding directive, the active encoding module `$ion_encoding` can be added to the symbol table in order to +> retain the symbols from the active encoding module. +> `$ion_encoding` can occur anywhere in the `symbol_table` clause, so in Ion 1.1 it is possible to append and prepend to +> the symbol table. + Where a list occurs, it must contain only non-null, unannotated strings and symbols. The text of these strings and/or symbols are appended to the symbol table. Upon encountering any non-text value, null value, or annotated value in the list, the implementation shall signal an error. To add a symbol with unknown text to the symbol table, one may use `$0`. -All modules have a symbol table, so when a module has no `symbol_table` clause, the module has an empty symbol table. +All modules have a symbol table, so when a module has no `symbol_table` clause, the module has an empty symbol table. + +#### Symbol zero `$0` + + +Symbol zero (i.e. `$0`) is a special symbol that is not assigned text by any symbol table, even the system symbol table. +Symbol zero always has unknown text, and can be useful in synthesizing symbol identifiers where the text image of the symbol is not known in a particular operating context. + +All symbol tables (even an empty symbol table) can be thought of as implicitly containing `$0`. +However, `$0` precedes all symbol tables rather than belonging to any symbol table. +When adding the exported symbols from one module to the symbol table of another, the preceding `$0` is not copied into the destination symbol table (because it is not part of the source symbol table). + +It is important to note that `$0` is only semantically equivalent to itself and to locally-declared SIDs with unknown text. +It is not semantically equivalent to SIDs with unknown text from shared symbol tables, so replacing such SIDs with `$0` is a destructive operation to the semantics of the data. #### Processing @@ -228,6 +259,7 @@ When the macro declaration uses a name, an error must be signaled if it already An `export` clause declares a name for an existing macro and appends the macro to the macro table. * If the reference to the existing macro is followed by a name, the existing macro is appended to the exported macro array with the latter name instead of the original name, if any. + In this way, an anonymous macro can be given a name. An error must be signaled if that name already appears in the exported macro array. * If the reference to the existing macro is followed by `null`, the macro is appended to the exported macro array without a name, regardless of whether the macro has a name. diff --git a/_books/ion-1-1/src/modules/encoding_module.md b/_books/ion-1-1/src/modules/encoding_module.md index f17b1cd5..3353d8f3 100644 --- a/_books/ion-1-1/src/modules/encoding_module.md +++ b/_books/ion-1-1/src/modules/encoding_module.md @@ -1,4 +1,4 @@ -# The Encoding module +# The encoding module The _encoding module_ is the module that is currently being used to encode the data stream. When the stream begins, the encoding module is the [system module](system_module.md). @@ -8,7 +8,7 @@ An encoding directive is an s-expression annotated with `$ion_encoding`; its nes When the reader advances beyond an encoding directive, the module it defined becomes the new encoding module. -In the context of an encoding directive, the current encoding module is named `$ion_encoding`. +In the context of an encoding directive, the active encoding module is named `$ion_encoding`. The encoding directive may preserve symbols or macros that were defined in the previous encoding directive by referencing `$ion_encoding`. The `$ion_encoding` module may only be imported to an encoding directive, and it is done so automatically and implicitly. @@ -30,7 +30,7 @@ $ion_encoding::( ) ``` -#### Adding symbols to the current encoding module +#### Adding symbols to the encoding module The implicitly imported `$ion_encoding` is used to append to the current symbol and macro tables. ```ion @@ -49,6 +49,9 @@ $ion_encoding::( // ... $ion_encoding::( + // The first argument of the symbol_table clause is the module name '$ion_encoding', + // which adds the symbols from the active encoding module to the new encoding module. + // The '$ion_encoding' argument in the macro_table clause behaves similarly. (symbol_table $ion_encoding [ "d", // $4 @@ -67,3 +70,6 @@ $ion_encoding::( $ion_encoding::() ``` The absence of the `symbol_table` and `macro_table` clauses is interpreted as empty symbol and macro tables. + +Note that this is different from the behaviour of an IVM. +When an IVM is encountered, the encoding module is set to the system module. diff --git a/_books/ion-1-1/src/modules/grammar.md b/_books/ion-1-1/src/modules/grammar.md index bdbbc6ee..2bc4af47 100644 --- a/_books/ion-1-1/src/modules/grammar.md +++ b/_books/ion-1-1/src/modules/grammar.md @@ -1,24 +1,24 @@ -# Module Grammar +# Module grammar ```bnf encoding-directive ::= '$ion_encoding::(' module-body ')' - + shared-module ::= '$ion_shared_module::' ion-version-marker '::(' catalog-key module-body ')' ion-version-marker ::= '$ion_1_0' | '$ion_1_1' -module-body ::= import* inline-module* symbol-table? macro-table? +module-body ::= import* inner-module* symbol-table? macro-table? import ::= '(import ' module-name catalog-key ')' catalog-key ::= catalog-name catalog-version? -catalog-version ::= int // positive, unannotated - catalog-name ::= string +catalog-version ::= int // positive, unannotated + inner-module ::= '(module' module-name import* symbol-table? macro-table? ')' - + module-name ::= unannotated-identifier-symbol @@ -29,7 +29,9 @@ symbol-table ::= '(symbol_table' symbol-table-entry* ')' symbol-table-entry ::= module-name | symbol-list -symbol-list ::= '[' (symbol | string)* ']' +symbol-list ::= '[' ( symbol-text ',' )* ']' + +symbol-text ::= symbol | string // Macro Tables @@ -40,7 +42,7 @@ macro-table-entry ::= macro-definition | macro-export | module-name -macro-definition ::= '(macro' macro-name-declaration signature template-expression ')' +macro-definition ::= '(macro' macro-name-declaration signature tdl-expression ')' macro-export ::= '(export' qualified-macro-ref macro-name-declaration? ')' diff --git a/_books/ion-1-1/src/modules/inner_modules.md b/_books/ion-1-1/src/modules/inner_modules.md index d0bf1351..5b040760 100644 --- a/_books/ion-1-1/src/modules/inner_modules.md +++ b/_books/ion-1-1/src/modules/inner_modules.md @@ -1,4 +1,4 @@ -# Inner Modules +# Inner modules Inner modules are defined within another module, and can be referenced only within the enclosing module. Their scope is lexical; they can be referenced immediately following their definition, up until the end of the containing module. @@ -71,7 +71,7 @@ $ion_shared_module::$ion_1_1::( Inner modules can also be used for organization of symbols. ```ion $ion_encoding::( - (module diary (symbol_table [cheese, yogurt, milk])) + (module dairy (symbol_table [cheese, yogurt, milk])) (module grains (symbol_table [cereal, bread, rice])) (module vegetables (symbol_table [carrots, celery, peas])) (module meat (symbol_table [chicken, mutton, beef])) diff --git a/_books/ion-1-1/src/modules/shared_modules.md b/_books/ion-1-1/src/modules/shared_modules.md index b9cfb9fe..87a11a10 100644 --- a/_books/ion-1-1/src/modules/shared_modules.md +++ b/_books/ion-1-1/src/modules/shared_modules.md @@ -1,4 +1,4 @@ -# Shared Modules +# Shared modules Shared modules exist independently of the documents that use them. They are identified by a _catalog key_ consisting of a string name and an integer version. @@ -29,7 +29,7 @@ $ion_1_1::("org.example.geometry" 2 ) ``` -The system module provides a convenient macro ([`use`](../macros/system_macros.md#use)) to append a shared module to the current encoding module. +The system module provides a convenient macro ([`use`](../macros/system_macros.md#use)) to append a shared module to the encoding module. ```ion $ion_1_1 (:use "org.example.geometry" 2) diff --git a/_books/ion-1-1/src/modules/system_module.md b/_books/ion-1-1/src/modules/system_module.md index 08191f64..d7711e6e 100644 --- a/_books/ion-1-1/src/modules/system_module.md +++ b/_books/ion-1-1/src/modules/system_module.md @@ -1,4 +1,4 @@ -# The System Module +# The system module The symbols and macros of the system module `$ion` are available everywhere within an Ion document, with the version of that module being determined by the spec-version of each segment. @@ -9,7 +9,7 @@ The system macros are more visible, especially to authors of macros. This chapter catalogs the system-provided symbols and macros. The examples below use unqualified names, which works assuming no other macros with the same name are in scope. The unambiguous form `$ion::macro-name` is always available to use in the [template definition language](../macros/defining_macros.md#template-definition-language-tdl). -### Relation to Local Symbol and Macro Tables +### Relation to local symbol and macro tables In Ion 1.0, the system symbol table is always the first import of the local symbol table. However, in Ion 1.1, the system symbol and macro tables have a system address space that is distinct from the local address space. From d35160dd7aeca9cce5d95650414cb36585fb17f3 Mon Sep 17 00:00:00 2001 From: Matthew Pope Date: Thu, 17 Oct 2024 16:15:25 -0700 Subject: [PATCH 4/5] Correction about shadowing in encoding directives --- _books/ion-1-1/src/modules/defining_modules.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_books/ion-1-1/src/modules/defining_modules.md b/_books/ion-1-1/src/modules/defining_modules.md index 59f63629..cfd5ee96 100644 --- a/_books/ion-1-1/src/modules/defining_modules.md +++ b/_books/ion-1-1/src/modules/defining_modules.md @@ -64,7 +64,8 @@ Macro references are resolved to a specific macro as follows: > [!WARNING] > An unqualified macro name can change meaning in the middle of a module if you choose to shadow the -> name of a system macro. To unambiguously refer to the system module, use the qualified reference syntax: `$ion::`. +> name of a macro in active encoding module. To unambiguously refer to the active encoding module, +> use the qualified reference syntax: `$ion_encoding::`. ### `import` From 679d940b822e7bb75a41e315bd112f2130102ea9 Mon Sep 17 00:00:00 2001 From: Matthew Pope Date: Thu, 17 Oct 2024 16:16:17 -0700 Subject: [PATCH 5/5] Add missing word --- _books/ion-1-1/src/modules/defining_modules.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_books/ion-1-1/src/modules/defining_modules.md b/_books/ion-1-1/src/modules/defining_modules.md index cfd5ee96..6904036c 100644 --- a/_books/ion-1-1/src/modules/defining_modules.md +++ b/_books/ion-1-1/src/modules/defining_modules.md @@ -63,8 +63,8 @@ Macro references are resolved to a specific macro as follows: Otherwise, the name or address is resolved within that module’s exported macro array. > [!WARNING] -> An unqualified macro name can change meaning in the middle of a module if you choose to shadow the -> name of a macro in active encoding module. To unambiguously refer to the active encoding module, +> An unqualified macro name can change meaning in the middle of an encoding module if you choose to shadow the +> name of a macro in the active encoding module. To unambiguously refer to the active encoding module, > use the qualified reference syntax: `$ion_encoding::`.