The user of Lpp can create new Lpp subtypes with the classL and
classLS macros. Note that all examples given in this section
assume that a type meta-object is generated somewhere (see genT
and genTS macros below). When a class is defined as an Lpp
subtype a new type meta-object named by that class name will exist in
the Lpp type hierarchy. Instances of that class then can be used
anywhere an Lpp object of type let can be used. For example,
such an instance can then occur in an Lpp list.
| classL name | Macro |
| classLS name | Macro |
The classL macro is used for defining new Lpp subtypes of type
let. The classLS macro is used for defining new Lpp
subtypes of Lpp supertypes. The name argument specifies the
name of the new class and subtype. The syntax of both is exactly the
same as the ordinary C++ class syntax except that instead of
using the class identifier either classL or
classLS is used.
For example
classL(MyType) {...};
let m1 = makeInstance(MyType);
let list1 = list(L(1), m1, L(2));
cout << second(list1);
We could do a similar thing with a subtype of MyType:
classLS(MySubType) : private MyType {...};
let ms1 = makeInstance(MySubType);
let list1 = list(L(1), ms1, L(2));
cout << second(list1);
// Should print "t" for both of these:
cout << typep(second(list1), type(MyType));
cout << typep(second(list1), type(MySubType));
To pass the specific type of any new Lpp object down through the Lpp
type lattice any constructor in a classL or classLS
definition must pass in a constructor for the super type with
the subtype as an argument. For classL this would be the
Let supertype and for classLS the user defined Lpp type.
Recall that the Lpp type can be referenced using the type
macro. So for a new user defined Lpp type T the super
constructor needed for classL would be Let(type(T)). Or
using our example above for MyType and MySubType the
class constructors might appear as follows
MyType() : Let(type(MyType)) {...}
MySubType() : MyType(type(MySubType)) {...}
| makeInstance type | Macro |
Returns a new Lpp object of type type. The argument type can be a C++ constructor form or just the type name. The constructor or type name must be of an Lpp type.
Since all Lpp object subtypes must have a type meta-object,
See Accessing Type Meta-Objects, the Type object must be generated
somewhere, usually in the C++ file that defines the accessors for the
subtype. This can be done easily with the genT or genTS
macros.
| genT type | Macro |
| genTS type supertype | Macro |
The genT macro generates a type meta-object of type
type. The genTS macro generates a type meta-object of
type type whose supertype is supertype. For example
classL(MyType) {...};
// The type meta-object for a MyType is generated here
genT(MyType);
classLS(MySubType) : private MyType {...};
// The type meta-object for a MySubType is generated here
genTS(MySubType, MyType);