ref: be5690bf05707107bc6f02005af82399b0c1c655
parent: 1dbebd5fe59f27106a4dfa553c9ee8b893d6008e
author: seh <henesy.dev@gmail.com>
date: Sun Mar 17 23:44:58 EDT 2019
add work on modules example
--- /dev/null
+++ b/Modules/README.md
@@ -1,0 +1,33 @@
+# Modules
+
+Limbo supports compartmentalization of functionality through the dynamic loading and unloading of names and definitions through modules.
+
+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
+
+###
+
+
+
+## Demo
+
+ ; modules
+ 0
+ 0
+ 1
+ 0
+ Name: Mars
+ Size: 2
+ Members:
+ → Spike
+ → Ed
+ ;
+
+## Exercises
+
+- Can you access `persons->population` from `modules`?
+- Could you make a global variable by placing said variable in its respective module definition?
+- 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`?
--- /dev/null
+++ b/Modules/mkfile
@@ -1,0 +1,10 @@
+</mkconfig
+
+DISBIN = ./
+
+TARG=\
+ modules.dis\
+ persons.dis\
+ towns.dis\
+
+</mkfiles/mkdis
--- /dev/null
+++ b/Modules/modules.b
@@ -1,0 +1,48 @@
+implement Modules;
+
+include "sys.m";
+include "draw.m";
+
+# Note the lack of `include "persons.m";`
+include "towns.m";
+
+sys: Sys;
+print: import sys;
+
+persons: Persons;
+Person: import persons;
+
+towns: Towns;
+Town: import towns;
+
+Modules: module {
+ init: fn(nil: ref Draw->Context, nil: list of string);
+};
+
+init(nil: ref Draw->Context, nil: list of string) {
+ sys = load Sys Sys->PATH;
+
+ persons = load Persons "./persons.dis";
+ towns = load Towns "./towns.dis";
+
+ persons->init();
+ towns->init();
+
+ print("%d\n", persons->getpop());
+ print("%d\n", towns->persons->getpop());
+
+ p := persons->mkperson();
+ p.name = "Spike";
+ p.age = 27;
+
+ print("%d\n", persons->getpop());
+ print("%d\n", towns->persons->getpop());
+
+ t := towns->mktown();
+ t.pop = array[] of {p, ref Person(13, "Ed")};
+ t.name = "Mars";
+
+ print("%s\n", t.stringify());
+
+ exit;
+}
--- /dev/null
+++ b/Modules/persons.b
@@ -1,0 +1,22 @@
+implement Persons;
+
+include "persons.m";
+
+population: int;
+
+init() {
+ population = 0;
+}
+
+getpop(): int {
+ return population;
+}
+
+mkperson(): ref Person {
+ population++;
+ return ref Person;
+}
+
+Person.stringify(p: self ref Person): string {
+ return p.name;
+}
--- /dev/null
+++ b/Modules/persons.m
@@ -1,0 +1,11 @@
+Persons: module {
+ init: fn();
+ mkperson: fn(): ref Person;
+ getpop: fn(): int;
+
+ Person: adt {
+ age: int;
+ name: string;
+ stringify: fn(p: self ref Person): string;
+ };
+};
--- /dev/null
+++ b/Modules/towns.b
@@ -1,0 +1,22 @@
+implement Towns;
+
+include "towns.m";
+
+init() {
+ persons = load Persons "./persons.dis";
+}
+
+mktown(): ref Town {
+ return ref Town;
+}
+
+Town.stringify(t: self ref Town): string {
+ Person: import persons;
+
+ s := "Name: " + t.name + "\nSize: " + string len t.pop + "\nMembers:";
+
+ for(i := 0; i < len t.pop; i++)
+ s += "\n→ " + t.pop[i].stringify();
+
+ return s;
+}
--- /dev/null
+++ b/Modules/towns.m
@@ -1,0 +1,14 @@
+include "persons.m";
+
+Towns: module {
+ init: fn();
+ mktown: fn(): ref Town;
+
+ persons: Persons;
+
+ Town: adt {
+ pop: array of ref Persons->Person;
+ name: string;
+ stringify: fn(t: self ref Town): string;
+ };
+};