diff options
Diffstat (limited to 'ADTs')
| -rw-r--r-- | ADTs/README.md | 51 | ||||
| -rw-r--r-- | ADTs/adts.b | 52 |
2 files changed, 103 insertions, 0 deletions
diff --git a/ADTs/README.md b/ADTs/README.md new file mode 100644 index 0000000..7f2d8bb --- /dev/null +++ b/ADTs/README.md @@ -0,0 +1,51 @@ +# ADT's + +Limbo supports Abstract Data Types (ADT's). These are analogous, but not equivocal to, structs in C and Go. + +For further reading on ADT's and how they compose in different contexts, see [Modules](../Modules) and [Generics](../Generics). + +## Source + +### adts.b:12,16 + +The type `Person` is an ADT declared within a module definition possessing an integer, string, and function reference member. + +The function is named stringify and takes an argument named `p` which is a reference to the adt variable instance which called the function. This function could be thought as being analogous to a method. + +Method-like function references declared with `self` as a keyword for an argument are not required to be called with said argument being passed. + +Note: Modules are a form of ADT with some special rules associated with them that differentiates them from a normal ADT. + +### adts.b:19,23 + +The type `Town` is an ADT declared outside of a module definition possessing an array of references to Person ADT's, a string, and a function reference. + +### adts.b:28,29 + +The variable `p` is created as a reference to an instance of a `Person` type which is instantiated using constructor-like syntax. The `Person` element `name` is then printed. + +Note: Although the syntax used to instantiate the `Person` type instance appears to be a function, it is closer to a tuple being passed into an instance of a `Person`, but used in an in-line fashion. That is, the tuple must contain all non-function reference types contained within the ADT. + +### adts.b:31,36 + +The variable `t` is created as an instance of a `Town` ADT. The non-function reference elements are then initialized manually. Note that the `ref Person(...)` instantiation can be used as a valid variable instance. + +### adts.b:41,52 + +The method-like function references are declared with a bit of special syntax. That is, the function name takes the form of `ADT.func()`. + +## Demo + + ; adts + Spike + Name: Mars + Size: 2 + Members: + ā Spike + ā Ed + ; + +## Exercises + +- Can you instantiate an ADT via its constructor without all its non-function reference members? +- How would you format the constructor-style instantiation of a `ref Town`? diff --git a/ADTs/adts.b b/ADTs/adts.b new file mode 100644 index 0000000..d5ff7e1 --- /dev/null +++ b/ADTs/adts.b @@ -0,0 +1,52 @@ +implement ADTs; + +include "sys.m"; +include "draw.m"; + +sys: Sys; +print: import sys; + +ADTs: module { + init: fn(nil: ref Draw->Context, nil: list of string); + + Person: adt { + age: int; + name: string; + stringify: fn(p: self ref Person): string; + }; +}; + +Town: adt { + pop: array of ref Person; + name: string; + stringify: fn(t: self ref Town): string; +}; + +init(nil: ref Draw->Context, nil: list of string) { + sys = load Sys Sys->PATH; + + p := ref Person(27, "Spike"); + print("%s\n", p.name); + + t: Town; + t.pop = array[] of {p, ref Person(13, "Ed")}; + t.name = "Mars"; + + town := ref t; + print("%s\n", town.stringify()); + + exit; +} + +Person.stringify(p: self ref Person): string { + return p.name; +} + +Town.stringify(t: self ref Town): string { + 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; +} |
