3. Module system¶
- module¶
A value loaded by the module system. A module has a set of functions of a single feature group as its variables. Module can be abbreviated to mod.
- module system¶
A subsystem of the runtime which manages modules.
3.1. Module loading¶
A module can be loaded from the module system by specifying a string
of the module name.
Module loading can be done by require_from
method
of a varref,
or MOD.require
function (see kink/MOD).
Module loading is done as follows:
If the specified module name has already been associated with a module, module loading results in “success” status with the module.
If the specified module name hasn't been associated with a module, the module system tries to find the source of the module. If the source is not found, module loading results in “not found” status.
If the source is found, and the source is a Kink program, the module system tries to compile the program. If compilation fails, module loading results in “compile error” status, with
(Msg, From_loc, To_loc)
, whereMsg
is the error message string,From_loc
is the inclusive starting location of the program error, andTo_loc
is the exclusive starting location of the program error.If the previous step succeeds, the module system tries to initialize a module. If the source is a Kink program, the compiled program is executed. It can result in an exception.
If initialization succeeds, and the specified module name has not yet been associated with a module, the the module name is associated with the initialized module.
Note that, during module initialization,
another module loading can be done.
For example, the source program of module A
might load
another module B
.
Recursive module loading is not permitted.
For example, if initialization of module A
results in module loading
of module A
, it can cause an exception.
3.2. Module naming rule¶
The module name must match the regex pattern:
([a-z_][a-z0-9_]*/)*_*[A-Z][A-Z0-9_]*
.
Examples of valid module names:
MAIN
kink/STR
kink/test/TEST
org/example/_internal/INTERNAL_MOD
com/example/_PRIVATE_MOD
3.3. Builtin modules¶
The runtime provides builtin modules. You can see the specification of public builtin modules at Builtin library API. There can also be private builtin modules which are not parts of the public API.
Builtin modules have higher precedence than module source program files on the file system. It means, when a builtin module is found with a specified module name, no search is performed on the module paths.
3.4. Module source program¶
A module can be loaded from a source program file on the file system.
The module source program is searched on module paths specified by
add_path
function of kink/MOD module,
or --path
option of the commandline
(see -p {Mod_path} / --path {Mod_path}).
3.4.1. File path¶
A module source program can be located at the file path which concatenates
a module path, the path separator, the module name, and the suffix .kn
.
For example, assume org/example/TARAI
is the module name,
and the module paths are /home/you/kinkmod
and /usr/share/kinkmod
.
In that case, the source program file can be located one of the following:
/home/you/kinkmod/org/example/TARAI.kn
/usr/share/kinkmod/org/example/TARAI.kn
3.4.2. Charset¶
Module source programs must be encoded with UTF-8 charset.
3.4.3. Initialization¶
On initialization, the source program is compiled and executed with a binding. After the execution succeeds, the binding is associated as the module with the module name.
Therefore, top level variables of the program can be accessed as variables of the module.
3.4.4. Example¶
Assume you have a module source program file of org/example/rat/RAT
module,
at /home/me/mymods/org/example/rat/RAT.kn as follows.
:new <- {(:Numer :Denom)
new_val(
... Rat_trait
'Numer' Numer
'Denom' Denom
)
}
:Rat_trait <- [
'numer' {[:R]
R.Numer
}
'denom' {[:R]
R.Denom
}
'repr' {[:R]
'{}/{}'.format(R.numer R.denom)
}
]
Assume you have a program file client.kn at the current directory. client.kn uses RAT module.
:RAT.require_from('org/example/rat/')
:Rat <- RAT.new(1 3)
stdout.print_line('rat: {}'.format(Rat.repr))
You can execute client.kn as follows.
$ kink --path /home/me/mymods client.kn
rat: 1/3
Since RAT
module is a binding, it has preloaded functions such as
if
and nada
.
It also contains a non-public variable Rat_trait
.
Access to those variables which are not parts of the public API of the module
should be restricted to unit software testing.
:RAT.require_from('org/example/rat/')
stdout.print_line(RAT.nada.repr) # => nada
stdout.print_line(RAT.Rat_trait.repr) # => ["numer" (fun ,,,
3.5. Launchable module¶
If a module have main
function, it can be executed by the commandline.
See kink and kinkw commands for details.