ref: c91045be5ed9f9019d92ce23a3955313e691f263
parent: 50bc0b3fb51052b59bf8873dc7eaf68257ef91d1
author: seh <henesy.dev@gmail.com>
date: Mon Mar 18 00:21:02 EDT 2019
add Modules example
--- a/Modules/README.md
+++ b/Modules/README.md
@@ -2,6 +2,8 @@
Limbo supports compartmentalization of functionality through the dynamic loading and unloading of names and definitions through modules.
+A particular module may include a `.m` file module definition associated with a given implementation of said module contained within `.b` files.
+
Disclaimer: At the time of writing I am not exceptionally well-versed with modules in Limbo. All assertions should be taken with a grain of salt.
## Source
@@ -8,41 +10,48 @@
### persons.m:1,11
+The `Persons` module exposes three functions and an ADT.
-
Function definitions:
-- init() persons.b:7,9
-- mkperson() persons.b:11,13
-- getpop() persons.b:15,18
+- init() -- persons.b:7,9
+- mkperson() -- persons.b:11,13
+- getpop() -- persons.b:15,18
Note: In a way, a module definition acts as an interface which dictates which functions, variables, and types are accessible from outside the module's implementation proper.
### towns.m:1,14
+The `Towns` module exposes two functions, a variable, and an ADT.
+Note that the module file includes `persons.m` to allow it to utilize the `Persons` definition, allowing a handle to be attached to the module `Persons` within the module `Towns` as per the `Towns->init()` definition.
Function definitions:
-- init() towns.b:5,7
-- mktown() towns.b:9,11
+- init() -- towns.b:5,7
+- mktown() -- towns.b:9,11
### modules.b:25,29
+This section loads the auxiliary modules used within this example and calls their respective initialization functions.
+Note that no module should be considered usable or safe to reference before calling their respective initialization function, if any.
### modules.b:31,39
+This section demonstrates calling the `getpop()` function within the `Persons` module using the currently loaded handle to the `Persons` module, `persons`. An instance of `ref Person` is created and its fields filled manually.
+Note that across these two calls, the `population` within `modules->persons` increments, however, the `population` within `towns->persons` does not increment. This is because the two instances of the `Persons` module are separate and loaded separately. These two modules share no resources other than a common origin within their `.dis` bytecode files.
### modules.b:41,45
+This section features a call to `mktown()` from within the `Towns` module. The contents of the respective `ref Town` are filled manually.
-
Note: The type `Person` is imported at modules.b:13.
## Demo
+ ; mk
; modules
0
0
@@ -62,3 +71,4 @@
- What happens if you remove the `import` statements for `Person` and `Town` in various `.b` files?
- What happens if you include `persons.m` in `modules.b`?
- What happens if you include `persons.m` in `modules.b` and remove the include for `persons.m` in `towns.m`?
+- Can you load the `Util` module contained within `util.b`?
--- a/Modules/mkfile
+++ b/Modules/mkfile
@@ -6,5 +6,6 @@
modules.dis\
persons.dis\
towns.dis\
+ util.dis\
</mkfiles/mkdis
--- /dev/null
+++ b/Modules/util.b
@@ -1,0 +1,9 @@
+implement Util;
+
+Util: module {
+ glenda: fn(): string;
+};
+
+glenda(): string {
+ return " (\\(\\\n �\". ..\n ( . .)\n | � �\n � ;\n c?\".UJ\"";
+}
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@
- [Functions](./Functions)
- [Function References](./Function-Refs)
- [Abstract Data Types](./ADTs)
+- [Modules](./Modules)
- [Generics, Picks, and Interfaces (kind of)](./Generics)
- [Exceptions](./Exceptions)