13 Modules
13.1 Using a module
Syntax
import = "use" NAME [ "as" NAME ] ;(1) One source is one module. The name the host gave when loading the source is the module’s name (pnx uses the file name without .pnx). Standard modules and host modules (13.3) are modules too.
(2) use MODULE opens that module in this source; from then on its parts are written as the path MODULE.NAME. use MODULE as ALIAS makes the same module be written ALIAS.NAME. Only core words and what this source declares are written as bare names, and the words of the modules a search order names (13.5).
(3) A module that is used shall exist already: a standard module, a module the host registered, or a source loaded earlier. When pnx meets use NAME it first loads NAME.pnx from beside the program file.
13-use.pnx
use io
use str
use geometry
200 50 geometry.area str.to_str io.println
geometry.unit str.to_str io.println
array corners point 2 rem an exported record is used by its name
3 0 corners idx to point.x
0 corners idx point.x str.to_str io.println
Output
$ pnx 13-use.pnx
100
10
3
13-use-as.pnx
use io
use str
use geometry as g
200 50 g.area str.to_str io.println
Output
$ pnx 13-use-as.pnx
100
Constraints
(4) Using a module that does not exist is refused.
13-unknown-module.pnx
use geometrie
Refused
$ pnx 13-unknown-module.pnx
13-unknown-module.pnx:1:5: no module of this name is registered or loaded
(5) A word of a module written as a bare name is refused, unless a search order names that module (13.5); so is a path into a module that was not opened.
13-bare-name.pnx
use geometry
200 50 area drop
Refused
$ pnx 13-bare-name.pnx
13-bare-name.pnx:2:8: this name is not declared before this place
13-no-use.pnx
use io
5 str.to_str io.println
Refused
$ pnx 13-no-use.pnx
13-no-use.pnx:2:3: this path names neither a module in use nor a record
13.2 Exports
(1) Another source can use only what was declared or defined with export. Words, constants and globals are written MODULE.NAME (an exported global is stored with set MODULE.NAME); exported records and types and the row types of tables are written by their name alone.
(2) The module geometry below is the one the examples of 13.1 use. square is not exported.
geometry.pnx
rem A module: only what is marked export is seen by a source that uses it.
export const unit 10
export record point
x int
y int
end
word square (n int gives int) n n mul end
export word area (w int, h int gives int) w h mul unit square div end
Constraints
(3) Using what is not exported is refused.
13-not-exported.pnx
use geometry
4 geometry.square drop
Refused
$ pnx 13-not-exported.pnx
13-not-exported.pnx:2:3: the module exports nothing of this name
13.3 Standard modules and host modules
(1) The standard modules come with the processor and are part of the language: str fmt hash encode bytes ptn rex json csv (clause 16). They are seen only after use.
(2) A host module is a set of words the host registered. A module the host did not register does not exist. Everything a script can do outside itself (files, clocks, the environment) is a word the host registered. pnx registers the standard host modules io file clock random env (clause 17).
(3) err is a set of constants written as paths without use (11.1).
13.4 Data load
Syntax
data-source = { data-item } ;
data-item = [ "export" ] ( [ "bound" ] bindable | "const" NAME literal
| "list" NAME type size | "queue" NAME type size | "pool" NAME NAME size
| "record" NAME { field | "big_endian" } "end" | "type" NAME base
| "index" NAME NAME PATH )
| "forward" ( "array" | "list" | "pool" ) NAME
| row-item | assign-item
| data-value [ data-value ] "set" NAME (* a global, or a cell *)
| data-value NAME "to" PATH ; (* a field of a named row *)
data-value = literal | NAME ; (* NAME: a const or a row name *)(1) A source the host reads by data load accepts declarations and values only. Word definitions, calls, use, extern, test, control, blocks and cat are refused. Such a source therefore cannot run any code. It is for reading settings, data and other text that is not trusted.
(2) A value is stored with value set NAME, a cell with value index set NAME ("10.0.0.1" 0 set allow) and a field of a named row with value ROW to RECORD.FIELD, as in code (8.8, 9.4). Everything a data source declares counts as exported.
Diagnostics
| Condition | Message |
|---|---|
| A module that does not exist | no module of this name is registered or loaded |
| A path into a module not opened, or no record | this path names neither a module in use nor a record |
| A name not exported | the module exports nothing of this name |
A definition or use in a data load | a data source defines no words and uses no modules |
| A call in a data load | a data source calls no words; only literals, const names and stores |
13.5 The search order
Syntax
search = "search" ( "(" [ NAME { "," NAME } ] ")" | "none" ) ;(1) search (io, str) gives the search order: the modules in which a bare name is looked for. Each module named is opened as by use (13.1 (2), (3)); pnx loads a file module beside the program first, as for use. search () and search none empty the order. Without a search order, nothing is looked for in a module.
(2) A bare name in code is looked for in this order, and the first that has it is taken: the locals and parameters; what this source (or session) declares; the core words; then the modules of the search order, left to right. So a name of the source and a core word keep their meaning whatever the order holds, and a module added to it cannot change code that compiled before. A word of a module named like a core word (str.len beside len) is written with its path. A path is read as before.
13-search.pnx
use io
use str
search (io, str)
"pinax" upper println
word shout (s str) cat (s upper, "!") println end
"hello" shout
"abc" str.len 3 eq if "three bytes" println end
Output
$ pnx 13-search.pnx
PINAX
HELLO!
three bytes
13-search-core.pnx
search (str)
word size (s str gives int) s len end
Refused
$ pnx 13-search-core.pnx
13-search-core.pnx:2:31: this word takes the name of an array, list, queue or buffer; of a str it is str.len
(3) A search order stands at the top level of a source or of a session line, as often as needed. Each one replaces the order from there to the end of the source; a session keeps it for the lines after, until the next one. A word takes what its names found when it was compiled.
(4) A name reached through the search order does not count for the rule against hiding names (9.5): a local may have the name of a word of a module in the order, and inside that word the local is meant.
Constraints
(5) A search order inside a definition or a block, one that names a module twice or more than 16 modules, and one that names a module that does not exist are refused.
Diagnostics
| Condition | Message |
|---|---|
search inside a definition | search stands at the top level, outside definitions and blocks |
| No parentheses | search is followed by modules in parentheses: search (io, str) |
| A module named twice | this module is named twice in the search order |
| More than 16 | a search order names at most 16 modules |