-
Notifications
You must be signed in to change notification settings - Fork 0
11. Classes
Alongside the classes associated with the built-in primitive and container types, DSSL adds support for user-defined classes. A class is defined using the class
keyword with a label and block element as the first and second arguments, respectively. Once defined, the class's hierarchy becomes a sub-hierarchy of the current scope, much like the hierarchy of imported scripts. For that reason, classes can simply be used to construct namespaces without imports:
/Math {
/pi 3.14159265358979323846 def
/e 2.71828182845904523536 def
/factorial {
/result 1 def
1 + ( 1 3 2 roll ) {
/result exch *=
} foreach
result
} macro
} class
"pi + e = " Math .pi Math .e + ~ println
"52! = " 52 Math .factorial ~ println
The new
keyword is used to create instances of a class from a class element on the top of the stack, which can be created by using the class's identifier. The following defines two variables a
and b
as instances of the Pos
class and prints their magnitudes using the abs
method:
/Pos {
/__init__ {
/this exch def
/this .z exch def
/this .y exch def
/this .x exch def
this
} macro
/abs {
/this exch def
this .x 2 ** this .y 2 ** + this .z 2 ** + 0.5 **
} macro
/__add__ {
/this exch def
/other exch def
this .x other .x + this .y other .y + this .z other .z + Pos new
} macro
/__str__ {
/this exch def
"[" this .x ~ ", " ~ this .y ~ ", " ~ this .z ~ "]" ~
} macro
} class
/a 3 4 5 Pos new def
/b 1.41 1.73 2.24 Pos new def
a Pos .abs println # static access
b .abs println # instance access
While a
's magnitude is obtained by using static access to the macro in the Pos
sub-hierarchy, the interpreter knows that b
is an instance of Pos
and so an instance access is performed, which first pushes b
to the stack before executing the Pos .abs
macro, resulting in the same outcome.
Members defined with particular names add indirect magic functionality to instances of the class. For example, the constructor __init__
executes directly after the new
keyword pushes the new instance to the stack. The constructor of the Pos
class pops the top three elements after the new instance and uses them to define the member variables x
, y
and z
. If any instances of a class are created within the class definition itself, they must be created after the constructor has been defined.
Magic definitions can also be used for overloading built-in operators, such as addition with __add__
, and defining explicit string casts with __str__
. For example, the Pos
class defines magic for each of these, and the following code prints a + b = [4.41, 5.73, 7.24]
;
/c a b + def
"a + b = " c ~ println
All identifiers for members with magic functionality are listed here.
Note that individual instances have their own hierarchies, and so it is possible to define members in them which no other instances will have:
/c .shout { "Hello!" println } macro
c .shout